#clojure logs

2009-11-17

00:00jkkrameri did add this to my emacs config a while back, maybe related? (define-key global-map (kbd "RET") 'newline-and-indent)
00:00hiredmandeclare just lets you defn functions that reference vars that are not defined yet
00:00technomancyjkkramer: the minibuffer has its own keymap; it shouldn't be affected
00:00Draggorhiredman: Is there any way to get around this? I greatly dislike the idea of having to procedurally define things
00:00slyrustechnomancy: what was that we were saying about how awesome these magic download-and-install-package-manager-thingys are? :)
00:01jkkramerthe only place i have swank-clojure installed is in ~/Library/clojure/swank-clojure
00:01technomancyslyrus: heh; yeah M-x clojure-install was always an interim solution until I could get elpa working.
00:01hiredmanDraggor: I have no idea what "procedurally define things" means
00:03arohner_Draggor: the var must be declared before it can be referenced when compiling. At runtime, the var must have a value when it is referenced or you get a unbound var exception
00:03arohner_if you don't want it to have a value, set it to nil
00:04jkkramereven with minor obstacles, clojure-mode made my life a lot easier. none of the other IDE/editor solutions i've tried were as good
00:05jkkrameralthough, now it's harder to poke fun at emacs users, since i am one now
00:05arohner_following your earlier example, something is calling (func1 some-arg) before it has a value. that can't work in any sane PL
00:07slyrusjkkramer: i'm so far gone that I have a hard time imagining that folks would consider using anything else (except climacs, of course... :) )
00:07slyrusI assume most emacs users here use paredit?
00:08jkkrameri still hit ESC whenever i intend to invoke some command
00:10technomancyparedit is bliss.
00:10jkkrameri installed paredit but have no idea how to use it
00:11technomancyjkkramer: http://p.hagelb.org/paredit-outline
00:11technomancyone day that will become a screencast... not sure when. =)
00:11jkkramerooo
00:12jkkramerthat's what i've been looking for. quick-start guide
00:12jkkrameryou are awesome
00:12lgastechnomancy: re. the clojure wide-finder from your blog, this version gets the time down to about ~2.7 seconds (from ~272) on the same input file I posted to your blog about: http://pastie.org/702158
00:12lgasit still doesn't really peg my CPUs during that 2.7 seconds though
00:13technomancylgas: wow! so partitioning inside the pmap makes a pretty big difference?
00:14lgasyeah... otherwise I guess the unit of work that each thread is doing is too small.
00:15lgasI don't have time tonight but I'm going to try to pull down some larger logs and try processing them (and also changing the regex so that it matches more of our URLs).
00:15technomancyyeah, I realized the original regex was more complicated
00:15technomancyalso: it's hard to find sample log files!
00:18lgasYeah. We have some decently sized log files, but I can't give them out unfortunately. The one I've been testing with is 1.1m lines. But out of that 1.1m lines it only produces 48 matching URLs and of those a couple occur 4 times, a couple 3, a couple 2, and most just once, so it may not be the best test.
00:23Drakesonis slime trunk still broken with clojure ?
00:24Drakeson(it broke for me around Oct 30)
00:24technomancyyep
00:24slyrusI'd put it differently. swank-clojure is broken wrt slime HEAD
00:24slyrusthe offending commit is: addc5be70a489cdc8ed555a2fed7273040da196e
00:24slyrusbefore that you should be ok
00:24technomancyis it un-idiomatic to use doto in non-java contexts?
00:25slyrus(not to blame swank-clojure, as this clearly seems to be changes in slime that broke swank-clojure)
00:25technomancyDrakeson: if you must work from git, use the technomancy fork of slime on github; else use elpa
00:25technomancy(I haven't fixed it, I just haven't updated it with the breaking change yet)
00:25hiredmantechnomancy: I think it must be
00:26arohner_technomancy: yeah, I'd like to see an example of that
00:26slyrusDrakeson: or, for a second opinion, just make sure you checkout the version right before addc5be70a489cdc8ed555a2fed7273040da196e :)
00:26arohner_I've never needed to outside of java-interop
00:26technomancyhiredman: I like (doto (str (:root project) "/Manifest.txt") (spit (str "Main-Class: " (:main project)))) much better than the let-using equivalent
00:27technomancybut it reads a little funkily
00:27hiredmanI see
00:27technomancy(apart from the fact that it's squashed onto one line)
00:28arohner_where is let-using?
00:29qedhttp://clojure.pastebin.com/m1c41118e -- could someone tell me why im getting an error that says recur is missing args?
00:29hiredmanarohner_: it would be (let [x (str (:root project) "/Manifest.txt")] (spit x (str "Main-Class: " (:main project))) x)
00:29technomancyarohner_: left as an exercise to the reader =)
00:29arohner_oh, I thought there was an actual function named 'let-using'
00:30hiredmanI have a marvelous example that this terminal is too narrow to contain
00:30_atoqed: you're calling recur with 2 args while your loop has 6 bindings
00:30technomancyhiredman: that trailing x bugs me
00:30qed_ato: hmm i thought i had this loop/recur stuff figured out
00:30hiredmantechnomancy: I as well
00:30Drakesonslyrus: I have been doing that ever since it broke
00:31qed_ato: do i have to do something to those args in recur?
00:31qedcould they just be empty lists?
00:31Drakesontechnomancy: well, the rate of changes in slime trunk is fairly high. I would rather stick to a fork of swank-clojure
00:32_atoqed: they could be... then v2 v3 etc are going to be assigned to empty lists? is that what you want?
00:32qedno, i just want to run x2->x6 on every inc of cnt
00:32Drakesonbut again, I haven't look into what actually broke between the two, so I don't know if slime is going in the wrong direction (to deserve a fork) or swank-clojure should just keep up with slime's changes.
00:33technomancyDrakeson: I don't mean "fork" in the negative sense, merely the "I've branched and haven't bothered to update" sense
00:34Drakesonoh, I made my "update-clojure" script to use a specific commit for slime since then
00:35_atoqed: ah, move all the v2 v3 v4 etc into a let-binding inside the loop then
00:36Drakesonbtw, will it make sense to have swank-clojure be merged into upstream slime (as there is ruby, etc. backends for slime)
00:36qed_ato: before or after the loop's binding?
00:36_atothe bindings on loop should just be the ones you want recur to assign to
00:36qedis the let-binding part of the body of the loop
00:36hiredmanhttp://gist.github.com/236676 <-- with-open? we don't need no stink'n with-open
00:37_atoqed: lets try this again: http://etherpad.com/XIbR7KzRQl
00:38arohner_hiredman: what about exceptions?
00:39hiredmanarohner_: I'm not exceptional
00:51qed:)
00:59st3fani'm doing a clojure talk here in toronto on thursday
01:01st3fantime for zzz
01:03Drakesonst3fan: where?
01:04Drakeson(assuming you still haven't zzz'ed!)
01:05technomancyfolks: it's time to discuss what the collective nouns should be for Clojure terms
01:05technomancy"An alignment of vectors"
01:05technomancy"A lethargy of lazy-seqs"
01:05technomancy"A cartography of maps" (sorry)
01:13adityo"An Agency of Agents"
01:14technomancyyes! that's what I'm talking about.
01:14hiredman(Secret) Agency
01:14adityo:)
01:14_atoA conspiracy of conses?
01:15hiredman(def #^{:private true} a [(agent nil (agent nil)])
01:17technomancy"𝅘𝅥𝅮 Secret ... Aaaaaagent Man 𝅘𝅥𝅯"
01:18adityoLook up the CAD, Clojure Agent Directory ;)
01:24qedInstead of 007 it's BigO1
04:21ngocHi, how to convert Java's ArrayList to Clojure's array and Java's HashMap to Clojure's map?
04:31Chousukengoc: (into [] arrayList) or (into {} hashmap) should work
05:22djpowellI suppose it ought to be possible to automatically generate a method-map from a datatype's fields. Would be quite handy so that I can have 'subclasses' that override the field accessors with more complicated logic, and then I don't need to change client code from (:my-field o) to (my-accessor o) if I decide that simple fields aren't good enough
06:05AWizzArd~max people
06:05clojurebotmax people is 214
06:05AWizzArduh la la
06:43krumholthi, is there a difference between sync and dosync?
06:44rhickeykrumholt: dosync is built on sync
06:44rhickeysync has a (currently unused) spot for options, dosync elides that
06:44krumholtrhickey, ok thanks
06:45rhickeyprefer dosync for now
06:45krumholtwill do thanks
07:21djpowellurgh, macros confuse me. I wanted to autogen a protocol based on a datatype's fields.
07:29AWizzArdand?
07:32djpowelli'm getting confused. as defprotocol is a macro, does that mean I need to write a macro to construct a call to it?
07:39rhickeydjpowell: yes
07:40rhickeybut what are you going to generate for the fields - accessors? you already get them for free
07:42djpowellwell, I want to (in some 'subclasses') override some accessors to do some more complicated stuff, like have fallbacks to other fields. so I don't want to have to change all client code to change from (:field o) to (accessor o)
07:42djpowellso i wanted to have a base method-map that has accessors for the fields, that I can override
07:43rhickeydjpowell: there is no equivalent to subclasses with deftype/protocols
07:45djpowellno, but I can have a bunch of deftypes representing some related entities, and have them implement a common protocol, along with a protocol for their type specific operations
07:46djpowelland I can override the method-map from the defaults to type-specific versions where i need something more than getting the field directly
07:46rhickeydjpowell: ok, I'm not trying to dissuade you, just don't want you to be disappointed later :)
07:47rhickeyso, right now the mechanics of defprotocol are wrapped in a macro. Exposing that as a function might be useful
07:49djpowelli'm just toying around with things at the moment, looking at how these features might help me. cause I have some java right now (as you can probably tell!), that really needs some of the dynamic features that deftypes/protocols seem to offer
07:51AWizzArdbtw, rhickey, why is a hierarchy of types bad? You mention something like this on the Protocols wiki page.
07:56rhickeyAWizzArd: the long answer would take hours. A short answer is, a) I didn't say that, and b) if you can provide features (protocols/mixins) without requiring derivation/hierarchy, that's better
07:57lpetitrhickey: what would you consider the most interesting "paper" on this subject, that anyone could read to make one's own opinion without making you repeat things over and over again ?
07:57AWizzArdMaybe in your future talks you will leak out more details about it :)
07:58djpowellrhickey: I might be ok with using keyword accessors, and distinct protocol methods for the cases where I need different behaviours. Not sure yet.
07:59fogus_lpetit: This one is not bad: http://www.scala-lang.org/docu/files/IC_TECH_REPORT_200433.pdf
08:00rhickeyit's better because hierarchy creates a world in which some people are saying, "if something is an X, do this that way" while others may say "foo instanceof Y", and still others say "Y isa X" and managing the implications becomes impossible
08:00fogus_lpetit: Scala-centric of course
08:00rhickeyfogus_: I don't think so. traits are a good example of what I'm trying to avoid with protocols
08:02fogus_rhickey: Interesting. I've always liked the discussion on the expression problem in that paper, but if you have a link more in line with your own thinking, then I would also be interested in reading it
08:05fogus_rhickey: RE: Traits. You're trying to avoid them because they do not solve the problem that you presented above, no?
08:06rhickeyI think Scala implicits shows they don't really address the expression problem in as shown in the paper
08:06rhickeytraits are classes, so can have impl they have no pure interface-like spec construct
08:06rhickeyprotocols are specs only
08:07rhickeytrait introduce hierarchy and isa, protocols don't
08:07rhickeyyou can't imbue a class with a trait other than with implicits, which requires an adapter allocation and introduces identity and other isa problems
08:08rhickeyvs extending a protocol to String
08:08fogus_rhickey: You had to mention implicits... they are the skeleton in Scala's closet. ;)
08:08rhickeyand mixing in implementations by method map composition, no hierarchy required
08:09rhickeyso, yes, traits/implicits are in the same expression problem space, they are very different from protocols
08:10rhickeyprotocols - pure specs, no adapters, compositional mixins
08:10fogus_I see that more clearly now.
08:11rhickeytraits/implicits - impure specs, implicit adapters, hierarchical mixins
08:12fogus_rhickey: I have a lot of experience with Scala and it's M.O. so it's helpful for me to understand the comparison. Thanks
08:14djpowellhmm, juxt seems slightly handy for composing method impls from calls to other methods
08:15djpowellperhaps
08:45ohpauleezwhen writing something like: (let [x [1 2 3 4 5]] (nth x (rand-int (count x)))) one could do: (let [x [1 2 3 4 5]] (nth x (-> x count rand-int))) ...
08:45ohpauleezbut is there something more concise?
08:48hoeckohpauleez: I have written a little rand-nth function for this case, like (rand-nth [1 2 3 4 5]), couldn't find a more concise way
08:48ordnungswidrighoeck: a rand-nth function is concise for the user of the rand-nth function
08:49ohpauleezis there a way to man-handle something like %1 when not making anon-functions/lambdas
08:50ohpauleezfor example: (-> x count rand-int (nth x %1))
08:50ohpauleezwhich I guess isn't more concise, so nvm haha
08:57st3fanwhat does -> do?
08:58chouser,(let [x '[a b c d e]] (->> x count rand-int (nth x)))
08:58clojurebotc
08:59ohpauleezit threads the values from one call to the next
08:59chouserst3fan: it rearranges your code
08:59fogus_st3fan: http://blog.fogus.me/2009/09/04/understanding-the-clojure-macro ;)
08:59ohpauleezthanks chouser!
09:00st3faninteresting :-)
09:02ohpauleezchouser: what's the rationale for quoting the vector
09:02chouserohpauleez: so I didn't have to quote each of the symbols
09:03ohpauleezahh right right
09:03ohpauleezthanks
09:03chousersymbols instead of keywords or strings because I can type each with a single keystroke instead of 2 or 3. :-)
09:09esj->> is related to -> how ? Doesn't seem to be on the reader section of the web-page.
09:09ohpauleez,(doc ->>)
09:09clojurebot"([x form] [x form & more]); Threads the expr through the forms. Inserts x as the last item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the last item in second form, etc."
09:09ohpauleezit stacks on the last, not the second arg
09:14esjaah, brilliant, thanks.
09:16ohpauleeztotally welcome
09:27fogus_Is it possible to destructure and coerce at the same time using `let`?
09:28cemerick"coerce"?
09:30AWizzArd,(doc coerce)
09:30clojurebotExcuse me?
09:31ordnungswidrigwatching rick's infoq presentation right now. I like the idea of identity beaing a series of values. Is there more information on this topic? I see that patch-theory is related to this,
09:31cemerickfogus_: do you mean hinting in a destructuring form?
09:31cemerickif so, sure
09:31fogus_I'm ripping out the chars from a string and want to coerce them to int. At the moment I have (let [[a b] "xy"] (println (int a) ", " (int b)))
09:31cemericksure, you can hint a and b
09:32cemerickyou can hint any symbols in a binding-form
09:32cemerickregardless of destructuring, etc
09:32chouserhinting is not coersion
09:32fogus_cemerick: I don't think hinting gets me what I need.
09:32chouserfogus_: I think you have to use two separate steps
09:32fogus_chouser: As I suspected
09:33chouserthis is not the only case where it feels like it would be useful to call more or less arbitrary functions during destructuring
09:33chouserI think languages with flexible pattern-matching mechanisms can allow that to some extent
09:33cemerickfogus_: oh, you are actually converting, sorry, didn't read the sample carefully enough
09:33AWizzArdfogus_: can you hae your let also be something like (map int "xy")?
09:33AWizzArdhae ==> have
09:34rhickeychouser: do you have any examples in other langs?
09:34fogus_cemerick: no worries.
09:34fogus_AWizzard: That's it!
09:34AWizzArdk
09:35fogus_,(let [[a b] (map int "xy")] [a b])
09:35clojurebot[120 121]
09:35fogus_AWizzard: Thank you
09:36chouserrhickey: not off the top of my head, but I'm pretty sure I've seen somewhere a general mechanism where you can provide both a constructor and a deconstructor. I'll see if I can find it.
09:41patrkrishey, i'm looking for something to do for my masters thesis, and since I like Clojure very much, I thought about maybe doing something about distributed parallelism in Clojure? Along the lines of Erlang. What do you think?
09:42ohpauleezrefs, STMs, agents, AND actors?
09:42ohpauleezhaha
09:42patrkristhat's a stupid idea? :P
09:43ohpauleezno, I personally think it's good
09:43ohpauleezI once wrote a networked namespace for python
09:43ohpauleezto support a distributed testbed
09:43patrkrisi don't know if it is even possible or whatever... I'd just like to work with Clojure ;)
09:43fogus_chouser: Would Scala's unapply mechanism fit your description? It's not an arbitrary function however.
09:44rhickeypatrkris: I'd love to see more work done around predicate dispatch.
09:45chouserfogus_: I think that must be it. What I'm thinking of would have to be a feature of either Scala or Haskell, and it feels more like Scala.
09:45chouserbut yes, I see that it is controlled by the type of thing being destructured, not arbitrarily specified at the moment of destructuring. :-/
09:46patrkrisrhickey: have you or others done any work in that regard?
09:48rhickeyI did some Chambers/Chen style stuff in a prototype for Clojure
09:49rhickeybut to move it forward I think you'd want some more sophisticated notions of logical implication, maybe combining it with the datalog stuff
09:50rhickeythe implications in Chambers/Chen are derived from the type hierarchy, or possibly hardwired numeric implications, not a general system
09:50rhickeysupporting arbitrary logic and good performance is still a research topic, AFAIK
09:52ordnungswidrigrhickey: do you think there a connection points between the idea of "identity being a series of values" and patch theory?
09:54rhickeypatch theory as described where?
09:54ordnungswidrigrhickey: as implemented by darcs or git.
09:55ordnungswidrigrhickey: well, git does not really patch theory but a repository is basically a collection of functions applied on a state in distributed manner. Like STM, I think.
09:55rhickeyI know darcs has some theory behind it, GIT is definitely a persistent data structure on disk
09:55rhickeybut the whole notion of merging complicates things
09:56ordnungswidrigrhickey: STM has the same problem, or not? I two concurrent processes try to execute conflicting changes they'll have to be merged.
09:57ordnungswidrigs/I two/If two/
09:57AWizzArdordnungswidrig: I have this same issue with my in-ram db.
09:57AWizzArdClojure is fortunately already doing a lot of needed work for you.
09:57ordnungswidrigAWizzArd: but the merge problem exists anyway
09:57AWizzArdthis is true
09:58AWizzArdif you have a db and two threads snapshot it and calculate a new db each, then the first who wants to check is data in wins. The second thread will have to merge.
09:58AWizzArdEach thread which makes a snapshot will have to create its own replay-log, from which merging is possible.
09:59lpetitAWizzArd: won't the commute function help here ?
09:59ordnungswidrigAWizzArd: using patch theory you can provide a way to merge the conflicting changes. e.g. inc and dec can be commuted without changing the result.
09:59AWizzArdlpetit: not really
09:59ordnungswidrigAWizzArd: what is the underlying data model of your db?
09:59AWizzArdordnungswidrig: maybe we talk about different things
09:59rhickeyordnungswidrig: STM does no merging other than commute, otherwise there are retries
09:59AWizzArdordnungswidrig: clojure data structures
10:00rhickeymerging and operational state transform etc are all interesting
10:00rhickeythey get application-domain specific though
10:00AWizzArdright
10:01rhickeyso, merging edits to a text file is an application domain
10:01ordnungswidrigrhickey: I expect the things to come together at some point of time. Yes, the domain specific part is often surprisingly easy.
10:01rhickeywell, commute is there
10:01rhickeyyou write the fn
10:02ordnungswidrigrhickey: merging text is hard because the intention of the change is lost. Talking of key value sture the merge model is easier.
10:02ordnungswidrigOh, there is a commute fn?
10:02ordnungswidrigI mean a way to specify a domain specific one?
10:02rhickeyClojure's STM has commute
10:02ordnungswidrigrhickey: As I said. The things are coming together :-)
10:02patrkrisrhickey: thanks - you mentioned a lot of things that I'll need to look up, but sounds interesting (distributed Clojure that is)
10:02AWizzArdcommute allows for more parallelism than alter I think?
10:03AWizzArd,(doc commute)
10:03clojurebot"([ref fun & args]); Must be called in a transaction. Sets the in-transaction-value of ref to: (apply fun in-transaction-value-of-ref args) and returns the in-transaction-value of ref. At the commit point of the transaction, sets the value of ref to be: (apply fun most-recently-committed-value-of-ref args) Thus fun should be commutative, or, failing that, you must accept last-one-in-wins behavior. commute allows for more
10:03fogus_,(doc commute)
10:03ordnungswidrigAWizzArd: a commute function can event be interactive. Like a mergetool in DVCS
10:03clojurebot"([ref fun & args]); Must be called in a transaction. Sets the in-transaction-value of ref to: (apply fun in-transaction-value-of-ref args) and returns the in-transaction-value of ref. At the commit point of the transaction, sets the value of ref to be: (apply fun most-recently-committed-value-of-ref args) Thus fun should be commutative, or, failing that, you must accept last-one-in-wins behavior. commute allows for more
10:03fogus_Whoops..
10:03rhickeypatrkris: I wasn't suggesting work on distributed Clojure, but on (non-distributed) dispatch
10:04ordnungswidrigAWizzArd: is you db public?
10:04AWizzArdordnungswidrig: i don't know at which level you want to be aware of changes for merges. I want highlevel merges. One entry in the replay-log resembles a full transaction.
10:04AWizzArdordnungswidrig: Not yet, I will be working on having it opensourced :)
10:04AWizzArdClojures snapshots are so cheap, I can have tons of them in ram.
10:05patrkrisrhickey: see, I don't know anything... yet :)
10:05AWizzArdSo, one can have undo, and other nice things.
10:05chouserfogus_: you were right. unapply.
10:06ordnungswidrigAWizzArd: seems like were working on similiar topics.
10:06rhickeypatrkris: http://portal.acm.org/citation.cfm?id=320407
10:06chouserBut it looks like you can do arbitrary work, you just have to stick it in an unapply method of a class.
10:06AWizzArdordnungswidrig: gut :)
10:06chouserhttp://www.scala-lang.org/node/112
10:08rhickeychouser: do you get only one unapply per type?
10:09fogus_chouser: Arbitrary work yes, but still bound to the case class (or somewhere along its heirarchy)
10:10lisppaste8Chouser pasted "simplified unapply example" at http://paste.lisp.org/display/90579
10:10patrkrisrhickey: thanks, i'll take a look. If you have any other ideas for a masters thesis subject, I'd be happy to hear them
10:10patrkrisrhickey: that is, additional ideas
10:11chouserSo there's only one unapply for Twice, but because any number of classes could take an Int as their arg in unapply, and you could specify any of them in a case expression.
10:14chouserso just like [a] means roughly assoc in normal expressions but nth in destructuring forms, I suppose int could mean "convert a to an int" normally but "assign a to an int" in destructuring?
10:15chouser (let [[(int a) (int b)] "xy"] ...) ?
10:15rhickeyseems pretty easy (let [(destructure-fn a b c) x] ...), where destructure-fn takes one arg and returns a 3-tuple
10:16rhickeyarbitrary functional destructuring
10:17fogus_So in the original case it would be: (let [(int a b) "xy"] ...) ?
10:17rhickeyI doubt int is going to mean that, but some fn
10:17rhickeyintify
10:17chouseryes, that does seem simple. That's orthogonal to the naming -- would there be 'int' and 'as-int', or would destructuring somehow call a different fn when it sees int in a destructuring form
10:18fogus_What would `intify` return?
10:18rhickeyI don't think int is that intersting, also might be covered by type hints at some point
10:20fogus_OK, then would would `destructure-fn` return? A seq?
10:20chouserwell, something that 'nth' could be used on, so a seq or vector
10:21fogus_OK. Got it.
10:22chouser(let [(vec a b c) x] ...) would be the same as (let [[a b c] x] ...), wouldn't it?
10:22chouserthat seems -- right. :-)
10:23rhickeychouser: yes
10:23rhickeybut would make a temporary vector out of x if it wasn't already
10:24rhickeyso, kind of a waste
10:24chouseryes, not a practical example
10:24rhickeyin general, (let [(foo a b c) x] ...) would be the same as (let [[a b c] (foo x)]
10:25rhickeyso, still not that interesting
10:25chousermore interesting when nested
10:25rhickeyexcept when used in internal pieces
10:25chouserright
10:25rhickeyheh
10:25chouserwhich was fogus_'s original case
10:26chouserhad to use map on the expression side to get it, and that only worked because he wanted the same fn applied to all pieces
10:27chouser(let [{:keys [name (int age)]} person] ...)
10:27fogus_(let [destruct-fn #(vec %) (destruct-fn a b c) x] ... ) still not incredibly interesting, but fun
10:28chouserheh
10:28fogus_I could go all day like this.
10:31chouser(let [{:keys [name (Integer. age)]} person] ...)
10:32chouser(defn intify [x] [(Integer. age)])
10:32chouser(let [{:keys [name (intify age)]} person] ...)
10:33chouserit seems a shame to require intify be defined just to stuff a result into a vector.
10:34chouser(let [{:keys [name (#(list (Integer. %)) age)]} person] ...)
10:34fogus_yeah
10:37chouserbut since a destructure-fn doesn't know how many values it's being required to produce, if they can ever support more than one, they all would need to return a collection even for a single item.
10:37chouserthat would generally rule out direct use of most existing fns -- new ones would be written to be used in destructuring.
10:38fogus_Unless you want to create a new special type of function that returns a coll if one isn't already reurned... I doubt anyone wants to go down that road
10:38cgrandor change the syntax to (let [(foo [a b c]) x] ...)
10:39chouserfogus_: yeah, and that runs into issues when you return a coll that's meant to be a single item, so it doesn't get wrapped... bleh
10:39fogus_chouser: Yep. No way to know for sure
10:44chousercgrand: so the existance of [] in the args would tell destructuring to expect a seq to unpack instead of a single value
10:44lpetitchouser: cgrand's idea fixes it, no ?
10:44lpetitchouser: or is it the other way around ? (I guess soà
10:44lpetit)
10:45lpetitchouser: if foo is a function that does no collection wrapping, provide it yourself around the parameters ?
10:47cgrandchouser: (let [(foo x) y] ...) would always be equivalent to (let [x (foo y)] ...) no matter what x is (symbol, map, vector, another destructuring fn...)
10:48rhickeycgrand: and (foo a b c) not meaningful then
10:48cgrandrhickey: sadly yes
10:48rhickeybut very strange to have bindings of return of foo appear as args to foo
10:48fogus_What about: (let [[(destr-fn a b c)] x] ... ) ? This could either mean, optionally wrap the result in a coll or always do so.
10:49rhickeyI wouldn't want to explain it
10:49rhickeydestructuring confusing enough as is
10:49fogus_rhickey: True
10:50cgrandwhat about (let [([a b c] foo) x] ...)? the destructing fn isn't in fn position anymore
10:50rhickeymaybe (-> foo a), (-> foo [a b c])
10:50cgrandor (let [(:as foo [a b c]) x] ...)
10:50rhickeythe last position being the bindings
10:51cgrandrhickey: yes
10:51rhickeyyes to what?
10:51rhickey-> is nice at it chains, and leaves room for args
10:52cgrandyes to (-> foo a), (-> foo [a b c])
10:52rhickey(let [(-> foo (bar 5) [a b c]) x] ...
10:52rhickeycould do -> and ->>
10:52djorkhow about this: (let [[a b c]] (let [x (foo a b c)] ...))
10:53djorkand we don't make destructuring more complicated
10:53djork:)
10:53rhickeydjork: I don't understand what that says
10:54djorkI'm just saying do destructuring in one step and them apply a fn to the destructured args in a separate let
10:54fogus_rhickey: Would -> and ->> therefore be the only allowed destructure-fns?
10:54djorkwould there really be special cases for onl ycertain symbols in fn-position of a list
10:55rhickeyfogus_: possibly
10:55cgrandrhickey: (let [(-> foo (bar 5) [a b c]) x] ...) would be equivalent to (let [[a b c] (-> x foo (bar 5))] ...), right?
10:55rhickeycgrand: yes
10:56rhickeybut with the nesting support
10:56cgrandwithout nesting support it wouldn't be interesting
10:56lpetitThe use of existing operators (-> or ->>) confuses me
10:57lpetitWhat if I want to use regular -> in the (bar 5) expression ?
10:57rhickeylpetit: really? I think they save it
10:57fogus_In the original case: Would we therefore have (let [(-> int [a b]) "xy") ?
10:58fogus_That is (let [(-> int [a b]) "xy"] ... )
10:58lpetitrhickey : what would (let [(-> foo (-> bar baz) [a b c]) x] ...) mean ?
10:58rhickeylpetit: ordinary code goes anywhere except in the last position, which is treated as a binding construct
10:58chouserI'm afraid it would be (let [[(-> int a) (-> int b)] "xy"] ...)
10:59lpetitrhickey : oh yes, it works
11:00fogus_chouser: :(
11:00rhickeychouser: or (let [(-> coerces int [a b]) "xy"] ...)
11:02cgrandor (let [(->> (map int) [a b]) "xy"] ...)
11:02fogus_cgrand: beat me to it
11:02rhickeycgrand: right, use functions to help us
11:03fogus_I like it
11:11chouserhehe
11:12fogus_I would be happy to work on it... as long as no one minds it taking until Clojure 3.0
11:17qedso is -> the thrush combinator?
11:17qedis that rght?
11:17qedright*
11:18qedTxy = yx
11:23chouser-> is a macro
11:24chouser,(-> [x (range 5)] (for (/ x 2)))
11:24clojurebot(0 1/2 1 3/2 2)
11:31AWizzArdCan deftype take a docstring? When yes: at what position?
11:34fogus_qed: -> is the Thrush... but because Clojure is not lambda calc it provides different forms to handle different argument positions
11:49fogus_,(#(* % %) (->> (range 1 100) (filter even?) (reduce +)))
11:49clojurebot6002500
11:49sh10151Is there an idiomatic way to check for tree equality in zip-filter.xml type code?
11:50sh10151basically I want to filter based on whether or not some child nodes are equal to a given node
12:02qed(recur b (+ a b) (inc term)) --> What is happening here with the b all by itself?
12:02Chousukethe loop has three parameters and on the next iteration the first one is b?
12:04qednot sure I follow
12:04qedwhat do you mean the first one?
12:04Chousukethe first parameter to the loop
12:05Chousuke(loop [a 1 b 2 c 3] (recur c b a)) ; infinite loop that shuffles a, b and c :P
12:05Chousukehm, well, b actually never changes.
12:05qedbut you swap a and c around b
12:05Chousukebut a and c keep switching values :)
12:06qedhm, interesting, i didnt know you could control recur's order
12:06Chousukeorder?
12:06Chousukeyou just specify the values the loop will have on its next iteration
12:06ohpauleezqed: recur is like calling the function name again
12:06Chousukebound to a, b and c in the order they were declared in the initialisation.
12:07ohpauleezexcept instead of going down the call stack
12:07ohpauleezit does it in place
12:08ohpauleezadditionally, recur can call back to a loop, and not a function call, but the idea stays the same
12:08Chousuke,(loop [a 1 b 2] (when (< b 5) (print b) (recur b (inc a))))
12:08clojurebot223344
12:09qedoh, so it's like two nested for loops?
12:09Chousukeno, just a single loop with two "variables"
12:10ohpauleeznot even, it's conceptually like writing: (defn some-name [a 1 b 2] (when (< b 5) (print b) (some-name b (inc a))))
12:10chouserhuh. I think finished it during a single status meeting.
12:10ohpauleezchouser: finished what?
12:11chouser(let [[a (-> str b) c] [1 2]] (list a b c)) ==> (1 "2" nil)
12:11ohpauleezalright!
12:11Chousukeon the first iteration, the values are a = 1, b = 2, on the second, a = 2 (b), b = 2 ((inc a)), and on the third a = 2, b = 3, etc...
12:11AWizzArdchouser: Can deftype take a docstring? Do you know if it is planned that the printed representation of a deftype can be read/read-string'ed back?
12:11drewr,(filter identity [1 nil 2 3 nil])
12:11clojurebot(1 2 3)
12:11qedthank you
12:11qedChousuke: that makes sense now, thanks man
12:12chouserah, not quite yet...
12:13fogus_chouser: Wow, you're much faster than me. Clojure 3.0 is not even close
12:13chouser:-P
12:13chouserit's about 6 lines of code
12:13Licensergood evening everyone, how is the clojure world? Everything functioning fine I hope?
12:14fogus_chouser: Do you mind sending me a patch?
12:14fogus_Or a link to a branch
12:15chouserit only nests in some cases, not yet all
12:16Chousukethe -> is not the same as the -> macro is it?
12:16lisppaste8Chouser pasted "-> destructuring [incomplete]" at http://paste.lisp.org/display/90584
12:16chouserChousuke: very nearly
12:18fogus_chouser: very nice
12:19ohpauleezchouser: cool
12:20cgrandchouser: shouldn't '#{-> ->>} be #{'-> '->> `-> `->>}?
12:21chousercgrand: yep, thanks.
12:22ohpauleezcgrand: great post in the blog, I really enjoyed it
12:22cgrandohpauleez: thanks
12:25qedcgrand: just reading now, but while we're on the subject, i love your blog, how do you do your syntax hilighting?
12:25lisppaste8Chouser annotated #90584 "fixed `-> and recursive final form" at http://paste.lisp.org/display/90584#1
12:26cgrandqed: pygments
12:26chouserI think that's everything except (let [{:keys [(-> str a) b] {:a 1 :b 2}] a)
12:27cgrandI resurected an old pygment plugin for wordpress http://gist.github.com/213649
12:27AWizzArdchouser: what should your last example accomplish?
12:27chouser(let [[a (->> (map int) [b c])] [\a "bc"]] (list a b c)) ==> (\a 98 99)
12:27qedcgrand: ah i see -- i tried using pygments with my rails blog but gave up and have just been converting my code with pygments and then pasting in the html
12:28qedcgrand: where'd the theme come from?
12:28cgrandqed: Barecity http://shaheeilyas.com/barecity/
12:28chouserAWizzArd: in short, the final form in a destructuring -> can now itself be a complex destructuring form
12:29qedcgrand: i meant the pygments coloration
12:29qedmy pygments highlighted code doesn't look like yours
12:29cgrandqed: let me check
12:33cgrandqed: style=manni
12:33qedah-ha, cool, thank you
12:35chouserhuh. so (let [{:strs [(-> str a)]} {"a" 1}] a) can only be supported when the a in (-> str a) is a single symbol, not a destructuring coll
12:36chouserit's still worth doing, though, right?
12:36rhickeyprobably not
12:36chouserok! then I'm done.
12:37rhickeywow
12:37chouserrhickey: you saw the patch paste? you want it in dev-clojure?
12:38rhickeyshould get an assembla entry I think
12:38rhickeyif you don't mind - thanks
12:38replaca_rhickey: it looks like clojure.parallel is not compatible with the latest jsr166y stuff since ParallelArray has moved to extra166y.jar
12:38chouserit was easy because requiring -> was brilliant
12:40rhickeyreplaca_: clojure.parallel is not going to be moved forward, as the ParallelArray is not making it into JDK 7. The new par branch will be the future of that stuff, on top of ForkJoin directly
12:41rhickeyreplaca_: the other advantage of the new par approach is that it uses the persistent data structures directly, not converting to/from parrays
12:42replaca_rhickey: OK, so I won't worry about it for the autodoc then :-)
12:43rhickeyreplaca_: right :)
12:43replaca_thanks
12:43rhickeythank you - the doc stuff looks great!
12:46lisppaste8dakrone pasted "why does this script error out?" at http://paste.lisp.org/display/90589
12:47replaca_rhickey: thanks. I need to get it working with contrib again and then I'm going to try to get it doing multiple branches, but that's tricky for the core (since I'm using things that depend on a given version of core)
12:47dakronecan someone enlighten me as to what I'm doing wrong with that script?
12:49dakronesince (ioc-file "lipsum.txt") seems to work without any problems
12:53cgranddakrone: ... clojure.lang.Script ./ioc.clj -- lipsum.txt
12:54dakronecgrand: if I do that, there's no output at all
12:56tomojcan clojure.test unwind the stack on a failure?
12:57cgranddakrone: because map is lazy, here you should use doseq instead: (doseq [file *command-line-args*] (ioc-file file))
12:57tomojor would I have to throw exceptions on failures and catch them at the top-level?
13:04dakronecgrand: I changed it to doseq and it still errors out, same error
13:05cgranddakrone: doseq and -- ?
13:05dakronecgrand: okay, that did it, didn't realize I needed the -- also
13:06lisppaste8dakrone annotated #90589 "fixed version" at http://paste.lisp.org/display/90589#1
13:06dakronecgrand: thank you very much
13:06cgranddakrone: yw
13:27dnolencgrand: great blog post on optimizing Life of Brian.
13:45chouserhttp://www.assembla.com/spaces/clojure/tickets/211-Support-arbitrary-functional-destructuring
13:49technomancythat was quick.
13:51mtmtechnomancy: playing with the latest leiningen and getting "Component descriptor cannot be found in the component repository: org.apache.maven.artifact.manager.WagonManager"
13:52danlarkinmtm: gah! I get that sometimes too!
13:52stuartsierratomoj: clojure.test prints stack traces for exceptions, is that what you mean?
13:53tomojno, I mean like how rspec stops running a test on the first failure in that test
13:53tomojcertain failures for me mean that the test can't continue
13:54stuartsierratomoj: It doesn't stop on failure. I debated whether or not to do that. But the other tests will just fail, wont they?
13:54tomojwell they will blow up with exceptions currently
13:54stuartsierrayse
13:54stuartsierra*yes
13:55stuartsierraSo no, there's no built-in way to stop the test function prematurely.
13:56tomojI guess I can just throw a meaningful exception instead of doing a test there
13:56stuartsierraYou could write something like (deftest ... (when (is foo) (is bar) ...))
13:56tomojah, yeah, that'll work, thanks
13:56stuartsierra(is...) always returns the result of the assertion expression.
14:00the-kennylisppaste8: url
14:00lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
14:02hiredmanarbitrary functional destructuring <-- wow
14:02lisppaste8the-kenny pasted "untitled" at http://paste.lisp.org/display/90595
14:03hiredmanbinding is dynamic scope
14:03KirinDaveYeah
14:03KirinDaveDynamic scope is not lexical scope.
14:03the-kennyhm.. a bit annoying.
14:03KirinDaveUh, no
14:04KirinDaveWhat you want, sir, is to use a lexical scoping construct. :)
14:04hiredmandynamic scope is resolved at function call time, not function definition time
14:04KirinDaveYou can visualise it as something that rides along in the call stack.
14:05cemerickchouser: the examples in #211 confuse me, FWIW.
14:05the-kennyhm.. ok. I thought something like this was possible.
14:05KirinDavethe-kenny: It is.
14:05hiredmanbut don't do it
14:06the-kennyheh ok :D
14:06hiredmanjust pass an argument
14:06KirinDaveOr swap bindings for let
14:06KirinDaveWhich is the lexical scoping construct. Consider what you're doing carefully though.
14:07KirinDaveBecause you're defining ONE instance at definition time.
14:07the-kennyhiredman: clojure-couchdb is a library
14:07hiredmansure
14:07KirinDavethe-kenny: So you'd expect to say (bindings [*server* "server-url"] (foo))
14:08KirinDavethe-kenny: In other words, you tend to set bindings at runtime at the upper level of your call tree.
14:08hiredmanthe first thing I do with libraries that use dynamic scope is wrap them in functions that take arguments
14:08the-kennyKirinDave: That's what I'm doing now. I was a bit confused about the defn-thing
14:09KirinDavethe-kenny: Yeah. Just remember the idea that dynamic scope is a rider in the call stack
14:12jasapphiredman: did you ever use clsql for common lisp?
14:26chousercemerick: do you think that particular syntax is confusing, or the whole idea of arbitrary code allowed in destructuring? Or are they just poor examples?
14:27KirinDaveWow, clojure.http.resourcefully is a really nice idea.
14:28KirinDavekotarak: It's just pattern matching. You haven't seen it out of control until you've worked in Prolog. ;)
14:28cemerickchouser: all of the above?
14:29cemerickI'm just not clear what pain is being relieved.
14:29cemerickfor the sample examples there, or anything like it, I generally prefer (let [a (foo) a (other-foo a)] a), just to keep things clear.
14:29kotarakcemerick: most likely a shortened let, which I don't particular feel as pain. You get a more unreadable destructuring for return.
14:30kotarakcemerick: exactly
14:31cemerickwell, if I remember fogus_'s question from before that prompted this, it wasn't so much trying to destructure in a different way than it was trying to get function application into binding forms for their own sake.
14:31cemerickalthough, I'm probably not being charitable there.
14:31cemerick...which brings me back to, when would anyone use this, why, and what is the gain?
14:35cemerickchouser: yeah, looking at those examples again, I'm just not at all clear as to what's going on. i.e. (-> str b) is apparently *binding* b, not applying a fn 'b', which is confusing as hell.
14:42rhickeycemerick: are let of vectors and maps confusing in that they don't create vectors and maps? probably at first
14:44rhickeyobviously destructuring is sugar, as we can get at the components using fns
14:48stuartsierraI've only been vaguely following this discussion, but it looks confusing as hell.
14:48cemerickrhickey: [] and {} are known sugar -- start messing around with function application, and I think things go bad quickly.
14:49cemerickIt's not even so much a matter of it being confusing, the proposed change means that one needs to *read* binding-forms, whereas they're nicely scannable right now.
14:51rhickeycemerick: I don't see how this affects scanning (let [[a b] c d [e f]]...) 0 there's no automatic balancing op
14:52rhickeymust distinguish unfamiliar from confusing
14:52cemerickrhickey: I was saying that the proposal in #211 affects scanning, not existing destructuring forms (which are super-readable/scanable, IMO)
14:52rhickeypeople argue against Lisp because it is 'confusing'
14:53rhickeycemerick: becasue you have to look at the end of (-> ...) for the bindings?
14:53cemerickrhickey: because you need to interpret the ... in order to have any clue as to what the bound value is
14:53rhickeyny example above just to show it's not clear which are the bindings without some manual grouping
14:54rhickeycemerick: you would also if it was on the right hand side
14:55cemerickrhickey: granted, but I currently don't have to do any reading/interpreting to answer "what are the bindings available in this scope", or "where is foo bound", etc.
14:56rhickeycemerick: that, I think, is a familiarity thing, once you understand (-> ends in bindings)
14:56rhickeyI agree at the top level it is superfluous and should be discouraged
14:57cemerickheh, only in binding forms, but (-> foo bar) applies bar to foo everywhere else
14:57rhickeycemerick: but it does apply the destructuring bind of bar to foo
14:57rhickeycemerick: vectors and maps do different things in binding forms than elsewhere also
14:58cemerickoh, my, now I just grokked the third example in #211
14:59cemerickrhickey: so, when *would* this be used? I still haven't seen any compelling example where this is beneficial.
15:01slyrus_does stefan kamphausen hang out here?
15:01kotarakcemerick: still the only use case I can think of is cutting down on lets: (let [[a (-> str b) c] x] (list a b c)) vs. (let [[a b c ] x b (str b)] (list a b c))....
15:02cemerickkotarak: and I'd prefer the latter anyway, for clarity's sake
15:02kotarakcemerick: me too. :)
15:03cemerickI'm no minimalist, but complexity has to carry some commensurate power.
15:07kotarakfor is a good example: (for [x abc :let [y (do-something x)] z fgh :when y w asd :while y] ...) packs a lot in the punch. (for [:let [foo bar] ...] ...) just for the sake of saving one surrounding let.... questionable.
15:10rhickeycemerick: I agree, and we'll have to see if it holds muster. My gut says it will have utility in those cases where you might not have direct access to the thing being destructured or the subsequent expansion, i.e. when binding forms flow through macros
15:10spuzcgrand: nice post today. I wonder, why does unrolling a function call get you such large performance gains? What did the original version of the code look like?
15:11cemerickrhickey: any example off the top of your head, what the workarounds were?
15:13rhickeywell, for before it had let :)
15:14rhickeythe workaround was adding let to for, would we have needed that?
15:14rhickey:let
15:14chouser:let is still a bit clumsy, what with the extra [] in there...
15:15rhickeythat :let now seems like a special case workaround for exactly this, serving only one macro
15:17rhickeyit's an example of where bindings are flowing along and you haven't access intermediately
15:17rhickeyto install another let
15:17chouser'let' is actually often the least compelling example for any sort of destructuring. for, doseq, and fn better
15:17kotarakrhickey:Well, it is only a problem in for, no? Not in let, fns, .... The only improvement there is (maybe) that you can do (let [[a (-> str b) (-> (foo b) c)] bla] ...). In which way is that better or worse than (let [[a b c] bla b (str b) c (foo c b)] ....)
15:18rhickeykotarak: for and doseq, and anything like them...
15:19rhickeyalso a very compelling macro target, again, where you don't control the expanded-into scope
15:20rhickeyyou need to perform a transformation but emit a single clause
15:22nathanmarzhey guys... if i have two lazy seqs, say something like (1 2 3 4 5 ...) and (0 1 2 3 4 ...), is there an easy way to "merge" them and produce something like ([1 0] [2 1] [3 2] [4 3] [5 4]...)?
15:22cemerickrhickey: if this *does* run the gauntlet, perhaps we can avoid -> at the very least. Having its last argument be a binding instead of the last function to be applied is perhaps the most grating issue, IMO.
15:22kotaraknathanmarz: (map vector seq1 seq2)
15:24rhickeycemerick: I disagree strongly, this is a binding form slot, where the fundamental 'function' is destructuring.
15:24chouser(let [(a str) 1] a) ==> "1" is perhaps more consistent, but definitely worse
15:24nathanmarzthank you
15:25rhickeyreading (-> foo bar [a b c]) says to me - flow the destructuree through foo and bar before breaking up into a b c
15:26rhickeyonce we've taught the editors and IDEs to do local var coloring it will become clear :)
15:27kotarakBtw: is let in for really only a short-hand for a vector? (for [x [1 2 3] y [(str x)]] ...) vs (for [x [1 2 3] :let [y (str x)]] ...)?
15:27rhickeycemerick: so you'd just take parens off the table for any syntax?
15:27rhickeyone of 3 grouping constructs?
15:28rhickeyused here for function application during destructuring?
15:28cemerickrhickey: barring compelling use-cases, yes
15:28cemerickof course, compelling is relative
15:29cemerickIMO, destructuring is *structural*, thus the name. "function application during destructuring" is an oxymoron for me at the moment.
15:29rhickeywhat about :let in for, a plain workaround, the need for which will come up again?
15:31cemericknever having used :let in for. I tend to just use a nested let.
15:31rhickeyyou must have never needed the transformed value later in the for header
15:32kotarakrhickey: and even the workaround ([..]) is not impossible if really necessary
15:32rhickeykotarak: that is not a workaround
15:32kotarakrhickey: why not?
15:34cemerickrhickey: yeah, I rarely have more than 4 lines in a for, et al. -- a couple of seqs + a :when or :while.
15:34lisppaste8Chouser pasted "example of -> destructuring" at http://paste.lisp.org/display/90605
15:35rhickeykotarak: doesn't do the same job
15:36chouserI appreciate, for example, avoiding the tortured name mime-exts
15:37Chousukehmm, that looks pretty neat.
15:37cemerickchouser: you mean (let [a (foo) a-str (str a)] ...)?
15:38Chousukeit might be a bit confusing initially though, given that -> and ->> are also macros
15:39cemerickChousuke: no, don't you see, this will bring the locusts down from up on high!!!! :-P
15:40chouserbut these aren't coincidentally named -> and ->> -- they're used outright in the implementation.
15:40Chousukechouser: yeah, i noticed. clever :P
15:40chouserthey mean the same, just a bit different context.
15:41rhickeyfor's :let is a perfect example of the gut case I made before, and a categoric one - should every construct that flows bindings provide a similar 'gap' to allow executable code to run?
15:41Chousukecemerick: the way I see it, this just allows you to specify your own destructuring operations
15:41rhickeythen think about a macro targeting for
15:41rhickeythat needed to emit an inner :let
15:41rhickeyaargh
15:42Chousukesplitting the string to mime-exts is just a part of the destructuring
15:42lpetitIn the clojure syntax, does/can : (colon) prefix other things than keywords ?
15:42rhickeylpetit: no
15:43lpetitThat is, if I want to do syntax coloring right for keywords even if just : (colon) is typed by the user, is it ok to consider it a keyword (or at least the start of a keyword) ?
15:43Chousuke,(keyword? (symbol ":foo")); I think you can cheat though
15:43clojurebotfalse
15:43Chousukebut that's not supported :)
15:43lpetitI'm interested in literal keywords, btw :)
15:43Chousukehmm
15:43Chousuke,:
15:43clojurebotInvalid token: :
15:44cemerickChousuke: yeah, I understand the mechanics. I just know that I'm confused looking at these things. Readability and consistency is a big deal for me, and I think this impacts both negatively.
15:44lpetitBut how would you like your preferred editor to react :when you have just typed : (colon), do you want it to already apply the syntax coloration for keywords, or do you want it to apply no coloration since it's not yet a valid keyword
15:44lpetit ?
15:45cemerickClearly, I'm not the intended audience, but I'm not looking forward to reading this in other people's code.
15:45rhickeycemerick: I don't know why it should occur in handwritten code any more often than :let in for
15:45rhickeybut given this, we could eliminate :let in for and the need for any similar construct in any similar macro forever
15:46lpetitcemerick: this is a good functionality AFAIC, since it will allow me write a "warning problem marker" in eclipse if people abuse it in simple cases :-p
15:46cemericklpetit: lol
15:47cemerickrhickey: we'll have to find out, of course. :let in for is a very niche widget, though -- this will be available in every binding-form everywhere.
15:48lpetitJoke apart, I think if the mechanism is totally orthogonal (and it seems to be the case), then it's worth having it
15:48lpetitBut he, time will tell :)
15:49Chousukecemerick: do you have any suggestions for a better syntax?
15:49lpetitSo you did not answer my oh so more important question about the special case of handling single : (colon) syntax coloring in clojure editors ?
15:49Chousukelpetit: can you have a delay in the colouring?
15:50cemerickChousuke: nope, I'm just lobbing stones. I can definitely see the utility for macro writers, but I think it's simply not appropriate in user-land, so to speak.
15:50Chousukelpetit: a single : is an error but you shouldn't flag it so immediately
15:50lpetitChousuke: tell what you have in mind :)
15:50Chousukelpetit: mostly because it's very likely to be followed soon by other characters that make it legal.
15:50lpetitChousuke: cute, but no, not such sophistication for the moment (but I like it)
15:51lpetitChousuke: we may well end up with this later, indeed : a quick syntax coloring, and when the user pauses for a long time, a more in depth syntax coloring, yes.
15:51ziga`write an editor for clojure in clojure or better - an IDE with debugger and all
15:51lpetitChousuke: so ok you convinced me to do nothing for the moment :)
15:52lpetitziga`: huh ?
15:52ziga`just kidding
15:52Chousukefor now it's more cost-effective to build upon existing IDEs anyway
15:53Chousukethough there is a Clojure editor I think. Was it called Waterfront or something?
15:53lpetitziga`: there is room for anybody's contributions anyway, the door is not closed :)
15:57cemerickchouser: I'd suggest that if #211 is going in, we should add arbitrary fn application to map destructuring as well, if it's doable.
15:58cemericke.g. (let [{ival .intValue} 5.0] ival) or (let [{ival (-> :a .intValue)} {:a 5.0}] ival), etc.
15:58chouserit's there.
15:58chouserer
15:59kotarak(defn p [string] (for [mime-exts (.split string ",") [mime exts] [(.split mime-exts ";")]] [(keyword mime) exts])), still not sure why I need :let in for besides it being sugar.
16:00chousercemerick: (let [{(-> int ival) :a} {:a 5.0}] ival) ==> 5
16:02cemerickchouser: ok -- I was trying to wiggle the host invocations in there. I've actually always thought being able to specify .getFoo in map destructuring would be super-useful, especially in :keys.
16:02chouseryou can use .intValue in place of int there
16:03cemerickyeah, I'm talking about more straightforward usage like {a .getFoo b .getBar}, etc.
16:07spuzmsg lpetit Hey
16:07spuzshit
16:07hiredmanhah!
16:07hiredmanI knew it!
16:08lpetitmsg spuz Ho
16:08lpetitre -shit :-p
16:08spuzhiredman: that I'm retarded? I'm surprised you hadn't realised :p
16:09hiredmanclojurebot: I knew it! is <reply>You know nothing!
16:09clojurebotAck. Ack.
16:44michaeljaakaclojurebot: how are you?
16:44clojurebotwith style and grace
16:45michaeljaakaclojurebot: what is the meaning of life?
16:45clojurebotwhat is wrong with you
16:45mabesit should answer with 42
16:45KirinDaveNo
16:46KirinDavemabes: Pretty sure it answered your question correctly.
16:48mabesKirinDave: you mean michaeljaaka's question?
16:48KirinDaveWell, yes.
16:48hiredmanKirinDave: very philosophic
16:48KirinDaveIt answered the question correctly.
16:57spuzthe meaning of life is what's wrong with me?
17:03georgeclojurebot: Am i handsome ?
17:03clojurebotIt's greek to me.
17:04georgeclojurebot: what is your name ?
17:04clojurebotWhat is meta
17:04nathanmarzis there any sort of clojure function that acts like reduce but outputs all the intermediate values?
17:04fanaticoIf AI has taught us anything, the correct response to "what is the meaning of life?" is "why do you say what is the meaning of life?".
17:05nathanmarzby output i mean returns a lazy seq to the intermediate vals
17:05chousernathanmarz: clojure.contrib.seq-utils/reductions
17:05georgeor should answer it with a philosofical meta referrence ... "the meaning is to find a meaning"
17:06nathanmarzchouser: thanks, nice and simple like usual
17:06hiredmanclojurebot: why?
17:06clojurebothttp://clojure.org/rationale
17:07georgeanyone knows how is the market for clojure ... i mean , for find a job ...
17:07chousergeorge: get a Java job. Then sneak Clojure in the back door.
17:08chouserif that doesn't work, get another Java job -- there are plenty to choose from. :-)
17:08ohpauleezIn Philadelphia, there are currently two companies actively using clojure that I know of
17:08ohpauleezI'm pushing a third company to adopt it
17:09georgechouser: Can i put java code in clojure as i was writing java code ?
17:10chousergeorge: not (usefully) in the same text file, but things defined in clojure and things defined in java can interact quite easily.
17:11ohpauleezgeorge: and someone has created jsr233 bindings for clojure too
17:11georgechouser: so i would have to start learning java ...=/ . It probably would be hard , after having fun with scheme ...
17:12lpetitgeorge: maybe TeachScheme -> Reach Java may help : http://www.teach-scheme.org/
17:21georgelpetit: cool ... how do i get "How to Design Class Hierarchies"
17:23KjellskiWhat is the algorithm used to coordinate things in a transaction on refs?
17:25ChousukeKjellski: As far as I know it's multiversion concurrency control but I don't know the details of the algorithm at all :P
17:25_atoKjellski: http://clojure.org/refs
17:25_ato"The Clojure STM uses multiversion concurrency control with adaptive history queues for snapshot isolation, and provides a distinct commute operation.
17:26_atothat means little to me, but it's enough to google some papers on :)
17:26KjellskiThanks a lot... and sorry for not digging clojure.org first...
17:33hiredmanhttp://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.105.3507&amp;rep=rep1&amp;type=url&amp;i=0 <-- rhickey mentioned this paper on stm a while back
17:34hiredmananyway, http://delicious.com/clojurebot/rhickey
17:34Kjellskihiredman : thanks... I´ll save that one too
18:02spuzare there any articles that describe how Clojure implements lazy sequences?
18:06spuzWhen debugging a clojure application, it's pretty mind-bending to look at the call tree that is generated
18:07Kjellski,(doc .
18:07clojurebotEOF while reading
18:07Kjellski,(doc .)
18:07clojurebotGabh mo leithscéal?
18:07Kjellski,(doc ..
18:07clojurebotEOF while reading
18:08Kjellski,(doc clojure.core/.)
18:08clojurebotHuh?
18:08Kjellski,(doc clojure.core/..)
18:08clojurebot"([x form] [x form & more]); form => fieldName-symbol or (instanceMethodName-symbol args*) Expands into a member access (.) of the first member on the first argument, followed by the next member on the result, etc. For instance: (.. System (getProperties) (get \"os.name\")) expands to: (. (. System (getProperties)) (get \"os.name\")) but is easier to write, read, and understand."
18:08hiredman. is a special form, so there is no var for a docstring to hang on
18:09hiredmanthe clojure doc stuff has special handling for special forms, clojurebot's doc does not
18:09Kjellskihiredman : Your bot is not recognizing when closing parens aren´t out there... I´ve figured that from the sources...
18:09hiredmanKjellski: what?
18:09Kjellski,(doc clojure.core/..
18:09clojurebotEOF while reading
18:09Kjellski,(doc clojure.core/..)
18:09clojurebot"([x form] [x form & more]); form => fieldName-symbol or (instanceMethodName-symbol args*) Expands into a member access (.) of the first member on the first argument, followed by the next member on the result, etc. For instance: (.. System (getProperties) (get \"os.name\")) expands to: (. (. System (getProperties)) (get \"os.name\")) but is easier to write, read, and understand."
18:09hiredmanand?
18:09Kjellski,(doc apply
18:09clojurebotEOF while reading
18:10Kjellski,(doc apply)
18:10clojurebot"([f args* argseq]); Applies fn f to the argument list formed by prepending args to argseq."
18:10licoressejaha?
18:10Kjellskihiredman : huh? Sorry... thought that was somewhat different the last time I´ve tried that .....
18:17Kjellskihiredman: the clojurebot accepts xxx-lookup? functions without closing parens? But gives EOF while reading?
18:17hiredmanwhat?
18:18Kjellskihiredman : Is the "EOF while reading" from the clojurebot his indication of missing parens?
18:20ChousukeKjellski: it's Clojure's indication of a missing closing paren :)
18:20Chousuketry (read-string "(+ 1 2") in a repl
18:21KjellskiChousuke : aha! so, nevermind hiredman ... ^^
18:23KjellskiWhatever, sleep well... =) cya
18:24spuzhow can I tell whether a given function returns a lazy sequence or not?
18:25spuzsay, for example, vec
18:25hiredmanwell
18:25hiredmanvec returns a vector
18:25hiredmanvectors are not sequences
18:25hiredmanso a vector cannot be a lazy sequence
18:25spuzI see your point
18:25spuzwhat about say, rest
18:26spuz,(class (range 10))
18:26hiredmanrest returns a sequence
18:26clojurebotclojure.lang.LazySeq
18:26spuz,(class (rest (range 10)))
18:26clojurebotclojure.lang.ChunkedCons
18:26spuzWhat is a ChunkedCons...?
18:27hiredmanspuz: why does it matter?
18:27hiredmanyou can call first and rest on it
18:28hiredmanwhat else do you need?
18:28spuzhiredman: I want to know whether a function will evaluate the entire sequence that I pass to it
18:28KirinDave1technomancy: Hey, is there more detailed docs on how to use leiningen?
18:29hiredmanspuz: then read the docs
18:29spuzhiredman: for example, vec will evaluate all the elements of a sequence passed to it, but it doesn't tell me that in the docs
18:29KirinDave1technomancy: Things like manipulating the classpath, etc. I'd like to use it and your clojure-http-client stuff, but figuring out the right way to go about doing that is kinda opaque to me.
18:30hiredmanspuz: it should be obvious
18:30hiredmanvectors are not lazy
18:30hiredmanvec returns a vector
18:30spuzyes, but in general, is there a way to find out empirically?
18:31hiredmanwhy?
18:31technomancyKirinDave1: docs are slim unfortunately. right now it works best with dependencies that are already published to a public repository, which clojure-http-client is not.
18:31KirinDave1technomancy: What's the "right way™" to use something like clojure-http-client?
18:31KirinDave1technomancy: Just roll it into src/ for now?
18:32Chousukespuz: try the function on a seq that has side-effects.
18:32technomancyKirinDave1: yes, but I hope to have a better solution in a matter of days.
18:32technomancyyou just caught me at an awkward time. =)
18:32KirinDave1technomancy: well I think it's an awesome library
18:32technomancyI know _ato is working on a public repo service that should make this easier too.
18:32technomancythanks
18:32KirinDave1technomancy: Too bad github doesn't support it directly.
18:32KirinDave1technomancy: Is there an easy way to modify the invocation classpath?
18:33hiredman~latex \text{vec returns a vector}\\\text{vectors are not sequences}\\\text{since vec returns a vector, and vectors are not sequences, than vec cannot return a type (lazy) of sequence}\\QED
18:33technomancyKirinDave1: the clean way to do it would be jar it and put it in lib
18:33technomancybut that involves installing the clojure-pom project too, which is a hassle right now.
18:33spuzChousuke: ok, but how do I evaluate the function? I can't type it at the repl as printing automatically evaluates a lazy sequence
18:33technomancyunfortunately the centralized maven repos are very slow-moving nad hard to get stuff into.
18:33hiredmanundoubtly a misuse of qed
18:34KirinDave1technomancy: Not to mention that lein seems to disagree with the maven repo about somethign that should be there.
18:34technomancyKirinDave1: how's that?
18:34spuzheh, does anyone use QED correctly?
18:34KirinDave1technomancy: As lein deps on the sample repo currently fails for me
18:34Chousukespuz: you can just try (do (f someseq) nil)
18:34spuzChousuke: ok
18:35technomancyKirinDave1: there was a typo in the maven source repo URL, wipe your ~/.leiningen.jar and do a self-install again
18:35Chousukespuz: but in general, most functions operating on seqs will be lazy
18:35KirinDave1technomancy: Ah
18:35Chousukespuz: vec produces a vector so it can't be lazy. :)
18:35spuzChousuke: as hiredman has proved :)
18:38KirinDave1technomancy: Well, okay. So… what's the way that I am to modify the classpath to include your code for tasks such as repl?
18:38KirinDave1technomancy: If I have a submodule with clojure-http-client?
18:39technomancyKirinDave1: actually hang on; I might have this available in a public repo now that I think about it
18:41technomancyKirinDave1: I set this up a while ago and had forgotten about it: http://p.hagelb.org/project.clj.html
18:41technomancybut it should work
18:42KirinDave1rad.
18:43KirinDave1technomancy: That's awesome.
18:43KirinDave1technomancy: I am curious tho, how you might go about doing things like extending the classpath or other salient environment settings for the default tasks. Seems like it could be important.
18:44technomancyKirinDave1: I'm of the opinion that the less the classpath varies on a per-project basis the better
18:44KirinDave1technomancy: So, if it's not a public repo somewhere leiningen doesn't make it easy to use it?
18:44technomancysince any changes must be reflected in your build tool as well as Emacs or any other IDE contributors use
18:45technomancyKirinDave1: if it's not a jar, it's going to be more complicated.
18:45KirinDave1For clj files it doesn't seem like it would be.
18:45KirinDave1as long as you have the relative directory structures, I suppose.
18:46technomancyyou can jar up clj files; that works fine. doesn't have to be AOT-compiled.
18:47KirinDave1Okay, so let's say it is a jar?
18:47technomancyif it's a jar, you toss it in lib/
18:47KirinDave1You'd lob it in deps then?
18:47KirinDave1Err lib, sorry
18:47technomancyit's a pretty standard convention that all jars in lib get globbed onto the classpath
18:47technomancyso all the IDEs etc. support it.
18:47KirinDave1I can see that.
18:48technomancymuch of this depends on it becoming easier to publish to a public repo in the future
18:48technomancywhich I hope to help tackle once lein is somewhat stable and documented.
18:49KirinDave1It'd be nice if github supported us the way that they do rubygems. :)
18:49technomancyit would... but considering they're moving gems off github it seems unlikely.
18:49technomancybut you know those guys, right? maybe you can talk them into it. =)
18:50KirinDave1Unlikely.
18:50KirinDave1But I could mention it.
18:50KirinDave1I see Tom a lot less because of his jet-setting successful-startup lifestyle. :)
18:50_atoKirinDave1: I'm have a go it: http://clojars.org/
18:51KirinDave1_ato: That's awesome.
18:52_atoI'm going to get search working today and then release this afternoon or tomorrow
18:52KirinDave1Wow, on the cusp!
18:52technomancy_ato: I'll race you to release. =)
18:52_atobwaha
18:53technomancywait, this afternoon? never mind.
18:53_atotechnomancy: you decided to do a repo as well?
18:53technomancy_ato: that's old stuff from when I was using clojure-pom with maven
18:56_atotechnomancy: you don't mind if I say Leiningen is the preferred way of using it right? (ie Leiningen is usable enough already)
18:56technomancy_ato: it's useful today if ill-documented.
18:57technomancythe main bummer is that mvn must be installed to install your project locally since that part still shells out =\
18:57technomancybut the primary blocker to release is documentation
18:58_atoah, ok.
18:59_atoI'll probably write up a tutorial for clojars.org that covers the basics of Leiningen as well
18:59technomancyend-user type projects generally won't need to install anyway; it's only an issue for library developers
18:59technomancy_ato: be sure to check with me before you do that; I may have something by then
19:00_atook
19:02piccolin1Are you going to make leiningen eventually not use Maven?
19:04technomancypiccolino: it will not need maven installed, but it will bundle some parts of maven with it internally. but you shouldn't have to worry about that.
19:04piccolinoAh, cool.
19:05piccolinoAre you going to keep it in ~/.leiningen.jar?
19:06technomancypiccolino: it'll probably go in ~/.m2/repository... haven't decided about that yet.
19:06piccolino'k
19:07technomancyif you feel strongly, speak up. =)
19:07piccolinoOh, I don't have strong feelings about where it should be, other than that a hidden jar in the user's home directory feels wrong.
19:07_atotechnomancy: oh yeah, that reminds me. how about a per-user config-file for leiningen, which you could add plugins (like swank or whatever) to so that you can use them without have to configure on a per-project basis?
19:07technomancy_ato: it will come with time, I'm sure
19:08technomancybut I'm not going to code it myself until I need it personally.
19:08_atookay, no worries
19:16annealerhmm
19:17annealerso i just noticed scrollback involving clojars / leiningen
19:17annealerthought i'd throw out that... https://www.javagems.org/
19:17annealeri'm on a similar endeavour, because maven is infuriating
19:17gravityIs there a standard place that people stick jars for their classpath?
19:17annealerit'd sure be nice if we could all work together on somethin'
19:18_atoannealer: ah interesting
19:18gravityNot having the equivalent of /usr/share/lib is weird to me
19:18annealergravity: javagems installs to ~/.javagem/java by default
19:18piccolinoDude, I already failed on "READY"
19:18annealer(psa javagem is nowhere near production ready yet which is why i havent really publicised it)
19:19gravityheh, ok thanks :-)
19:21annealerpiccolino: i can't tell if that was general smartassery or a slam against ruby or both!
19:21notallamacan anyone explain why this doesn't work? (protocols) http://paste.lisp.org/display/90628
19:21piccolinoWell, neither. I tried the READY command, and it gave me an error.
19:21piccolino"could not find gem javagems locally or in a repository"
19:21technomancyannealer: would love to talk, but I can't until I get off work later today. efforts should definitely be coordinated.
19:21annealerpiccolino: do you have gemcutter installed? some time tonight, gemcutter will become the official rubygems repo. like, 10pm tonight
19:22annealertechnomancy: awesome. my email is gabriel.gironda@gmail.com, i'm gabrielg on github. we should coordinate
19:22annealerpiccolino: until then, you need to "gem install gemcutter && gem tumble"
19:22piccolinoAh, no I do not, apparently.
19:22piccolinoI've never used gem
19:22annealeri figured i'd leave that part out since.... it's an official change in a few hours anyway
19:23piccolinoFirst I gotta upgrade my gem install, I guess.
19:24annealer_ato: as an example, something like this: http://gist.github.com/237420 works already
19:25piccolinoHey, I'm in Chicago too.
19:25annealeri'll be adding "javagem exec" tonight
19:25annealerpiccolino: neat. we should get a beer some time
19:25piccolinoCool.
19:29_atoannealer: custom_require.rb:31:in `gem_original_require': no such file to load -- net/https (LoadError)
19:29_atoam I missing a ruby lib?
19:29_atoor wait.. do I need to run it with jruby?
19:30Anniepoothis is sweet
19:30_atoah that looks like it
19:32_atolooks like it also doesn't compile clojure
19:32_atobut I get the idae
19:32_atocool
19:32_atowhat I like is that you can use it with C ruby so it has fast startup times
19:35_atoannealer: I thought about using gemcutter, but it seems important to be able to use maven-style repositories so you can use java libs without having to repackage anything
19:35_atoalthough I guess there's probably an easy way to convert maven stuff to gems
19:52timothypratley1http://www.wakaleo.com/blog/237-more-groovy-magic-with-maven-pom-files <<< looks promising too :)
20:48sh10151has anyone done anything to set up the slime repl's classpath from one that maven sets up?
20:49danlarkinsh10151: M-x swank-clojure-project
20:49danlarkin:)
20:50sh10151hey, thanks
20:50sh10151seems like something's broken with the prompt though
20:50sh10151it prompts for a classpath
20:50sh10151I hit ret to accept the default
20:50sh10151newline appears in minibuffer
20:50danlarkinno it prompts for a project root
20:51sh10151yeah, sorry
20:51danlarkinAh, you have an old version of swank-clojure then
20:51danlarkincombined with not having i-do mode
20:51danlarkin(fixed bug)
20:51tomojdoes ido not come with emacs?
20:51sh10151will enabling ido work around?
20:51danlarkinif you don't want to upgrade the workaround is to call swank-clojure-mode directly:
20:52danlarkinM-x-: (swank-clojure-mode "...")
20:52danlarkinwhere ... is your project root
20:53sh10151I'll give that a shot when emacs coms back to life
20:53sh10151thanks for the pointers
20:53danlarkinit will hang forever
20:53sh10151yep, I think I have noticed this behavior in other modes too
20:54sh10151I should probably just upgrade actually
20:54danlarkini-do has a bug/annoying feature where if you call the ido directory chooser and you don't have ido-mode on then the minibuffer hangs like that
20:57sh10151hm, the clojure-update automagic seems to be confused by the git output
20:57sh10151wish I knew the first thing about git
21:11sh10151oof, blind update hurts ... M-x slime -> "Symbol's value as variable is void: package-activated-list"
21:12sh10151old clojure-mode I guess
21:18sh10151nope, still a failure
21:38sh10151Well, M-x slime is working but M-x swank-clojure-project says clojure/main class not found
21:40_atosh10151: you've got clojure.jar in yourprojectdir/lib right?
21:42sh10151was hoping it'd get it from pom
21:42sh10151but looking at the implementation that appears not to be the case
21:42_atoI don't think swank-clojure reads the pom
21:43sh10151nope, just makes assumptions based on its existence
21:43_atoI think mvn dependency:copy-dependencies or some such should copy over the libs in the pom
21:45sh10151yep, it did
21:46sh10151is clojure/main right for clojure-1.0.0 ?
21:48_atonot sure.. the earliest jar I've got handy is 1.0.1-alpha.. it works in that
21:49sh10151I think it's probably still ok and I still don't have the right classpath somehow
21:50sh10151gonna debug swank-clojure-project to see
21:52sh10151it has target/dependency in its list of directories
21:52sh10151but it doesn't walk it for jars
21:52sh10151bug or user error?
21:53_atocould be a bug, not sure I haven't tried it with a maven project
21:53_atohow about just symlinking target/dependency to lib/
21:54sh10151will try
21:54sh10151every time
21:54sh10151I have to do man ls to look at argument order
21:54annealer_ato: i considered the repackaging thing, and honestly, i think i'm ok with it, as long as we can automate it. which i bet we can
21:54annealerit seems almost trivial to turn a jar into a gem
21:54sh10151sorry, "man ln"
21:55_atoln -s target/dependency lib
21:55sh10151yep
21:55sh10151that worked, so I'm going to call it an oversight in swank-clojure-project
21:56sh10151target/dependency is in a list of other dirs containing .class files
21:56sh10151but it should be treated like lib
21:56_atoyeah, it's likely. I don't think technomancy uses maven for clojure stuff much
21:56sh10151wish I didn't :-P
21:57sh10151though really for the crazy long classpaths people are installing at work, it helps a little I guess
21:57sh10151Mule imports the world basically
21:58_atosh10151: have you tried leiningen? http://github.com/technomancy/leiningen
21:58sh10151now that is a witty name
21:59sh10151haven't tried it, but I will bookmark it in case I convince more people to ditch Groovy for Clojure
21:59sh10151already have been working over a few people :-D
22:00_ato:D
23:15technomancyoh, did I miss him? dang.