#clojure logs

2013-12-21

00:13ddellacostacan someone tell me what I'm misunderstanding here? https://www.refheap.com/22091
00:13ddellacostawhy can't I run the output of my macro the same way I run a normal function, if they are both PersistentLists?
00:14alewYou are trying to run a list as a function
00:15alewIf you called eval on (make-adder [2 2]) I think it would work
00:15technomancyyeah you need an eval
00:16ddellacostaslew, technomancy: yeah, that I already get...so let me ask a different question: is there any way for me to get something that looks like a list that I can run as a function? I suppose the answer is no
00:16ddellacostaslew -> alew
00:16technomancywrap it in (fn [] ...)
00:17ddellacostatechnomancy: okay, I guess that's the answer. I guess the thing I'm fundamentally not getting is why a list is a list when quoted, but becomes a function when called in the repl or in code.
00:18alewthe list isn't a function
00:18justin_smith,((fn [[f & args]] (apply f args)) (list + 1 2)) ; ddellacosta is this what you want?
00:18clojurebot3
00:18aleweval takes the list and performs an evaluation of it
00:18alewwhich it assumes the first element to be a function
00:18alewwhen you quote it, you esentially tell eval to ignore it
00:18alewand it stays as a list
00:19ddellacostajustin_smith: no, what I want is for me to be able to evaluate '(+ 1 1) without jumping through the hoops you're jumping through...a.k.a. for Clojure to work like my misconception of it...haha.
00:19justin_smithcalling eval is really a heavyweight operation though, it is nice to avoid it if possible
00:20ddellacostajustin_smith: exactly...which is why I was hoping I could just pass a list around and call it when I wanted to. But I suppose I need to take the approach you and technomancy described. Okay, that's that...thanks technomancy, justin_smith and alew!
00:28bitemyappddellacosta: macros generate lisp data, not opaque functions.
00:29ddellacostabitemyapp: doesn't that depend on the macro?
00:29ddellacostabitemyapp: not trying to quibble, just not grasping what you mean by thatt.
00:29ddellacosta*that
00:31tbaldridgeddellacosta: the input and output of macros are data. Now after all macros have been run, that data may be eval'd and turned into functions, but macros do not create functions
00:31tbaldridgethey create data that may be evaluated by the compiler as functions.
00:31tbaldridge, '(fn [x] 42) ; this is not a function
00:31clojurebot(fn [x] 42)
00:31bitemyappddellacosta: it doesn't depend on anything, it's axiomatic.
00:32ddellacostabitemyapp, tbaldridge: thanks, that's a lot more clear now.
00:43technomancya list doesn't really "become a function" when entered in the repl
00:43technomancycalling eval may be heavyweight, but it's what the repl does =)
00:48ddellacostatechnomancy: yeah, after hearing what tbaldridge and bitemyapp were saying, I realize I was thinking...magically. None of this is stuff I didn't know but somehow I was forgetting when a macro actually does what it does. As bitemyapp said, "it's axiomatic." Now that I think back on my original question, I'm not really sure what I was thinking.
00:48justin_smithwe had a template engine that would call eval on expressions, until we noticed the performance was shit. We switched up to read+apply and it was a big improvement
00:49ddellacostabut as usual, asking dumb questions on #clojure has brought me to enlightenment. ;-)
00:49technomancythe Magic of IRC
00:49ddellacostajustin_smith: ah, that's an interesting point. Why is that?
00:50ddellacostatechnomancy: indeed.
00:50tbaldridgebecause he was only using data. No reason to eval the read forms if you only want the data
00:50justin_smithddellacosta: eval has a bigger setup to do in terms of creating the evaluation context
00:51justin_smithtbaldridge: we were using helpers that were functions though, and allowed inline clojure
00:51justin_smithtbaldridge: but we didn't need full on namespaces and closures, so we gained by not paying for that
00:51tbaldridgeright, but you went from compiling the templates to some sort of interpreting.
00:51justin_smithright
00:51justin_smithexactly
00:51tbaldridgedid you reload the templates each time?
00:52justin_smithyeah, because the data was coming from the db
00:52justin_smiththe smart way would be to compile the template into a function once, with all db data in the args
00:53tbaldridgeyeah, or eval once and cache the results. that way the JIT actually has a chance to help you.
00:53justin_smithright, but the results aren't going to be any good if part of what is evaluated is coming from a db call that could give a different result next time
00:59ddellacostaI see, eval actually creates a PushbackReader and passes it to LispReader, where as read defaults to *in*...
01:00ddellacostabtw, what is the convention followed by the formatting in the Clojure (Java) source? I've never seen that kind of bracket indenting. I suppose it's reasonably readable...is that common in Java-land?
01:00coventryEval doesn't do those things. Those are the Reading part of the REPL.
01:03ddellacostahuh, okay
01:08technomancyI think the general consensus around Clojure's Java source is that it isn't something to be emulated =)
01:10ddellacostatechnomancy: gotcha...haha.
01:10ddellacostaI am certainly finding the source to Compiler.java a bit tricky to follow
01:11technomancythis is normal, heh
01:11justin_smitheven the clojure clojure source isn't something to be emulated, in many places
01:12technomancyespecially core.clj
01:12technomancyor anywhere it uses load-file
01:12technomancyanyone care to review a draft blog post?
01:12technomancyit's about keeeeyboards
01:12ddellacostatechnomancy: definitely
01:13technomancycool; it's http://technomancy.us/172
01:14technomancyif you count XML as a language, every blog post I've written this year has introduced code in a new language
01:19ddellacostatechnomancy: wow, you're making me want to 1) get one of these and 2) switch to Dvorak
01:20technomancyjust don't do them both at the same time
01:20justin_smithI am using a kinesis freestyle 2, a split keyboard is a really nice thing
01:20technomancyunless you want to take a three-month sabbatical to re-learn how to computor
01:20ddellacostaha, gotcha...
01:21justin_smiththe transition period is nice for facilitating hammock driven development
01:21technomancydvorak is nice, but it's not that different from colemak, which you can learn a lot more quickly
01:21technomancyI learned when I was a freshman in college with not a lot to do
01:22ddellacostaone thing you may want to mention (at least, I didn't see a mention) is Jesse Vincent's project, http://launch.keyboard.io...that said, you have a pretty good narrative flow already, and I don't know if it would make sense.
01:22ddellacostawhoops, bad link: http://launch.keyboard.io
01:22technomancyI also wonder if there's any point in sticking with a 12-inch laptop if I'm going to be toting around a keyboard with me everywhere I go, heh
01:23technomancyddellacosta: oh yeah good call
01:23ivanhttp://mathematicalmulticore.wordpress.com/category/keyboards/ layout talk, also http://mkweb.bcgsc.ca/carpalx/
01:23technomancyI read his blog post about all his various attempts and it floored me. a true pioneer!
01:24ddellacostatechnomancy: yeah, ditto, I was really impressed by that!
01:26ddellacostaanyways, overall, I enjoyed your post technomancy ...I didn't know about the IBM Model M, I love that kind of history.
01:26justin_smithmy coworker has a model m
01:26justin_smithso distracting
01:26justin_smithmuch click
01:26technomancywow
01:27ddellacostajustin_smith: um, don't you mean "so click much distracting?"
01:27RaynesI'm still fine with my das.
01:27RaynesNobody at work ever cared about the clickiness.
01:27justin_smithddellacosta: yeah, pretty much
01:27technomancyRaynes: too young for RSI to set in =)
01:27technomancyRaynes: which switches is it though?
01:27Raynesamalloy_ would occasionally think about throwing things at me when trying to hear folks across the room.
01:27ddellacostajustin_smith: :-p
01:27Raynestechnomancy: Cherry blues.
01:27ddellacostaRaynes: what's a das?
01:27technomancyRaynes: represent
01:28Raynes$google das keyboard
01:28lazybot[Das Keyboard] http://shop.daskeyboard.com/
01:28technomancyI heart them so
01:28RaynesThey're delicious.
01:29justin_smithif only they made a split das, but I guess that kit technomancy got is close to being that
01:30ddellacostaintriguing...I should really start using something other than this built-in laptop keyboard. :-(
01:30technomancyjustin_smith: yeah, I held off for a long time because I didn't want to have to pick between mechanical and split
01:30technomancy(and the advantage was just too intimidating, heh)
01:30justin_smithddellacosta: split is awesome, especially if you have wider chest/shoulders than average
01:31technomancyddellacosta: actually in japan it's probably a lot easier to find good keyboards
01:31justin_smithpatchwork uses an advantage
01:31technomancystrong otaku culture there =)
01:31ddellacostatechnomancy, justin_smith: yeah, I've been kinda coveting split keyboards for a while...should head over to Akihabara and see what I can find!
01:31justin_smithsplit with a trackball in between is pretty sweet
01:32pdkwhere do you find those
01:32pdkthat sounds pretty nice now
01:33justin_smithwhich?
01:33technomancyjustin_smith: https://secure.flickr.com/photos/95666385@N02/8731901844/
01:33pdkwith a keyboard in the middle of the split
01:33justin_smithwoah, that is fucking awesome
01:33pdkum
01:33pdktrackball
01:34pdkdamn and it's got arcade buttons
01:34justin_smithpdk: I just manually put a kensington ball mouse between the halves of my kinesis freestyle
01:34pdkthis is truly the everything keyboard
01:34pdkhm there's an idea
01:35justin_smithpdk: bonus, maximum flexibility for rearranging the halves / mouse to keep hand positions switching up
01:35pdkgonna have to look into this
01:35technomancyjustin_smith: do you use any tenting?
01:35justin_smithtechnomancy: yes at work, no at home
01:36technomancydo you feel like it makes a big difference?
01:36justin_smithI am considering getting the tenting for home too, but not sold on needing it yet
01:36technomancycool
01:36justin_smithfor more extended typing it is nice
01:36technomancyI need to spend some more time gettinhg used to the matrix layout before getting any fancier =)
01:37justin_smithhttp://www.kinesis-ergo.com/freestyle-ascent-features.htm I use the ascent
01:37technomancythough I did just order some colored caps for the home row and homing bumps
01:37justin_smiththat is a bonus with the freestyle, that the various risers are swappable
01:37technomancynice
01:37technomancywhat position do you mostly use?
01:38technomancyI mean which angle+
01:38technomancyderp
01:38justin_smitha fairly shallow one
01:39justin_smith20-30
01:39technomancygotcha
01:39justin_smithit would be funny to use the 90 degree tenting with the halves on either side of the monitor - like hugging the screen
01:41justin_smithI use the palm supports too
01:41technomancythat'd be awesome with a CRT
01:41justin_smithheh, yeah
01:41justin_smithyou could just mount the keys to the side of the crt
01:41justin_smithlol
01:58arrdemhas anyone used core.logic for optimization problems?
01:59arrdemjust wondering if I can do better than a brute force search of my solution space here
02:02logic_progis your space convex?
02:02bitemyapparrdem: I don't think core.logic will know more about your problem than you, but it's possible. I think core.logic is more useful when you just want to quickly express something.
02:02logic_progis it continuous?
02:02logic_progis it np-complete?
02:03technomancy"quickly express something, as long as it's a search tree"
02:03arrdembitemyapp: mmkay. I'll watch some of dnolen's stuff on it tomorrow.
02:03arrdems/tomorrow/later today/
02:03arrdemlogic_prog: it's an ordering and selection problem, so it's at least combinatoric, but bounded, to n < 10.
02:04technomancysee also http://programming-puzzler.blogspot.com/2013/03/logic-programming-is-overrated.html for another perspective
02:04technomancyoops, the url is kind of a spoiler there
02:04logic_progarrdem: do you know if it has a polynomial time solution?
02:04arrdemlogic_prog: no effort has been made to rigorously analyze this algorithm/problem.
02:05logic_progarrdem: waht is the input/output?
02:05bitemyapparrdem: I'm more or less on board with what technomancy linked.
02:05arrdemlogic_prog: input is a set of weapons with stats, a weilder and a victim
02:06arrdemlogic_prog: output is a sequence of attacks
02:06arrdemmaximized for projected damage
02:06logic_progarrdem: I think you want dynamic programming
02:06logic_progit's probably do-able in O(Wt) time, where W = # of weapons, and t = number of discrete "time steps"
02:06logic_progoh, and damage is "additive" right?
02:07arrdemlogic_prog: yes but it isn't monotonic because there's weirdness with a finite selection of "boosted" actions.
02:07arrdemit's complicated and domain specific :P
02:07logic_progarrdem: how can we help you if we don't have a formal definition of ht eproblem? :-)
02:08arrdemlogic_prog: as with bitemyapp and technomancy the expectation was vague "this is my gut" answers :P
02:09bitemyappI'm good at spaghetti->wall Q&A sessions.
02:09logic_progare you writing a world of warcraft bot? :-)
02:09technomancybitemyapp: the author is a seajure member
02:09bitemyapplogic_prog: he's modelling a pen & paper game.
02:09arrdemlogic_prog: with all the smart people in here, the community gut is really bright
02:09logic_progfigure out how to maximize damage vs this boss with these weapons :-)
02:09technomancy"that guy who uses Windows"
02:09bitemyapptechnomancy: nifty. I like how they think.
02:09bitemyappLOL
02:09technomancyhe's been using clojure professionally longer than I have though, so who am I to judge
02:09bitemyappthere's always one.
02:09arrdemthat one guy....
02:10technomancyin this case two: he's started to bring his son in
02:10arrdemgood. get 'em yong.
02:11technomancyhis son gave a really cool talk about different optimization strategies for a certain mobile puzzle game a few months back
02:12bitemyapptechnomancy: I talked to one of the founders of my company yesterday night. They'd like me to stick around for another ~6 months to put down some more roots, but in the end, I'm free to go remote tomorrow if I so desired.
02:12technomancynice; good luck
02:12arrdemwho mentioned dynamic?
02:12arrdem(inc logic_prog)
02:12lazybot⇒ 1
02:12bitemyapparrdem: Logic Prog - dynamic programming is a good toolkit to have in mind.
02:12bitemyapp(inc logic_prog)
02:12lazybot⇒ 2
02:13bitemyapptechnomancy: thanks. hopefully the IPO/mezzanine round that happens in 10-12 months goes well.
02:13arrdemlogic_prog: good call there. I suspect that this is a perfect candidate for a two level dynamic approach.
02:13logic_progarrdem: given that I don't have a formal defintion lf the problem you're working on, I can't argue the other side
02:13logic_prog:-)
02:14logic_progbut I think absically, all control problems
02:14logic_progi.e. making decisitions at various tiem steps
02:14logic_progare basically dynamic programming problems
02:14arrdemI mean I could slap one together if you're interested... there's even some Clojure in Python that's an old (working) prototype :P
02:15TEttingerarrdem, if your stuff is open source, hell I could probably use it
02:16arrdemTEttinger: there used to be a github repo with the python code, but I recycled the name for the clojure rewrite.
02:16arrdemlemme see if I can paste the relivant file..
02:16TEttingera while ago I made a list of 100 weapons in a spreadsheet, later figured out a way to get it into clojure but never did anything with it https://dl.dropboxusercontent.com/u/11914692/Weapons%20Spreadsheet%20Full%20100.PNG
02:17TEttinger,(read-string (slurp "https://dl.dropboxusercontent.com/u/11914692/weapons-map-too-large.clj&quot;))
02:17clojurebot#<SecurityException java.lang.SecurityException: denied>
02:17bitemyappTEttinger: you play the same game?
02:18TEttingerheh not in any more than a metaphorical sense
02:18arrdemTEttinger: refheap.com/22092
02:18TEttingerneat arrdem
02:19bitemyapparrdem: if you're serious about scaling this up, you'll want to give some thought to rule/behavior composition.
02:19arrdembitemyapp: ooh yeah
02:19TEttingeryeah, for my thing it would need to be scaled up, 80 columns on that spreadsheet
02:19bitemyapparrdem: which often take the form of monoids and monads >:)
02:19TEttingeroh boy
02:19arrdemTEttinger: lol
02:20TEttingeryou should see the dungeon project, haha
02:20bitemyappspreadsheet evaluation lends itself nicely to loeb.
02:20TEttingerloeb?
02:20TEttingerlots of empty booleans?
02:21logic_progwow
02:21bitemyappTEttinger: http://math.stackexchange.com/questions/90781/something-like-recursive-harmonic-numbers-where-can-i-read-more http://www.haskell.org/haskellwiki/Blow_your_mind#Other
02:21logic_progare you guys playing civ 5 with pencil paper ?
02:21TEttingerlol, one wasn't P&P
02:21TEttingerthe weapons aren't, the dungeon thing (also manipulated with clojure) is
02:23arrdemlogic_prog: see what it's doing?
02:23arrdembitemyapp: and yeah I'm gonna have to come up with some capability based way of representing all these rules
02:23bitemyappTEttinger: loeb is a nice brainfuck :)
02:24logic_progarrdem: no, I saw the links by Tettinger, but nothing from you
02:24arrdemlogic_prog: http://math.stackexchange.com/questions/90781/something-like-recursive-harmonic-numbers-where-can-i-read-more
02:24arrdem oops
02:24arrdemlogic_prog: https://www.refheap.com/22092
02:25logic_progarrdem: I was about to ask: is this a game designed to be played between Fields Medalists?
02:25TEttingerhttps://dl.dropboxusercontent.com/u/11914692/Dungeon%20Vanguards.xls the spreadsheet is apparently not massive by any means, but is too large to fit in its entirety on google docs
02:25TEttingereach class is one paragraph, roughly
02:25TEttingerthere are a lot of them.
02:26arrdemlogic_prog: negative. this game is designed to be played by middle aged dudes with too much money and time who like tabletop miniature wargames.
02:26arrdemlogic_prog: average IQ and sub-par math skills are accounted for.
02:26arrdemlogic_prog: I'm just building an AI because I can :D
02:27arrdemalso because an AI with provably optimal decisions provides a benchmark for the quality of my decisions..
02:29logic_progarrdem: http://en.wikipedia.org/wiki/Bellman_equation <-- I think this is what you want
02:32arrdemwoah where'd logic_prog go Q_Q
03:03nonubyis there any issues with passing channels over channels?
03:09ivannonuby: I heard that is an acceptable thing to do
03:09nonubycool, so many approaches one can take with channels, with only limited guidance (todo and tic tac toe apps etc..)
03:12ddellacostais it bad form for any reason to use clojure.test/function? in normal code? I'm doing something where I recurse through a list and evaluate any values which are functions before evaluating the final list itself.
03:15bitemyapparrdem: typeclasses are capabilities >:)
03:59logic_progclojure is too fucking badass
04:00logic_progI think I'm down to think 1 hour, write 10 lines of code
04:00logic_progthe levels of abstraction possible are insane
04:00Rayneslogic_prog: Deep breath.
04:00RaynesInhale ... ... ... exhale
06:07mi6x3mhey clojure, if I have nested let's binding the same local, can I refer to the one from the outside let
06:07carknope
06:08mi6x3mok
07:22Bronsak
07:47anagriusIs anyone using nrepl-ritz with cider. Or would I have to revert to nrepl.el?
08:28danlentzhey wow cider-inspect is quite nice!
08:29danlentzcloses a little bit of the distance between ciderr and slime
08:30danlentzthings have come a long way since one launched clojure repl with java -jar and prayed never to need backspace
08:33danlentzwell done cider/nrepl team!
09:27xeqicemerick: ooh, is it piggieback PR time?
10:08cemerickxeqi: yup
10:09cemerickxeqi: burning through the github queue in general
10:39danlentzso Java booleans appear to consume 128 bits of storage
10:40danlentzwould be intertesting to know what the extra 127 bits are need for
10:41andyfdanlentz: A Boolean object, you mean?
10:41danlentzwhy on earth should booleans require more space than any other primitive type-- longs, doubles included.
10:42andyfAll Java Objects take a certain amount of overhead for each instance, including a synchronization lock (although I've heard some Java creators considered that overkill later)
10:42danlentzwell a boolean primitive gets wrapped in Boolean
10:42andyfdanlentz: I had not measured to see that they take more than others.
10:42danlentza long primitive requires 64 bits
10:43andyfCompare against Integer, Long, not the primitives.
10:43andyfIf it is indeed Boolean, not boolean you are comparing them to.
10:43andyfboxed values abound in typical Clojure code.
10:44danlentzhmm. well the actual heap space used by the wrapper class is unknown to me id think without some l;ow-level tool to inspect it
10:45andyfYeah, the easiest way I know is to have a sample JVM session where you generate millions of them, and then use a memory profiler to see the size of the most frequently allocated object.
10:45danlentzbut im really talking about the primitive type though
10:45danlentzie int -
10:45andyfYou can avoid the boxing overhead if you need to for some huge data set, e.g. boolean-array
10:46danlentzfrom what i understand that will require 128 bits per boolean element of the artray
10:46andyfHow did you reach the conclusion that a primitive boolean takes 128 bits? I am not saying it is wrong, just wondering what the evidence is.
10:47danlentzdocs -- although i just copied the table into my source file as commemts I dont have the url handy at the moment
10:47danlentzdoh
10:49danlentzit was during the course of working with a lot of signed/unsigned numeric representation issues for my clj-uuid library
10:49andyfI don't have an authoritative answer for you, but at least some people discussing the question on StackOverflow believe a primitive boolean is the same as a 32-bit primitive int. http://stackoverflow.com/questions/1907318/java-boolean-primitive-type-size
10:50andyfBut that JVM implementations probably use less than that for arrays of booleans,
10:51andyfAs far as Clojure goes, that is a JVM implementation detail that Clojure can neither directly observe nor control.
10:51danlentzhuh. well then thats better maybe i'm mistaken about it
10:52danlentzyeah but if we couldnt gripe about jvm issues we wouldnt have all that much to gripe about :)
10:53andyfThere are Java classes and Clojure data structures for storing bit arrays more compactly, of course.
10:54danlentzy the next thing i think im going to write is a bit-vector type
10:54andyfJava BitSet http://docs.oracle.com/javase/7/docs/api/java/util/BitSet.html Clojure immutable-bitset https://github.com/ztellman/immutable-bitset
10:54xeqifor oracles jvm, the spec says booleans use ints, but that boolean[] use byte arrays
10:54xeqihttp://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.3.4
10:55danlentzxeql: hmm cool. i stand corrected then
10:56andyfI believe both of the libraries I linked to can approach 1 bit per element, plus the fixed Object overhead.
10:56hyPiRionAccording to the JVM spec, arrays of booleans take 8 bit per element. So it's not only the Oracle JVM which does that
10:57danlentzztellman has a lot of good stuff
10:57andyfYes, yes he does :-)
10:57andyfinc ztellman
10:57andyfdang, forgot the syntax
10:57danlentzfor bitwise byte munging
10:58andyf(inc ztellman)
10:58lazybot⇒ 7
10:58danlentzim using primitive-math. does anyone else notice though it seems to behave in a slightly contagheous fashion
10:59danlentzie, any ns that uses a ns that uses p-m automatically gets its operators replaced
10:59andyfIt is considered best practice to (:require [lib.name :as short-alias]) not :use
11:00andyfI have seen ztellman :require p-m as p, but it still leads to p/+ p/- etc in your code.
11:00danlentzit hasnt caused me any problems, but it is a kind of worrisome behaviiour
11:00andyfYou get to pick whether you want the override or the namespace-aliased behavior yourself.
11:01dsrxyou could refer those specific operators you need, no?
11:02andyfOh, yes, and I don't personally use it much, but you can also rename the symbols you :refer, if you want to avoid needing the alias/symbol all of the time to refer to them, but don't want the names to override those in clojure.core
11:03danlentzi see now -- he has the ns-wrapper do automatically use-primitive-operators if the ns is :used
11:04andyfBronsa: Is it fundamentally impossible to wish for an analyzer where I could tell from the results when portions of the result came from a macroexpansion, and even what the source code before macroexpansion was for that part of the result?
11:05Bronsaandyf: you can attach that info as metadata in macroexpand-1 if I'm understanding correctly what you're asking
11:05andyfBronsa: Or maybe the existing tools.analyzer already provides that, and I haven't noticed it yet.
11:06Bronsae.g. you can make so that (macroexpand-1 '(macro)) => ^{::source '(macro)} (expanded form)
11:06andyfBronsa: I think I see what you mean. That may be useful.
11:06danlentzcross another item off my TODO-clojure.lang.PersistentList :)
11:07andyfBronsa: Sometimes in writing a linter, if I use the ast I am left trying to use tree-shape recognition methods to guess whether it came from a particular macro expansion, but if I use the form read in I am missing out on important details that occur only after macro expansion is done.
11:07andyfBronsa: What you suggest should be able to give me the best of both worlds if I use the ast with the extra annotations.
11:08Bronsaandyf: yeah, it would be cool to say "if this sub-expr is the result of macroexpanding defprotcool then ignore this particular linting warning" I agree
11:08andyfBronsa: Oh, I am doing that already, just in the hackish way I described.
11:08Bronsayeah, I saw the commit
11:08andyfBronsa: I don't expect defprotocol to have its definition change any time soon, but it feels fragile
11:09andyfBronsa: Hopefully seeing those commits didn't disgust you too much :-)
11:11Bronsaandyf: https://github.com/jonase/eastwood/commit/81b600ca740caf4c9edb5fb75a84c3f86a88db98
11:11andyfWorking on a linter now that tries to detect mistakes in the use of clojure.test that I have seen while looking through earlier warnings. It is amazingly easy to try to write unit tests as (= expr expected-value) and forget the (is (= ...)) completely.
11:12Bronsayeah, I'm guilty of doing that myself
11:12andyfBronsa: You, sir, are a scholar and a gentleman. Thanks for the help.
11:12andyf(inc Bronsa)
11:12lazybot⇒ 15
11:14andyfBronsa: I recall you mentioning a possible soon-ish alpha release of tools.analyzer(.jvm). Any thoughts on when that might be?
11:15andyfIt isn't 1.0 quality or anything, but I personally think the latest versions of it and Eastwood are getting reasonably useful.
11:15Bronsaandyf: I'd like to wait for the :tag situation to get solved but.. it doesn't look like we're going to get any ufficial response any time soon
11:16andyfby which I mean, ready to be beaten on by the masses of the world and thus shattering my illusion that it is as stable as it seems
11:17Bronsaandyf: speaking of eastwood, I think it should wait for https://github.com/jonase/eastwood/issues/29 to get fixed before a release
11:17andyfBronsa: I would like an answer to that to, but there really isn't any way to predict when that might happen. It moves on their free time schedules, not our have-time-to-ask-a-question schedules.
11:18Bronsaandyf: the problem now is that jvm.tools.analyze didn't use c.c/eval, it just called .eval on the Compiler.java generated AST
11:18andyfWould it be any kind of solution to use something like tools.namespace to determine dependencies between analyzed namespaces, and analyze them in dependency order?
11:19Bronsaandyf: with tools.analyzer.jvm we have to analyze once && eval analyzes the form again -- we have deftype/protocol issues with the double analysis
11:20Bronsaanalyzing the namespaces in order of dependency would solve those issues
11:20andyfRight now Eastwood's namespace order is fairly arbitrary - just the order of seq on a set.
11:20andyfI believe.
11:20Bronsabut I haven't had any time yet to see how to determine that order with tools.namespace
11:21andyfI can take a look at that after finishing my clojure.test linter a bit more, if it would help. MIght be a couple days before I can start.
11:22andyfIIRC tools.namespace simply looks at each source file and expects the first form to be an ns form, and then parses dependencies from that.
11:22andyfBut I haven't looked at the details. Shouldn't take long, I would guess, with enough experimentation and caffeine.
13:12yediim sure there has to be a better way for me to parse a file? https://github.com/yedi/rhyme-finder/blob/master/src/clj/rhyme_finder/core.clj#L3
13:19ryantmyedi: slurp? http://clojuredocs.org/clojure_core/clojure.core/slurp
13:21yediwow
13:21yediok
13:52jergasonI'm confused by how this works (defn indexed [coll] (map-indexed vector coll))
13:52jergasoni thought vector was a data structure, but here it seems to be a function which returns a sequence of numbers
13:54jergasonwait i get it
13:54jergasonvector gets called with an index and each item in the collection
13:54jergasonso this returns a sequence of [0 first-thing] [1 second-thing] etc
14:03hyPiRionjergason: yes. (vector a b) just returns [a b]
14:05jowagjergason: there is a function which returns a vector which will contain all the items you give it, and this function is called 'vector'
14:05jergasonthanks hyPiRion and jowag, that is very helpful
14:06jowagjergason: so if you call (vector 1 2), it will create a new vector, put 1 and 2 into it and returns it back
14:06jowagjergason: ad because it is a function, you can used in in a higher order functions like map-indexed
14:07hyPiRion(and map-indexed is just a fancy way of saying (map f (range) coll)
14:07hyPiRion)
14:07dobry-denis there a way to refer to the current function without naming it? for example (defn foo ([a] (foo a 1)) ([a b] (+ a b))) without repeating 'foo'?
14:09hyPiRiondobry-den: what do you mean by "without naming it"? (fn foo ([a] (foo a 1)) ([a b] (+ a b))) is an anynomous function
14:09hyPiRionbut it's kind-of named, still.
14:12dobry-denhyPiRion: right, it's just brittle
14:17justin_smithhow is that brittle?
14:19alewyou can use recur
14:19alewif you are doing a tail-call
14:26dobry-denjustin_smith: brittle in that it's a dependency on the name of the function. certainly trivial however.
14:27dobry-denbut easier to acknowledge if you've ever renamed the function and it took you longer than you'd like to realize that you didn't rename it everywhere within the body
14:27justin_smithahh
14:28LajjlaRaynes,
14:28Lajjlado you know where the Finn they call Chousuke hangs out?
14:28dobry-deni'm not saying it's a showstopper. it would just be cool if there was some `recur`-like semantic for it
14:28justin_smith"this"
14:28dobry-denpls anything but this
14:28dobry-denme
14:29justin_smithlol
14:33andreiHow does one do xpath queries on html documents? clj-xpath wants an xml document
14:36justin_smithhttp://www.w3.org/TR/xpath/ by pretending html is xml maybe?
14:38hyPiRionhtml is not xml unfortunately
14:39justin_smithif I understand correctly, xpath is not well defined for html. Though I guess one could take the approach of renaming the html to .xml and hope things work... ?
14:40pdurbinthat's what xhtml is for :)
14:42jergasonthat is a naughty word
14:42hyPiRionjustin_smith: it's unlikely that it would work. <br> is legal html, but invalid xml
14:46pdurbinJSF is all about xhtml :)
14:47jergasonthat is another naughty word
14:48justin_smithjergason: what are the nice words?
14:48jergasonwhatever gets you the most upvotes on hacker news
14:49justin_smith"show hn:" is the universal nicifying prefix
14:54wei__what's a quick way to check whether every element is unique in a collection?
14:55dobry-denwei__: naive solution is (= coll (set coll))
14:55dobry-denbut you'd want it to short-circuit
14:56wei__that doesn't work for me
14:56wei__dobry-den: ^
14:56dobry-denoh yeah duh
14:56wei__maybe (count ..)?
14:56dobry-den(= (count coll) (count (set coll)))
14:57wei__good enough for now, thanks
14:57wei__the collection isn't large
14:58dobry-denyeah it's simple
15:01justin_smith(fn [c] (boolean (reduce (fn [m x] (if (get m x) (reduced false) (assoc m x true))) {} c)))
15:01justin_smiththat version short circuits with the first dup
15:02justin_smith,((fn [c] (boolean (reduce (fn [m x] (if (get m x) (reduced false) (assoc m x true))) {} c))) [0 1 2 3])
15:02clojurebottrue
15:02justin_smith,((fn [c] (boolean (reduce (fn [m x] (if (get m x) (reduced false) (assoc m x true))) {} c))) [0 1 2 3 2])
15:02clojurebotfalse
15:05Jardahmm
15:06Jardaplease enlighten me
15:06Jardalein deps downloads a lot of jars
15:06Jardabut then lein ring server-headless downloads more
15:06dobry-denhow about this https://www.refheap.com/22099
15:06JardaI thought lein deps was supposed to donload everything
15:07dobry-denoh, i didnt see justin_smith's answer
15:07justin_smithdobry-den: nice, maybe the first/rest could be replaced with a destructuring
15:07justin_smithI agree that a set is better than hash map there
15:07justin_smithand contains is the right thing to call
15:07justin_smithrather than get
15:08dobry-denjustin_smith: i tried if-let with [[x] coll] but it would just conj a nil to the set and i didnt bother trying harder
15:09dobry-denit would be cool if if-let checked for nil? on destructured values.
15:09dobry-den(unless i'm missing something)
15:10justin_smithhttps://www.refheap.com/22100 I meant this
15:10justin_smithit works, just tested it
15:25jowag,(apply distinct? [1 2 3 4])
15:25clojurebottrue
15:25jowag,(apply distinct? [1 2 4 3 4])
15:25clojurebotfalse
15:25jowagwei__: ^^ for unique check
15:26wei__oh nice, looks like it short-circuits too
15:26wei__thanks jowag
15:26jowagwei__: yep
15:26justin_smith(inc jowag)
15:26lazybot⇒ 2
15:26justin_smithI knew that must have existed somewhere
15:26jowagthanks
15:27justin_smith$source distinct?
15:27lazybotdistinct? is http://is.gd/FSRvej
15:28justin_smithvery similar to what dobry-den and I ended up with
15:28justin_smitheven down to the destructuring
15:30jowagbut the variant with reduce should be faster, skips seq creation
15:32jowag,((fn [coll] (boolean (reduce (fn [s e] (if (contains? s e) (reduced false) (conj s e))) #{} coll))) [1 2 3 4])
15:32clojurebottrue
15:32jowag,((fn [coll] (boolean (reduce (fn [s e] (if (contains? s e) (reduced false) (conj s e))) #{} coll))) [1 2 3 4 4])
15:32clojurebotfalse
15:32angermanwhat's the clojure in c state?
15:32jowagjustin_smith: benchmark also that one :) ^^
15:33justin_smithyeah, I am doing so :)
15:33wei__love the dedication :)
15:33wei__(inc justin_smith
15:33wei__)
15:33wei__(inc justin_smith)
15:33lazybot⇒ 19
15:34jowagjustin_smith: and don't forget the :jvm-opts ^:replace ["-server"] if using lein
15:39jowag,((fn [coll] (boolean (reduce (fn [s e] (if (contains? s e) (reduced false) (conj! s e))) (transient #{}) coll))) [1 2 3 4 4])
15:39clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: contains? not supported on type: clojure.lang.PersistentHashSet$TransientHashSet>
15:39jowag,((fn [coll] (boolean (reduce (fn [s e] (if (get s e) (reduced false) (conj! s e))) (transient #{}) coll))) [1 2 3 4 4])
15:39clojurebottrue
15:40jowago_O
15:40justin_smithcontains? on a transient?
15:40justin_smithyou may need to call persistent!
15:41jowagofficial docs says: "Transients support the read-only interface of the source"
15:41Bronsajowag: http://dev.clojure.org/jira/browse/CLJ-700
15:41jowagso maybe I've just found a bug
15:42jowagheh
15:44hyPiRionreturns true here
15:45justin_smithso far the reduce based in both versions is faster than apply distinct?
15:45clojurebotGabh mo leithscéal?
15:45justin_smithtrying the loop based version too
15:45justin_smithfaster as in ~ half / third the time needed
15:46hyPiRionhm, that's probably a bug coming from 1.6
15:46hyPiRion&*clojure-version*
15:46lazybot⇒ {:major 1, :minor 4, :incremental 0, :qualifier nil}
15:46justin_smithloop version is equivalent to distinct?
15:46hyPiRion&((fn [coll] (boolean (reduce (fn [s e] (if (get s e) (reduced false) (conj! s e))) (transient #{}) coll))) [1 2 3 4 4])
15:46lazybotjava.lang.RuntimeException: Unable to resolve symbol: reduced in this context
15:49justin_smithtrying the version with a transient with get
15:49justin_smithsince contains? fails
15:50justin_smiththe version with transient/get is not as fast as the version with regular set and contains?
15:50jowagjustin_smith: get on transient is buggy, always returns false
15:50justin_smithjowag: in that case I would have gotten an infinite loop!
15:51justin_smithI was using (concat (range 100) (range)) as my test input
15:51justin_smithto amplify any garbage related differences
15:51justin_smithhttps://www.refheap.com/22101 <- my results
15:51hyPiRionjustin_smith: on 1.6 or 1.5.1?
15:52justin_smith1.5.1
15:53justin_smithhttps://www.refheap.com/22102 <- updated with jvm and clojure versions
15:57amoehey, is there some library I can use to transparently persist hashmaps to disk?
15:58justin_smithamoe: if it is an edn-compatible hashmap, then pr-str and spit will almost always suffice
15:58justin_smithno library needed
15:59jowag,(get (transient #{1 2}) 1)
15:59clojurebotnil
15:59jowagjustin_smith: see ^^
16:03justin_smithoh weird
16:03amoejustin_smith: I was hoping there was something that would automatically write the hashmap state to disk on every modification... yes, I'm lazy
16:03justin_smithahh that is for sets only
16:03justin_smith,(get (conj! (transient {}) [2 true]) 2)
16:03clojurebottrue
16:04justin_smithamoe: you are in luck, the hash map is immutible and can never be modified :)
16:04justin_smithnow if you want a var or atom or such to go on disk whenever it changes...
16:05justin_smith,(get (transient {1 true 2 true}) 2) ; simpler
16:05clojurebottrue
16:06amoejustin_smith: thanks, I'll hit the books :)
16:07justin_smithamoe: in caribou this is what we use caribou.model for (this puts a small but useful subset of hash maps into an sql db)
16:07justin_smithyou may want to look into datomic or couchdb or neo4j or some other keystore for creating and using hashes that persist and can be shared
16:08dobry-denIs there a way to find out where the majority of time is being spent between request and response in a ring app?
16:08amoejustin_smith: this is for a really tiny script and I just want to maintain a list of "seen" URLs
16:08dobry-denin my head the ideal result would be a timeline breakdown per function
16:08justin_smithamoe: a keystore will make that easy, instead of a hash map you could just have keys, and you can add / check for their existence
16:09justin_smithor even a single table with a single string column + clojure.java.jdbc even
16:10justin_smithnaively rewriting the file for each new piece of data is kind of a bad idea (unless you are going to have only one app instance ever and a very small set of seen urls)
16:11kes_Can someone tell me what this type of data is? #<Inet4Address example.org/192.168.1.100>
16:11dobry-denmocker`: http://docs.oracle.com/javase/7/docs/api/java/net/Inet4Address.html
16:11justin_smithkes_: http://docs.oracle.com/javase/7/docs/api/java/net/Inet4Address.html
16:12justin_smithhe is gone already?
16:12dobry-dennamechange
16:12mocker`hehe, sorry about that.
16:12justin_smithahh I hide that stuff
16:13mocker`justin_smith: Thanks, so I'm guessing I can do something like (str (InetAddress/getByName "example.org")) to get a string with the IP?
16:13mocker`(sorry, like third day with clojure)
16:14justin_smith(.getHostAddress add)
16:14justin_smithif add has that indet4address thing in it
16:14dobry-denQuestion: I store Markdown text in my database and currently render it to html one first request where it gets cached. But the markdown can be large and really test the patience of the first request. and the cache is a bit of a sparse map anyways, and it couldn't all fit in memory.
16:14dobry-denWould the solution to that be to prerender it all to html flatfiles?
16:15justin_smithdobry-den: maybe you could extend the core.cache protocol with a disk persistence cache?
16:15justin_smithif that does not exist already actually
16:15dobry-dencool, that is the kind of thing i was thinking about
16:16mocker`justin_smith: Thanks
16:16mocker`Need to take time and figure out this repl in emacs thing, compile and rerun to test command line arguments is slowing things down.
16:17justin_smith(do (require 'ns-with-code 'ns-with-tests :reload) (clojure.test/run-tests))
16:17justin_smithwhat I do is basically the above
16:17mocker`justin_smith: Haven't gotten to "tests" yet.
16:17justin_smithM-p to flip back to commands you previously run
16:17justin_smithahh
16:18justin_smithahh you meant "test" as in run it and see what happens
16:18justin_smithclojure.test is very easy to use
16:18mocker`I was doing pretty well in the repl, but don't know how to do something like pass command line arguments while in it.
16:18mocker`like how does (-main) take --hostname ?
16:19justin_smith(core/-main "--hostname" "blah" "--other-arg" "ok")
16:20justin_smiththe posix command line only provides the ability to pass in strings
16:22justin_smith(test/deftest -main-test (test/is (= (core/-main "--hostname" "localhost") "127.0.0.1")))
16:22justin_smithsomething like that
16:22mocker`justin_smith: Ahh, awesome.. Thanks again!
16:23mocker`Got a free clojure class coming up next month, can't wait.
16:23mocker`Until then just diving in for fun.
16:23justin_smithafter that you can run (test/run-tests) and all the ones you have defined will be run through again
16:23justin_smithassumption being you redefined some code they used in the meantime
16:24yediwhats the fn that does this: [1 2 3 4] => [[1 2][2 3][3 4]]
16:25justin_smith,(partition 2 1 [1 2 3 4])
16:25clojurebot((1 2) (2 3) (3 4))
16:25yedi(inc justin_smith)
16:25lazybot⇒ 20
16:35mocker`Ok, last question for the day. Any way to avoid doing (get options :foo) over and over again in this code snippet? https://gist.github.com/8075415
16:36justin_smithmocker`: destructuring, I will show an example shortly
16:37justin_smith,(let [{a :a b :b c :c} {:a 0 :b 1 :c 3}] [c b a b c a])
16:37clojurebot[3 1 0 1 3 ...]
16:37justin_smiththat works in the function args block too
16:37mocker`Awesome, thanks.
16:38justin_smith(defn new-message [{host :hostname username :username :as opts}] ...)
16:38mocker`Basically trying to switch from using set parameters in my function to command line arguments w/ tools.clj
16:38mocker`So that helps.
16:38justin_smithif you want names identical to keys: (fn [{:keys [hostname username ...] :as opts}] ...)
16:39mocker`I'll play, thanks again. :)
16:52dobry-denWhat's the simplest surrogate for a `pmap` that's intended for sideeffects?
16:53justin_smitha thread pool and a queue via core.async?
16:53justin_smithmaybe
16:53justin_smiththere could be something simpler
16:55dobry-denill try fork/join
16:57xeqi(doseq [x ...] (future x)) ?
16:57xeqihmm, not quite. need the fn call in there somewhere
16:58dobry-denxeqi: that wouldnt be pooled though, right
16:58xeqiright
16:58xeqi"simplest"
16:58dobry-denright, thanks
16:58dobry-denrollin with that for now
17:02danielszmulewiczCompletely off-topic: the Twitter client on the web is a SPA, right? There used to be a #!/username when navigating. Where has the location hash gone? Would anyboddy clue me in?
17:06xperaI'm writing a function that takes byte-array as an argument (for Java interop).
17:06xperaI was hoping I could attach metadata, but obviously cannot since byte[] is a primitive.
17:06xperaI'm looking at the Apache Commons lang library to convert byte[] to Byte[] and thinking about the cost involved
17:07TEttingerxpera, isn't there make-array or amake or something?
17:07TEttinger,(doc amake)
17:07clojurebotI don't understand.
17:07TEttinger,(doc make-array)
17:07clojurebot"([type len] [type dim & more-dims]); Creates and returns an array of instances of the specified class of the specified dimension(s). Note that a class object is required. Class objects can be obtained by using their imported or fully-qualified name. Class objects for the primitive types can be obtained using, e.g., Integer/TYPE."
17:09xperaTEttinger: I should look at that, thanks. reading https://groups.google.com/forum/#!topic/clojure/k8ZkpvO5QcM
17:09TEttingerand there's the ugly option, ^"[Ljava.lang.Byte"
17:09TEttingeror something like that for type hints
17:11dobry-dendanielszmulewicz: i'm not really in the know these days but i think #! is no the best practice anymore
17:11TEttingerxpera: http://asymmetrical-view.com/2009/07/02/clojure-primitive-arrays.html
17:11dobry-dentwitter could be a SPA and use pushState or whatever the kids do these days to update url
17:12xperaTEttinger: thanks. the main thing I want is a way to get metadata on the byte array with minimal extra stuff happening
17:12TEttingerwell I don't know if arrays can get metadata
17:12xperaI'm wondering about a minimal wrapper on top. what would be the simplest thing to wrap with that would let me have metadata
17:12xperaprimitives cannot have metadata. that includes byte arrays
17:13dobry-denif you (dorun (map #(future (process-thing %)) things), and then (doseq [fu futures] @fu), how come CPU indicates things are still being processed after doseq returns?
17:14TEttingerhere, xpera
17:14TEttinger,(with-meta (make-array Byte 2) {:foo :bar})
17:15clojurebot#<ClassCastException java.lang.ClassCastException: [Ljava.lang.Byte; cannot be cast to clojure.lang.IObj>
17:15xperapu dessem si wodniw cri ym ,ces enoI
17:15TEttingerarrays aren't objects and can't have metadata
17:15justin_smithdobry-den: maybe process-thing created a thread?
17:15xperasorry, IRC weirdness
17:16xperathat was really strange
17:16TEttinger[14:13:57] <xpera> pu dessem si wodniw cri ym ,ces enoI
17:16TEttingerI'll say
17:16xperaI use Colemak
17:16dobry-denjustin_smith: oh, so deref wouldnt work like a Thread/join.
17:16TEttingerwindow is messed up, I see
17:16xperaI think Textual got hosed for a second and was using qwerty? who knows
17:16TEttingerbut it was backwards, weird
17:16dobry-denxpera: seems like you would lose more than you gain by trying to get meta on [B
17:17justin_smithdobry-den: deref should block until the future is realized, but if something in the future created a thread, that is still out there
17:17dobry-denjustin_smith: i see. i just have a `spit` in there
17:17xperawhat is a minimal way to wrap a primitive? without copying? that's what I'm trying to ask :)
17:18xperaI've looked at the source for Apache Commons lang Byte wrapping. it copies stuff
17:18xperaand I think a make-array solution would be similar
17:18xperamaybe I can't put a primitive in an object. need to think about that
17:18alandipertxpera: for what purpose, to carry meta?
17:18xperaalandipert: yes
17:19justin_smith(def ^:foo parcel [some-byte-array])
17:19justin_smithis one way to do it
17:19justin_smithmaybe not the best
17:19xperajustin_smith: right. is there a simpler way? just a plain object?
17:20justin_smithhmm
17:20justin_smithwell you need a field that the byte-array could be in
17:20dobry-den^:foo {:stuff bytes}
17:20justin_smithyou could make a one-field record
17:20xpera,(new Object)
17:20clojurebot#<Object java.lang.Object@1755401>
17:20justin_smithyou can't put anything in a plain object, because it doesn't have a place to put it
17:21dobry-denyou can put it in a map
17:21TEttingerhell an atom could do it, or a var
17:22dobry-deni once wanted to put metadata on a bytearray and came up with a hilariously bad abstraction where my bytes were wrapped with maps
17:22xperadobry-den: the simplest so far is just a list I suppose. still looking for the simplest type that will work and accept metadata
17:22TEttingervar containing byte array?
17:23xperaTEttinger: I don't want a var, I want a simple value
17:23xperabut let me think about that
17:23alandipert[bytes]?
17:24xpera,(ancestors clojure.lang.PersistentVector)
17:24clojurebot#{clojure.lang.IEditableCollection clojure.lang.AFn clojure.lang.Indexed java.util.Collection clojure.lang.ILookup ...}
17:24alandipertso by simple, you mean for performance you need something?
17:24xperaalandipert: part of this is a learning exercise... to understand the Clojure/Java interaction
17:26xperaI have an idea from https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L207
17:26xperathe simplest is clojure.lang.IObj
17:26xperathat would the most minimal thing that could work for a simple wrapper
17:28xpera,(new clojure.lang.Obj)
17:28clojurebot#<InstantiationError java.lang.InstantiationError: clojure.lang.Obj>
17:28xpera,(new clojure.lang.IObj)
17:28clojurebot#<CompilerException java.lang.IllegalArgumentException: No matching ctor found for interface clojure.lang.IObj, compiling:(NO_SOURCE_PATH:0:0)>
17:31alandipertxpera: https://gist.github.com/alandipert/8075949 shows some stuff
17:33xperaalandipert: thanks, I'll play around with that
17:34xperaI can't be the only person who wants to find clean ways to attach metadata to primitives. I think JIRA is littered with questions along those lines.
17:34danielszmulewiczdobry-den: Yes, I think you nailed it. PushState seems to be the new thing. Thanks.
17:35justin_smithanother option: (defn box [value] (let [p (promise)] (deliver p value) p))
17:35justin_smithpromise is not so heavy weight a class
17:36xperajustin_smith: I appreciate the brainstorming, but I think that complects too much
17:37xperaanyhow, this is a fun way to dig into some the Java underneath Clojure
17:40xperajust found clojure.lang.Box
17:41xpera,(clojure.lang.Box. (byte-array (map byte [0 1 2])))
17:41clojurebot#<Box clojure.lang.Box@845473>
17:41xpera,(with-meta (clojure.lang.Box. (byte-array (map byte [0 1 2]))) {:charset "UTF-8"})
17:41clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.Box cannot be cast to clojure.lang.IObj>
17:42xperaclojure.lang.Box does not extend IObj. I don't see it shouldn't.
17:42xperaI mean I don't see why it shouldn't
17:46xperare: Box... probably because it is intended to be extremely minimal, only for use in maps and vectors
17:47danielszmulewicznoprompt: ping
17:48nopromptdanielszmulewicz: yo
17:48danielszmulewiczHi, quick question
17:48danielszmulewiczI've been using secretary quite happily with goog.history
17:48danielszmulewicznow I'm wondering if I can make it work with html5Hisotry
17:49danielszmulewiczI would like to get rid of the hash bang thing (location hash)
17:50danielszmulewiczHave you done something with pushState?
17:54nopromptdanielszmulewicz: i have not done anything with pushState, no.
17:54danielszmulewicznoprompt: OK, just asking. Thanks. I'll be investigating further.
17:55nopromptdanielszmulewicz: if you find a solution, be sure to share a gist.
17:56danielszmulewicznoprompt: I will. There is some good insights here: http://squirrel.pl/blog/2013/05/30/client-side-routing-with-pedestal/
17:57danielszmulewicznoprompt: Although it doesn't address pushState.
18:02Mandarsorry, i'm a bit lost regarding an error message: http://pastie.org/private/ai4lc6mq5safzyg9sfija
18:03Mandarin which function does the error occur? at which line?
18:03xperaMandar: the key is to look for files where you have control; e.g. your project
18:03TEttingersangria/core.clj:20 probably
18:03xperaMandar: that assumes your code is the problem, which is what I assume when I look at my code :)
18:04TEttingerit's a wrong argument, like if you do...
18:04TEttinger,(repeat [1] 1)
18:04Mandarxpera, i'm sure that's the problem too... but i don't see which line
18:04clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number>
18:04justin_smithMandar: I start from the top, and check out all the stuff in namespaces I own :)
18:04justin_smithusually the uppermost of the ones I control is the culprit
18:04TEttingeroh that's interesting
18:04MandarTEttinger, i don't see the error yet
18:05xperaMandar: start from top to bottom and find the lines that have your project. so... `/home/armand/dev/sangria/src/sangria/core.clj:20`
18:05TEttingerare you using type hints?
18:05Mandarno i'm not
18:05Mandari'll post the source code somewhere
18:05xperaMandar: gist, please :)
18:05TEttingeryeah, I'd like to see line 20 of core and 13 of guessing_game
18:06Mandari don't want someone to tell me where exactly it is, just give some guidance
18:06TEttingergood, because I have to get going.
18:08Mandarhttp://pastie.org/private/huteprc4elaemskkrwxwrg
18:08Mandari'm playing with lazy-seqs
18:09Mandarworking version is there: https://github.com/agolp/sangria/tree/master/src/sangria
18:10Mandarthe error happens when i call (get-question)
18:12justin_smithcons should have an open paren before it on line 13
18:12Mandarwow
18:12Mandarthanks
18:12justin_smithnp
18:12justin_smiththat may be the problem right there
18:12Mandarit worked!
18:12justin_smithgood news
18:12Mandarbut how could i have found it?
18:12Mandarare there tools for these?
18:13Mandarto check syntax automatically?
18:13justin_smithby checking what random-questions returned
18:13justin_smiththat is not a syntax error
18:13justin_smith,((fn [] cons 1 2))
18:13clojurebot2
18:13Mandarwhat does it mean?
18:13justin_smithyou just put cons in an implict do
18:13justin_smithso it gets referenced, but nothing is done with it
18:13Mandaroh ok
18:13Mandarthank you, much clearer now
18:13justin_smith,((fn [] (cons 1 [2])))
18:13clojurebot(1 2)
18:14justin_smiththis actually used it
18:14justin_smithalso auto-indenting
18:14Mandarshould i use recur inside a lazy-seq or is it ok to call the function name again?
18:14justin_smithif you use an editor that supports that
18:14justin_smithauto-indenting makes it clear where the nesting is not what you expected
18:14justin_smith(usually)
18:14Mandari think i "fixed" it because it wasn't working automatically, but didn't think about it
18:15Mandarthe indentation i mean
18:15justin_smithyeah, never manually fix indentation
18:15justin_smithif it auto-indents wrong, it is wrong
18:15justin_smiththe magic of sexprs - the editor knows exactly how it is structured, no ambiguity
18:15Mandargood
18:16justin_smithrecur is best, but only works in a tail position
18:16Mandarand regarding recur? is there a risk of stack overflows with lazy seqs as i wrote my function?
18:16justin_smitha tail position is the exit point of a function
18:16justin_smitha point where there is no more work to be done before returning
18:17justin_smithlazy-seqs will not stack overflow, but recursive calls that are not using recur can
18:17justin_smithlazy-seqs can run out of heap space thought, if you are too agressive about realizing them or hold on to the head when you don't need it
18:17Mandarthanks again
18:17justin_smithholding onto the head is assigning it somewhere so the item cannot be garbage collected
18:17justin_smithnp
18:18justin_smithrecur will throw an error if you call recur but not from the tail
18:18justin_smithif your algorithm can be expressed with recur, it is better to use it
18:24SegFaultAXjustin_smith: That last point is probably arguable. If there is a more natural expression of your algorithm (perhaps using reduce), that's preferrable to explicit recursion.
18:24justin_smithSegFaultAX: fair enough, yeah
18:25justin_smithI meant if the alternative was a self call, but of course often you can refactor to a reduce
18:25justin_smithor map, for, etc.
18:27SegFaultAXIn general, avoid explicit recursion in favor of the other existing sequence abstractions.
18:27justin_smithright
18:32radshttps://github.com/swannodette/om/blob/master/src/om/core.cljs#L171
18:32radsdnolen: looks like there is a typo there? cursor' instead of cursor
18:34dnolenrads: good catch fixed in master
18:34radscool
18:36bitemyappSegFaultAX: using recursion when a fold would've suited also tends to defeat optimization in Haskell.
18:36bitemyappit's also less expressive to use recursion where it isn't strictly needed.
18:37bitemyappthe best use-case of recursion I can think of is parsing.
18:38bitemyappwhich would figure, since I've been fucking with parsers in Python and the lack of TCO is wrecking my sanity.
18:38pandeirodnolen: any idea if om and hoplon would play well together?
18:38dnolenpandeiro: you'd have to talk to alandipert and micha
18:39alandipertpandeiro: i dunno, talk to dnolen ;-)
18:39dnolenalandipert: haha
18:39SegFaultAXbitemyapp: I can think of infinitely many use cases for recursion. :)
18:39pandeiroi'm getting the recursive runaround
18:39pandeiroi was thinking react for the one-way stuff and javelin for when i want more magical two way binding
18:40pandeiroi still haven't used hoplon yet but i am anxious to try it out
18:40alandipertpandeiro: seriously though, i don't know, i haven't dug into om
18:40dnolenpandeiro: Om is primarily concerned with fast rendering and being able to represent components as EDN
18:41dnolenpandeiro: hopefully that means it easy to plugin to whatever
18:41pandeirodnolen: the latter aspect seems similar to webfui
18:41alandiperthoplon is primarily concerned with conceptual simplicity, linear modification complexity, and designer friendliness
18:41dnolenpandeiro: yes
18:41pandeiroi am writing angular during the day right now
18:42dnolenalandipert: yeah Om isn't ever going to provide a particular template syntax, but I expect people layer whatever they like over it.
18:42alandipertby which i mean, large hoplon apps shouldn't be more complicated to change as they get larger
18:42Mandaris there a more idiomatic way to write this when you don't care about the result values? (doall (map ask questions))
18:42alandipertfor us it's a question of clojurescript syntax, as we don't templates
18:42SegFaultAXMandar: doseq
18:42pandeiroi will be experimenting with the combo over the holidays
18:42MandarSegFaultAX, thanks
18:42pandeiroalandipert: i think that is the major draw for me, i love the html as sexp idea
18:43SegFaultAXI consider it a code smell to use map for side-effecting code.
18:43pandeiroand i noticed that om has a dom ns doing something similar, at least syntactically
18:43pandeiro(i think)
18:43alandipertpandeiro: did you see the thing on ML about dom-as-lisp?
18:43alandipertpandeiro: err the message i posted elaborating on the concept
18:43pandeiroalandipert: no, let me dig that up
18:44pandeiroalandipert: but i will never think the dom the same again after watching your talk...
18:44pandeiro:)
18:45bitemyappSegFaultAX: do ho ho
18:45alandipertpandeiro: https://groups.google.com/forum/#!msg/clojure/gRFyzvRfPa8/QY_HvjaVfvUJ
18:45SegFaultAXbitemyapp: Vidya?
18:46bitemyappSegFaultAX: if that's an invitation, I'd be up for something. What do you have in mind?
18:46roland_dnolen: https://github.com/swannodette/om/blob/master/src/om/core.cljs#L174
18:47roland_dnolen: is there supposed to be some :true there?
18:47SegFaultAXbitemyapp: Dunno. Haven't really gamed in some time. What sounds good?
18:47bitemyappSegFaultAX: I've been mostly playing CS:GO, Insurgency, Dota 2, and DayZ lately.
18:48roland_dnolen: ie an else for cond expression
18:51SegFaultAXbitemyapp: DayZ is that the survival one?
18:52dnolenroland_: fixed thanks
18:52roland_dnolen: np
18:52bitemyappSegFaultAX: yeah, the standalone version finally came out.
18:55bitemyappSegFaultAX: have a mumble and a teamspeak server we can hop into.
18:56SegFaultAXbitemyapp: Sorry, got caught up browsing the steam sale...
18:57bitemyappSegFaultAX: s'no problem. Let me know when you want the talk server details.
18:57bitemyappSegFaultAX: that deal on CS:GO is really good.
18:58bitemyappI like that DayZ has been the top-seller for days on end, even during the holiday sale, with no discount offered.
19:27Mandarsorry to be a pain :(
19:27Mandarhttp://pastie.org/private/wfjvtnjadgwjxxn1md4t1q
19:27Mandari don't get it, been searching for more than 15 min now
19:27the-kennydnolen: Ping. May I ask you something about a bug/problem I have with the latest HEAD of Om?
19:27SegFaultAXMandar: What don't you get?
19:27SegFaultAXOh, looking at paste.
19:27MandarSegFaultAX, why do I get this IllegalArgumentException?
19:28the-kenny Mandar: -> puts the 'previous' item at the *first* position of the current
19:28Mandaroh
19:28SegFaultAXMandar: Use ->>
19:28Mandarthanks :(
19:28the-kennyso you have (count (map (doall (map ask questions)) identity))
19:30the-kennyMandar: also, you can drop the 'doall' here. While map & filter are lazy, count will realize the seq anyway
19:30Mandarthe-kenny, thank you
19:30bitemyappMandar: try to avoid blind forcing.
19:31Mandarbitemyapp, "blind forcing"?
19:31bitemyapppreemptive optimization.
19:31SegFaultAXWell in this case ask is almost certainly doing side-effects. So without considering the rest of the ->> form, it makes sense here probably.
19:31Mandarbitemyapp, regarding the lazy seq you mean?
19:32Mandarand yes, ask is doing i/o
19:34the-kennywell, there shouldn't really be a big difference between forcing it before and after the filter
19:36Mandarthe whole file is here: https://github.com/agolp/sangria/blob/master/src/sangria/guessing_game.clj
19:36Mandari know i shouldn't use the console right there, but i'll make things better once i start adding a user interface
19:47the-kennyIt's actually quite fine. At least that's what it looks to me ;)
19:48the-kennyYou should think about rewriting `random-questions' though. Is lazy-seq in this case really necessary?
19:54dnolenthe-kenny: what's up?
19:55the-kennydnolen: Using latest Om, using {:path [:todos]} for om/build fails, while just [:todos] works fine.
19:55Mandarthe-kenny, i don't know if it's necessary, i wanted to play with lazy-seqs and i find it quite nice
19:55Mandarbut really i was looking for an excuse to use some
19:55the-kennyheh
19:56the-kennyMandar: I usually prefer to implement such stuff in terms of other sequence functions (iterate or repeatedly comes to mind) than lazy-seq. It's likely a matter of taste
19:57dnolenthe-kenny: try now
19:57Mandarthe-kenny, i'll try them, thanks
19:58the-kennydnolen: Works, thanks :)
19:59the-kennyAlso, thanks again for building Om. I really like the approach for client-side development, and I'll definitely use it for some stuff soon.
20:02dnolenthe-kenny: thanks, there still quite a few loose ends and honestly I'm not completely convinced by the design :)
20:02dnolennot sure how much more warning than pre-alpha software I can give
20:02dnolenthe only thing I'm convinced about is the building UIs w/ EDN is a good idea and immutability is a nice perf boost
20:03Mandardnolen, are you considering adding support for something like jsx too?
20:03the-kennyWhat I enjoy most is the 'easy' reactive approach. If you just want a simple 'dumb' ui, you get away with an atom plus a few functions.
20:03dnolenMandar: nope, all sugar over React/Om DOM stuff should be provided by other people.
20:03dnolenpeople have different opinions about that stuff, and I don't want to get involved at all
20:04Mandardnolen, fair enough
20:04the-kennydnolen: I totally agree there. Not just because of different opinions, but also by the complexity
20:04dnolenthe-kenny: yep
20:04the-kennySomething like hiccup/dommy looks easy, but there are really some pitfalls
20:06the-kennydnolen: With which part of the design of Om (or a greater thing?) aren't you happy with?
20:06Mandarthe-kenny, they are nice for developers, but most web designers just want to be able to edit html
20:08the-kennyMandar: The html guy at my previous employer actually preferred hiccup-syntax over html
20:08Mandarthe-kenny, i think that's the exception
20:08Mandari've worked with quite a lot of frontend guys and they mostly prefer to be able to use their tools
20:09Mandar(i mostly work as a web developer)
20:09the-kennyyeah, of course. I just wanted to mention it :)
20:09Mandarbut i understand that the lib shouldn't try to "bite more than it can chew"
20:09Mandarit would be a fun exercise to try and reimplement something like jsx
20:15dnolenthe-kenny: the cursor concept is a little bit thorny, it's easy to have the "wrong" one if you're not careful about your design.
20:15dnolenthe-kenny: so I'd like to figure out how to minimize that
20:16dnolenthe-kenny: ideally eliminate that possibility
20:16dnolenif we can't eliminate it I'm thinking maybe throw an error to indicate your tried to update a stale cursor
20:16the-kennyWhat's 'the wrong one' in this case? From the top, cursors look just like an `get-in'-like interface
20:17the-kenny(plus the ability to mutate them though, I'm not sure if I like that yet)
20:17dnolenthe-kenny: open to ideas about get rid of explicit update! but I couldn't come up w/ anything given how React works w/o building a lot more machinery
20:18dnolenthe-kenny: the wrong one is if you some how forgot to make sure some nodes got updated, their cursors will be stale
20:18dnolenthe-kenny: simplest example is deleting from a middle of a list of things
20:18the-kennyWell, you don't have to use update!, you can always mutate the top-level state atom, but update! is likely much better
20:18dnoleneveryone after the deleted thing will have invalid cursors, they need to be re-rendered even though technically they didn't change.
20:18dnolenso something to think through
20:18the-kennydnolen: ah. Haven't come up with something like this yet
20:19dnolenthe-kenny: yes early on I had an API that included an explicit path
20:20dnolenI toyed w/ passing path and state via opts
20:20dnolenso I'm open to changing how it works if people hate it
20:20dnolenreleasing Om was just trying to show people that UI + Immutable data can be rocking
20:20dnolennow we gotta figure out it should actually look like
20:21the-kennyI didn't mean to say I dislike update! or the approach in general, sorry!
20:21dnolenthe-kenny: haha, it's OK if you do :)
20:22dnolenall feedback welcome at this point
20:22the-kennyIt's actually quite nice. Useful to reduce the amount of the whole application every component sees. The update! was just something that caught my eye.
20:22the-kennyDelegating the event handling via an async-channel in the TodoMVC example was quite nice too.
20:23the-kennyNot sure if I'd pass the channel around via the component's state though
20:23dnolenthe-kenny: yes, talking between logical components w/ core.async is pretty sweet
20:24dnolenthe-kenny: I agree about passing channels via opts being OK probably something cleaner possible
20:24xperai decided to roll a quick java class for the primitive boxing with metadata thing here: https://github.com/bluemont/clj-metabox
20:24xperajava source here: https://github.com/bluemont/clj-metabox/blob/master/src/java/metabox/MetaBox.java
20:25justin_smith if all you wanted was to box a number, why not use a class like Double or Integer?
20:25xperajustin_smith: see the bottom of the README
20:26xperaI wish it looked nicer in the REPL. (metabox/box 3) doesn't display just "3"
20:26the-kennyjustin_smith: because java.lang.Number doesn't implement IObj, which implements meta-data
20:26xperaplease let me know if I messed anything up. i was tempted to implement comparable until I realized that would not have made sense in general
20:33justin_smithxpera: would implementing IDeref make sense?
20:33justin_smiththen @box would work
20:34the-kennyOk, I'm heading to bed now. Let's see if I can use Om for some real stuff over Christmas :) I'm tempted to reimplement a Ember.js application from work just for fun.
20:34the-kennydnolen: Thanks again for creating Om & fixing the problem in such a short time! Let me know if I can help you somehow.
20:35dnolenthe-kenny: feedback after you've have had a chance to kick around would be great
20:36dnolenthe-kenny: I think in the short term just going to focus on Om as rendering solution, there's a couple of patches I'd like to land in React to make things nicer
20:36xperajustin_smith: that has to do with reference types. I was interested in values
20:36dnolenlike a React Iterator so we can pass seqs to React
20:36dnoleninstead of putting things into arrays
20:37dnolenand a way to tell React exactly which children to look at, instead of considering all children (even though that's a cheap operations makes a different when you're showing a lot of data)
20:38dnolens/different/difference
20:40the-kennyRendering seems like a good focus, it's the most obvious and most useful part :) I'll send you some feedback when I've done something which is more than a todo list
20:41dnolenthe-kenny: cool, thanks
20:41the-kennyUntil then - Good night!
20:41dnolenthe-kenny: later
20:41Mandarthe-kenny, good night!
20:42justin_smithxpera: what it has in common with a reference type is that it is there to wrap a single value
20:42xperajustin_smith: but the key is what 'wrapping' means, right :)
20:43xperareference types wrap for a different reason, even though the english word is still 'wrap'
20:43justin_smithreference types wrap for multiple reasons
20:43justin_smithbecause the target needs coordinating, because it is not ready yet
20:44xperathat's an interesting way of looking at it
20:45xperai put together the MetaBox class after looking at how some of the value types did things
20:45xperai didn't want any other added semantics or meaning attached
20:46xperaalandipert thanks for your gist, that got my brain thinking
20:50alandipertxpera: np!
20:50xperajustin_smith: you got me thinking though. just re-read the O'Reilly section on reference types. I'm thinking about what would happen if the underlying value changed
20:50alandipertxpera: what did you end up doing?
20:50xperaalandipert: I wrote a Java class: https://github.com/bluemont/clj-metabox/blob/master/src/java/metabox/MetaBox.java
20:51justin_smithxpera: delays, futures, and promises never change
20:52alandipertxpera: nice! any reason for java?
20:52xperajustin_smith: are we just talking as an idea/alternative... or are you recommending the IDeref way strongly?
20:53justin_smithThe commonality of course is that they are a semi-opaque container for a value, the difference is in your case the value is immediately ready for usage and does not change - with the built in reference types they are either alterable or held for later in some way.
20:53justin_smithxpera: brainstorming, I don't have a strong opinion, just working out the case for / against.
20:53xperaalandipert: deftype would probably work just as well
20:53alandipertxpera: cool, def. worth exploring the other side of interop anyway
20:53xperaand would be better for clojurescript
20:54xperajustin_smith: yes, I don't want people changing the val -- I went to some trouble in the Java class to hide the val in _val
20:55xperajustin_smith: when I think of reference types, I think of identity and state, which seems like more than was needed for my use case
20:55xperamy goal was immutability, now that I think about it
20:55justin_smithhow do delay / future / promise / relate to identity and state?
20:56xperaalandipert: I haven't really dug into clojurescript. might be a good thing to try next
20:56xperajustin_smith: time!
20:56xperathey can change
20:57justin_smitha promise or delay or future do not change
20:57justin_smiththey may make you wait until they are ready
20:57justin_smithbut they do not ever change
20:57xperaok, fair point
20:57xperabut time matters for them
20:57justin_smithyes
20:58xperaand underneath, things ARE changing
20:58justin_smithmaybe that is the key point
20:58alandipertxpera: in cljs, it's neat, you can just extend imeta to whatever types since cljs is all protocols
20:58justin_smithxpera: underneath every calculation is a change, period
20:58xperajustin_smith: but when is that change ready and expected?
20:58justin_smithas far as the CPU is concerned even identity is a mutation
20:58xperawith values, operations happen and are ready immediately (more or less)
20:59xperawith the reference types, time is a factor underneath
20:59justin_smithunless they are lazy
20:59xperajustin_smith: yeah, but still, when you evaluate, it happens to the degree it happens. no time involvement.
20:59justin_smithnot with delay - delay gets set once, it is just that the calculation is lazy
21:00justin_smithbut regardless of time it will calculate the same calculation
21:01xperajustin_smith: well I stiil feel pretty good about a simple class that implements IObj :)
21:01xperabut I appreciate the interconnections and discussion
21:01yediwhats the most idiomatic way to aadd something to the end of the last vec in a vec of vecs? aka [[1 2] [3 4]], 5 => [[1,2][3 4 5]]
21:05alandipertyedi: (conj (pop v) (conj (peek v) x)) maybe?
21:06alandipertyedi: where v is the vec of vecs and x is the new item
21:07justin_smith,(map (fn update-deepest-vector [e v] (if (vector? (peek v)) (conj (pop v) (update-deepest-vector e (peek v))) (conj v e))) (range) [[0 1] [0 [1]] [0 [[1]]]])
21:07clojurebot([0 1 0] [0 [1 1]] [0 [[1 2]]])
21:08justin_smithmaybe I misunderstood the question
21:08alandipertor maybe (update-in v (dec (count v)) conj x)
21:08xpera,(let [v [[1 2] [3 4]] x 5] (conj (pop v) (conj (peek v) x)))
21:08clojurebot[[1 2] [3 4 5]]
21:09xperayedi: what alandipert said ^
21:09alandiperterr (update-in v [(dec (count v))] conj x)
21:12yedi(inc alandipert)
21:12lazybot⇒ 1
21:13yediis there a fn partition-vec that does the equivalent of (vec (map vec (partition _ _ coll)) ?
21:13yediso it returns of vector of vectors instead of a list of lists
21:13yedidon't wanna have to recreate what might already exist
21:13justin_smithwell mapv is (vec (map ...))
21:14justin_smithso you are down to (mapv vec (partition ...)) at worst
21:14justin_smithmapvv would be an OK name for #(mapv vec %)
21:27arrdembitemyapp: I suspect you're right that I need some sort of higher order structure here. damnit.
21:29bitemyapparrdem: http://i.imgur.com/IUoMA1y.jpg
21:30bitemyapparrdem: on that note: http://ocharles.org.uk/blog/guest-posts/2013-12-21-24-days-of-hackage-contravariant.html
21:30bitemyapparrdem: fyi: contravariants and profunctors have applications in probability mass functions...
21:31`cbp``bitemyapp: im officially free for two weeks.. kinda! Time to finish revise and eris and something else :-)
21:31bitemyapp`cbp: awesome :)
21:31arrdem`cbp: I was about to ask you to simplify your name. thank you.
21:31bitemyapp`cbp: I'm hacking with noprompt and another friend tomorrow on Frak++. Probably using vacation time to do some hacking on Simonides too.
21:32`cbpbitemyapp: what-s Frak
21:32bitemyapparrdem: but seriously, look at that article about contravariant.
21:35bitemyapp`cbp: noprompt's regex generation thingy. He wants to rewrite it in Haskell to get a mental model for compare/contrast.
21:35bitemyapp`cbp: you should join me in the doters :3
21:36`cbpbitemyapp: someone else beat you in inviting me unfortunately :S
21:36bitemyappNOOOOOOOOOOOOOO
21:37bitemyapp`cbp: toss me invite?
21:37`cbpits for europa universalis 4
21:37bitemyappnuts.
21:42danlentzhey bitemyapp: i liked your 'exception' macro in brambling and posted about it on google+
21:44danlentzboth as a good example of how to make effective use of the destructuring and for its intended purpose
21:45danlentzmy question is if there is a similar technique whereby optional args also can have default values when not provided
21:45bitemyappdanlentz: wasn't even mine! yogthos lent it to me :)
21:45bitemyappdanlentz: appreciate it though, glad somebody is looking at brambling.
21:45justin_smithdanlentz: destructuring with :or only works when destructuring maps iirc
21:46danlentzdatomic is really mind-blowing i'm very excited about it
21:49danlentzyour destructuring way of optional args is a hell of a lot more convenient than fn with multiple bodies approach
21:49danlentzsrry i droppped off for av sec colloquy is shit
21:49justin_smith,(let [[a & [b c] :as all :or {b 2 c 3}] [1]] [a b c])
21:49clojurebot[1 nil nil]
21:50justin_smith,(let [{:keys [a b c] :as all :or {b 2 c 3}} {}] [a b c])
21:50clojurebot[nil 2 3]
21:50danlentzwhoa cool
21:50justin_smithnotice with the vector the :or is a noop
21:50justin_smithit doesn't complain, it is just a noop
21:50justin_smithbut with a map it works
21:50danlentzsombidy needs to make a list of these usefgul destructuring templates
21:50justin_smithhttp://clojure.org/special_forms
21:52danlentzok i gues reading the docs could also work :)
21:52`cbpa noop?
21:52justin_smith`cbp: it does nothing, silently
21:53danlentzi think when i read it i blew through it w/o fully appreciating the importance
21:56bitemyapp`cbp: no-op
21:56bitemyapp`cbp: or nop
21:58danlentzclojures universal destructueing is really quite wonderful
21:59Apage43I'm often tempted to use it in a fn sig though, which typically means it shows up in generated API docs. A bit icky =P
21:59Apage43easy enough just to drop that down into a let tho
21:59justin_smithApage43: only icky if people don't know how to read it
22:00Apage43justin_smith: more that internal details of the fn are leaked into the docs
22:00Apage43like
22:01justin_smithwith a vector I can kind of see the point, but with a destructured map, the destructuring is the api
22:01Apage43(fn [some args {:as options :keys [foo bar baz] bar-baz :name-that-was-inconvenient}] ..)
22:01Apage43where in most cases I just want to see "options" there, and the docstring explain wtf you can pass
22:02justin_smithrenaming of keys is another question, yeah
22:26logic_progin cljs, is there a wya to get goog.dom/getElementById to be able to find elemnt, by id, of elements taht are (1) created (via js/documente create ...), but NOT yet attahed to the document?
22:26logic_progright now, goog.dom/getElemtnById seems to only return elements that are actually attached to the DOM tree
22:53bitemyappin case anyone was wondering, Sean McDirmid of Microsoft Research is a massive prick.
23:06tbaldridgeokay, I'll bite, how so?
23:09arrdembitemyapp: do tell
23:27rubber-duckanyone knows why clojurescript compile time goes up to 13 seconds from 1 second just from placing a .clj file inside the .cljs folder ?
23:28rubber-duckthe .cljs files don't even reference the .clj files just putting a .clj file in the clojurescript source folder makes cljsbuild take 13 seconds
23:31bitemyapptbaldridge: btw, are persistentarraymap and treemap in clojure-py supposed to be broken? Could only get hashmap working.
23:31bitemyapptbaldridge: PAM breaks with an indexing exception if you try to assoc. Didn't see any tests.
23:32tbaldridgeno they aren't supposed to be broken. But I haven't worked on clojure-py for over a year now. Feel free to submit a patch
23:32bitemyappspooky. k.