#clojure logs

2010-09-13

00:00sproustSee what happens is that I'm using this: (if (seq coll) ... ) Doesn't look like the rest, doesn't look like a predicate. It would be better IMHO write (if (not-empty? coll) ...
00:01sproust(I know, I can cook my own... but then it's not idiomatic clojure anymore, as per the docs.)
00:02wwmorganwell, it's not just seq that you would use in that position, but any function that could potentially return nil
00:02wwmorganrather than false, for example
00:03sproust,(map boolean [nil false])
00:03clojurebot(false false)
00:06anonymouse89sproust: is (if (not (empty? coll))... not idiomatic?
00:06sproustwwmorgan: not sure I'm being clear-- I understand I could put any other function there; what I take issue with is the fact that the idiomatic/recommended way to check that a collection isn't empty (a very common task) isn't a predicate (e.g. "something?").
00:06sproust,(doc empty?)
00:06clojurebot"([coll]); Returns true if coll has no items - same as (not (seq coll)). Please use the idiom (seq x) rather than (not (empty? x))"
00:07anonymouse89ah
00:07sproustYup.
00:07ZhivagoApparantly someone thinks that the empty sequence is not a sequence.
00:09anonymouse89next time I'll scroll back some
00:09wwmorgansproust: I think I get it. If it makes you feel any better, the macros and and or are in the same boat
00:09sproustZhivago: so in your mind's eye you're thinking: "I have to get the ISeq using (seq) because the sequence might be empty (and that's a boolean true) but I know that the ISeq will eval to false if it's empty." ?
00:09clojurebot@ splices in a seq and foo# is a symbol, not a seq
00:11wwmorgansproust: aha! I got a good example, I think
00:11wwmorgan,(if (filter #(< 0 %) (range)) 0 1)
00:11clojurebot0
00:12sproust,(range)
00:12clojurebotExecution Timed Out
00:13wwmorgan(range) is the same thing as (iterate inc 0)
00:13sproustwwmorgan: great example.
00:14wwmorgana major use case for seq is forcing a lazy collection. You use seq to ask, is there a collection here, or not?
00:17sproustI see. I understand your way of thinking.
00:19wwmorganfwiw, I used (not (empty? ...)) for a while before changing my style
00:21sproustWell, I still think it's slightly twisted. But I guess (defn not-empty? [coll] (seq coll)) will put me to rest.
00:22sproustI'll probably give in in a week ;-)
00:22wwmorgan(def non-empty? seq) will do it too ;-)
00:22ZhivagoWouldn't empty? and then (unless (empty? ...) ...) make more sense?
00:24scottjwhen-not
00:25wwmorganZhivago: sure. But the idiomatic way would be (when (seq c) ...), for the couple reasons discussed above
00:25sproustZhivago: unless doesn't provide an else form
00:25sprousts/unless/when-not/
00:25sexpbot<sproust> Zhivago: when-not doesn't provide an else form
00:25scottjif-not
00:26johnmn3hi
00:26sproustAllright, you win.
00:26sproust(if-not (empty? coll) ... )
00:26johnmn3 trying to do a lein deps on a git clone of clojars-web. Failing to get: 1.1.0-alpha-SNAPSHOT
00:26sproustI'll buy that. [deleting not-empty?]
00:26johnmn3I tried changing the name to 1.1.0 but it is still looking for the old name
00:29scottjjohnmn3: weird. does lein clean help? you saved project.clj right? :) just "1.1.0" right?
00:29johnmn3yea, trying again with contrib as just 1.0 too
00:29scottjmaybe checkout a fork
00:30scottjyou looking to improve clojars-web or deploy a local one?
00:31johnmn3set the website up locally, so I can mess around with it, maybe help out if I can figure it out.
00:31johnmn3what should clojure-contrib be? was: [org.clojure/clojure-contrib "1.0-SNAPSHOT"]
00:32johnmn3I just tried: [org.clojure/clojure-contrib "1.0"]
00:32johnmn3with no luck
00:33johnmn3do I need to clean/purge .m2 out as well somehow?
00:33scottjhttp://github.com/kotarak/clojars-web/blob/master/project.clj
00:35johnmn3scottj, thanks, will try that
00:37johnmn3worked
00:38johnmn3now, I need to get the clojure-web/data too?
00:40scottjno clue, never setup clojars
01:06johnmn3hmm. The kotarak readme says to run: java -cp 'src:classes:lib/*' -i src/clojars/core.clj -e '(clojars.core/main)'
01:06johnmn3but java says there's no such -i option
01:06chouserhm. trying inserting clojure.main right before the -i
01:07johnmn3ah, k
01:08johnmn3wow.. I have clojars.org running locally
01:08chousernifty!
01:10johnmn3the repo isn't browsable or searchable yet, but registering just worked.
01:41sandGorgonwhy do I need to use a "alter" keyword in a "dosync". I can do changes by using deref/"@". Is there something I'm missing ?
01:42wwmorgansandGorgon: how can you make changes using deref?
01:43johnmn3when you deref, you are making a copy of that value.
01:43sandGorgonwwmorgan, lets say (def some-num (ref #{1 2 3})) . Then (dosync (alter @some-num conj 4)) or (dosync (conj @some-num 4)) is the same isnt it ?
01:43sandGorgonjohnmn3, so alter doesnt ? I thought all data-structures were immutable ?
01:44wwmorgansandGorgon: not the same thing. After executing the first form, some-num will be chaned. After executing the second, it will not
01:44johnmn3few things.. in your example, you don't need to use the @
01:44johnmn3(dosync (alter some-num conj 4))
01:45wwmorganoh yes, that too. The first form won't do what you want
01:45johnmn3(conj @some-num 4)
01:45johnmn3alter has specific semantics that only make sense relative to a dosync (inside a transaction)
01:45johnmn3transactions are a certain way to do things.
01:46johnmn3allowing syntax like (dosync (conj some-num 4)) would muddy the meaning of (conj some-num 4)
01:47johnmn3because a different kind of thing is happening with (dosync (alter some-num conj 4))
01:49SandGorgonjohnmn3, I got disconnected - would you please repeat ur message ? my last question was johnmn3, so alter doesnt ? I thought all data-structures were immutable ?
01:49johnmn3few things.. in your example, you don't need to use the @
01:49johnmn3(dosync (alter some-num conj 4))
01:49johnmn3(conj @some-num 4)
01:49johnmn3alter has specific semantics that only make sense relative to a dosync (inside a transaction)
01:49johnmn3transactions are a certain way to do things.
01:49SandGorgontrue true.. (dosync (alter @some-num conj 4)) should have been (dosync (alter some-num conj 4))
01:50johnmn3allowing syntax like (dosync (conj some-num 4)) would muddy the meaning of (conj some-num 4)
01:50johnmn3because a different kind of thing is happening with (dosync (alter some-num conj 4))
01:51johnmn3they are different forms that do different things. one operates on the identity while the other operates on the value (returning a new value)
01:52johnmn3the first returns a new value, but redirects the identity to the new value, sotospeak
01:53SandGorgonjohnmn3, ahh.. that is something that makes sense
01:53johnmn3it's confusing at first
01:54johnmn3a deref or @ pulls the current value out
01:55johnmn3so you could do something like, (dosync (alter some-num conj (inc @some-num)))
01:55SandGorgonright.. got that - I sort of lost the fact that identity needs to be redirected
03:00amalloydidn't rich post to the group about new stack trace functionality? i'm sure i saw it, but i'm totally baffled in that i can't find it anywhere
03:06chouserhttp://groups.google.com/group/clojure/browse_thread/thread/fd6cd491862bf9e5
03:06LauJensenGood morning all
03:06LauJensenchouser?!
03:06chouseramalloy: google group's search is stunningly bad
03:06chouserLauJensen: yeah, I really shouldn't be awake.
03:06LauJensenchouser: Those finger trees got you up at night now?
03:09chousernah, just a late night snack.
03:09chouserand that's consumed now, so off to bed with me.
03:09chouserhave a pleasant whatever it is!
03:11LauJensenRight back atcha
03:38LauJensenAnybody here from Austria?
03:57amalloyno, but one of my coworkers is from australia, so...let me know if you get desperate
04:03LauJensenthanks, I will
04:08AWizzArdIsn't Australia on the other side of the world?
04:08AWizzArdFrom Austria I mean.
04:08amalloyspelled similarly, though. best i could do
04:12zoldarI'm trying to alter a session but when executing "(alter session assoc :name val)" I get "clojure.lang.PersistentArrayMap cannot be cast to clojure.lang.Ref" which probably refers to session map. I have extracted session inside defroutes using map destructuring. What am I doing wrong?
04:14LauJensenamalloy: I appreciate the effort :)
04:14LauJensenzoldar: just call assoc session :name val, alter is for dosyncs/refs
04:15LauJensenMake sure you associate the modified data to the return of the handler
04:15LauJensen(assoc (response "Hi there") :name "Frank")
04:30zoldarLauJensen, sorry to bother you again but I'm not sure how to go about this when inside defroutes I'm delegating destructured data to separate functions - here's my (failed) attempt which I'm struggling with: https://bitbucket.org/zoldar/clj-smbbrowser/src/tip/src/clj-smbbrowser/core.clj
04:31LauJensenIts been a while since I've played with Compojure, but try (defroutes r (GET "/" [] (assoc (response "OK") :session {:username "Frank"}))) which should put franks username in the session. Note however, that if a single handler in your routes returns nil, the session will be deleted
04:32zoldarok I will play around with it, thanks for pointers
04:34LauJensennp - though just looking through your code, I think if this is going to turn into anything larger than what I see in that file, you would want to try Moustache/Enlive
04:36zoldarwell I wanted to try going the no-template-engine route ;) I'll see how it goes. It's my first clojure code longer than a snippet
04:37LauJensenAlright - Why did you want that?
04:39zoldarwell with that I don't have to switch between various languages (not so often at least). Besides in that case it's only me working on the code
04:39LauJensenYou mean switch between clojure and html ?
04:41zoldarwell, yes - I know it sounds stupid, but I hope for better flexibility with moving pieces around when using clojure directly for structuring documents
04:41zoldarat least when I'll get more fluent with it
04:43LauJensenI don't understand how mixing code and representation will give you more flexibility than a complete separation, can you elborate?
04:45hamzaIMHO it is much nicer to work with hiccup then html, you can still keep representation away from code.
04:46zoldarLauJensen, flexibility in terms of tools available in clojure itself when comparing to limited range of tools provided by template engine
04:46LauJensenzoldar: The template engine has its own tools, as well as all of the tools of Clojure
04:48zoldarLauJensen, well I won't argue because I'm too inexprienced at that stage, maybe you are right in the longer run. For now I ok with hiccup - using it also helps me to leverage my knowledge of the language
04:48LauJensenok
05:37fliebelmorning
05:39LauJensenmorning
05:41mbufare there any recommendations/tutorials for using clojure as backend, and Rails as a front-end?
05:42LauJensenmbuf: I suppose what you're looking for is a tutorial on using Clojure as a backend which communites via REST or some such interface, with just about anything?
05:44mbufLauJensen: yes
05:44msapplerHi is there some very good "stop using java - start using clojure" article or essay around?
05:44msapplerSo I do not have to write one myself
05:45LauJensenmsappler: cemerick wrote one called "Java is dead, you'll love it", I forgot the content though :(
05:46cemerickmsappler: http://cemerick.com/2009/10/01/java-is-dead-but-youll-learn-to-love-it/
05:46LauJensenmbuf: here's one take: http://mmcgrana.github.com/2010/08/clojure-rest-api.html
05:47LauJensencemerick: morning :)
05:47mbufLauJensen: thanks
05:47cemerickLauJensen: morning :-)
05:47LauJensencemerick: Did you see that tweet I sent your way ?
05:47cemerickI hadn't looked at twitter yet.
05:48cemerickLauJensen: Thanks :-)
05:48LauJensenok, just wondering if you see such tweets now that we're not following each other. I've had some problems with DMs on that note
05:50cemerickLauJensen: did we ever follow each other? I thought *I* was selective in who I followed, but you take it to the next level!
05:50LauJensenhaha - I don't know if you've followed me and unless you tweet less than once a week, I don't follow you
05:51msapplerHm That essay was not really what I meant ... I meant some kind of essay that can be sent to java developers that shows them the advantages they can get if they start using clojure... more like a comparison.
05:51cemerickI come and go in waves. ;-)
05:51cemerickI wish twitter profile pages showed stats: tweets/day over the last week, month, three months, etc.
05:53LauJensencemerick: Wow, you actually did a fund raiser for Raynes ? Good move
05:53cemerickyup, it was very successful
05:54LauJensenThats heart warming
05:54notsonerdysunnyhow to find the list of all vars in a given namespace in clojure
05:54LauJensenAnd it couldn't have happend to a nicer guy :)
05:54hamza,(doc ns-publics)
05:54clojurebot"([ns]); Returns a map of the public intern mappings for the namespace."
05:55hamzanotsonerdysunny: ns-publics
05:56notsonerdysunnyhamza: thanks
05:56hamzanotsonerdysunny: np
06:00notsonerdysunnyjust out of curiosity .. why map? why not just a set? what extra-info is the value part of the map giving us? wouldn't just the keys suffice?
06:03hamzavalue part is a pointer to the function
06:03hamza,(((ns-publics 'clojure.core) 'sorted-map))
06:03clojurebot{}
06:17notsonerdysunnywhat is it returning when the symbol is not a function.. for instance .. what is s which has been defined using (def s 10)
06:17notsonerdysunnywhen I do a (class <value>) it just says it is a var..
06:18notsonerdysunnyI was expecting it would say it is an integer
06:18mrBliss,(def s 10)
06:18clojurebotDENIED
06:19mrBlissWhen I do it in my REPL, (class s) returns java.lang.Integer
06:19notsonerdysunny,(def s 10)
06:19clojurebotnotsonerdysunny: Excuse me?
06:19notsonerdysunnymrBliss: you are right .. but I am refering to the value part of the map returned by (ns-publics <namespace>)
06:20notsonerdysunnycorresponding to the key "symbol s"
06:20notsonerdysunny<namespace> would be the one I executed (def s 10)
06:21mrBlissin the map you get #'user/s instead of user/s, #' is a sort of var quote
06:21notsonerdysunnyyes .. how would I find out what is the type of the object contained in #'user/s ?
06:22notsonerdysunnymind you I want to do it using the value part of the map returned...
06:23mrBlisstry var-get
06:23notsonerdysunnygotcha .. I would add a "deref" or @
06:24mrBlissis the same as var-get in this context
06:26notsonerdysunnyyea
06:42notsonerdysunnythe gen-class ed classes and definterface d classes don't seem to be visible when I do (ns-publics <namespace> ) .. is that expected?
06:47notsonerdysunnyfor instance for the file http://gist.github.com/577118
06:51fbru02guys stupid question time , what's the meaning of # in clojure? e.g. (defmacro dbg[x] `(let [x# ~x] (println '~x "=" x#) x#))
06:51fbru02?
06:51mrBlissit generates a unique symbol
06:51mrBliss,x#
06:51clojurebotjava.lang.Exception: Unable to resolve symbol: x# in this context
06:52mrBlissso it doesn't conflict with existing symbols
06:52fbru02mrBliss: thanks, so it doesn't collide with symbol named x for example??
06:53mrBlissexactly
06:53arbscht,`,x#
06:53clojurebotx__5439__auto__
06:53fbru02cool
06:54mrBlissevery x# in that macro will be the same unique symbol
06:54mrBliss,(doc gensym)
06:54clojurebot"([] [prefix-string]); Returns a new symbol with a unique name. If a prefix string is supplied, the name is prefix# where # is some unique number. If prefix is not supplied, the prefix is 'G__'."
06:56raeknotsonerdysunny: yes, I think so. the classes are not vars of a namespace
06:57raekI don't even think that the package of the generated class has to match the one of the namespace containing the gen-class
07:05notsonerdysunnyraek: you are right
07:05notsonerdysunnybut I have explicitly made sure it does match
07:06notsonerdysunnyso is there a way to get all the classes and interfaces of a package?
07:08notsonerdysunny->x#
07:08sexpbotjava.lang.Exception: Unable to resolve symbol: x# in this context
07:08notsonerdysunny->`,x#
07:08sexpbot=> x__11431__auto__
07:09notsonerdysunny->`~x#
07:09sexpbotjava.lang.Exception: Unable to resolve symbol: x# in this context
07:09notsonerdysunny->`->x#
07:09sexpbot=> ->x__11444__auto__
07:09notsonerdysunny`->x#
07:22notsonerdysunnyis there a function to list all the classes in a given package?
08:10naeuHow do I refer to an agent's current value from within itself?
08:10naeuI'm assuming that dereferencing an agent within itself is problematic
08:15naeuis there something like 'self' that you can reference in a function being executed by an agent?
08:15cemericknaeu: The current value of the agent is provided to the function you send or send-off to the agent.
08:16naeucemerick: sorry, I'm being confusing - can you also get the actual agent itself?
08:16naeui.e. so you can schedule another send?
08:17cemericknaeu: see *agent*
08:17naeucemerick: perfect, thanks :-)
08:36opqdonuthow do I solve "Can't embed object in code" ?
08:36opqdonutwhen compiling
08:41BahmanHi all!
08:42LauJensen hi Bahman
08:42LauJensenopqdonut: Find the line thats causing it
08:42opqdonutI know the object that's causing it
08:42BahmanLauJensen: Yo.
08:42opqdonutcan I somehow tell clojure how to read it?
08:45LauJensenopqdonut: I have no idea without seeing the code. I vaguely remember having had that problem myself, and solved it, but the details are lost
08:46opqdonutI understand what's happening here: clojure wants to be able to store constants into the generated class
08:46opqdonutfor some reason it uses print-dup to do this
08:46opqdonutunderstandably, it doesn't like my custom toString in one class
08:49LauJensenah ok, so implement print-dup for your class ?
08:49opqdonutok, where is this documented?
08:50opqdonutwhat signature should the method have?
08:51opqdonuthmm, public void printDup(Writer w) it seems
09:04opqdonutoh, hmm, yes
09:04opqdonutit's defmethod clojure.core/print-dup I should use
09:04opqdonutthe definition actually was there, it just wasn't getting used
09:15fliebelIs there a simple way so that my app can get command line arguments both when compiled and when run as clj file?
09:16fliebel*interpreted
09:20fliebelFor interpreted there is *command-line-args*, but for compilation I think I have to generate a class with a main function, right?
09:20raekyes
09:21raekcommand line args to a repl end up in *command-line-args*, and those to a class end up in the parameter of main
09:22fliebel:( So the best way would be to do (apply main *command-line-args*) for interpreted code?
09:22raekas of now, I think so yes... (please correct me if i'm wrong, #clojure)
09:25LauJensenI think thats right
09:51fliebel:( Cake doesn't like me… I'm trying to set up a custom task, but it gives me nothing but errors.
09:51LauJensenfliebel: Can you gist it?
09:52fliebelLauJensen: I have nothing to show, it's just that I don't know how to do it properly. It seems deftask is defined in cake.core, but I can't use or require it.
09:52arkhcan anyone tell me what I'm missing with re-matches ?
09:52arkh,(let [s "asdf"] (if (re-matches #"a" s) '(:yes) '(:no)))
09:52clojurebot(:no)
09:53LauJensenfliebel: What do you want your task to do ?
09:53fliebelLauJensen: Just to print hello for now… How is that relevant?
09:54LauJensenfliebel: Because you initialize your tasks differently, depending on whether or not they need full access to your projects vars, or just run on the outside
09:54fliebelThey need to do stuff with the rest of the project.
09:54Raynescemerick: I'll throw that info your way as soon as my eyes open to full width. :)
09:54fliebelLauJensen: It's for the static site generator, I want to use cake to do the compiling and other commands.
09:55LauJensenIn your project.clj, try adding (deftask hello [] (println "hello")) and run 'cake hello' from cli
09:55LauJensenThats the most basic use case. If that works, try (deftask hello (bake (:use something.in.your.project) [] (println "hello")))
09:56LauJensenWhich will then have access to the full project classpath
09:56LauJensenRaynes: Congrats on your trip to Clojure Conf - I was excited to read about the process!
09:56fliebelLauJensen: Why in project.clj? They told me to put it in tasks.clj
09:56clojurebotLauJensen is some dane
09:56RaynesThanks. :>
09:57raekarkh: (let [s "asdf"] (if-let [match (re-find #"a" s)] `(:yes ~match) '(:no)))
09:57LauJensenfliebel: just trying to keep it simple, now do as I say or prepare for the consequences
09:57fliebelokay
09:58LauJensenarkh: I think you're looking for re-find
09:58LauJensen,(let [s "asdf"] (re-find #"a" s))
09:58clojurebot"a"
09:58LauJensen(fliebel I was just kidding :P)
09:58fliebelLauJensen: Step 1 works :)
09:58LauJensenokay great, then Step #2 will probably also work
09:58arkhultimately I'd like to get a seq with re-groups, but I want to test for existence of a match object first
09:58LauJensenThen we can also discuss which part of the build you want your task to depend on
09:59LauJensen,(when-let [we-have-matches (re-find #"a" "asdf")] (println "matches: " we-have-matches))
09:59clojurebotmatches: a
09:59fliebelLauJensen: It says something.in.your.project does not exists (also kidding)
09:59LauJensenhaha
09:59arkhraek: thank you - why won't the 'if' at least return true on a match?
10:00LauJensenarkh: see example above
10:00raek,(re-matches #"a" "asdf")
10:00clojurebotnil
10:00arkhoh
10:00raek,(re-matches #"(a)" "asdf")
10:00clojurebotnil
10:01raekhrm
10:01raekre-find and re-seq re the only regex fns I use
10:01fliebelLauJensen: Great, also works… Now what? Just keep all tasks in project.clj? *meanwhile looks up bake*
10:01arkhLauJensen: thanks - would that work with re-groups ?
10:01LauJensenarkh: yea it works with groups
10:02raek,(re-find #"(a)(s)(d)(f)" "asdf")
10:02clojurebot["asdf" "a" "s" "d" "f"]
10:02LauJensenfliebel: I keep them in project.clj
10:03raek,(if-let [[_ a s d f] (re-find #"(a)(s)(d)(f)" "asdf")] [a s d f] :no-match)
10:03clojurebot["a" "s" "d" "f"]
10:03raekit is weird, indeed
10:03raek~re-matches
10:03clojurebotI don't understand.
10:03raek(source re-matches)
10:04raek~(source re-matches)
10:04clojurebotsource is http://github.com/hiredman/clojurebot/tree/master
10:04fliebelLauJensen: Fine with me, they'll just invoke some function and quit. But what is the bake command for? Is it like ns for tasks?
10:06fliebelLauJensen: ah: http://github.com/ninjudd/cake/blob/master/src/cake/core.clj#L156
10:07fliebelSo, Now I only need to figure out deftemplate, and I'll be on my way. Thanks LauJensen!
10:10LauJensennp :) Sorry I was afk, a danish mainstream IT media called me and wanted to talk about the release of Clojure 1.2 - Amazing the attention its getting
10:12boojumLauJensen: who?
10:12LauJensenVersion2
10:13boojumcool
10:14fliebelLauJensen: Cool :)
10:17arkhraek: LauJensen: looks like a person should usually stick with re-find and re-seq. They both take a match object, if available, and call re-groups on it. I still think it's confusing given the re- documentation but oh well.
10:17arkhnot so much fyi, more of a "I think I finally get it" ; )
10:21kjeldahlAnything similar to perl's Data::Dumper in Clojure? I'm stuck with debugging a clojure module which speaks to a java host which filters all (including stderr) output...
10:22kjeldahl(it dumps abstract data, including trees, lists etc)
10:24raeksomething like pr?
10:24raek,(pr-str {:a 1, :b 2, :c ["foo" "bar]})
10:24clojurebotEOF while reading string
10:24raek,(pr-str {:a 1, :b 2, :c ["foo" "bar"]})
10:24clojurebot"{:a 1, :b 2, :c [\"foo\" \"bar\"]}"
10:24kjeldahlExcellent, thanks!
10:38fliebelLauJensen: My deftask is still not working… I created a lovely macro to make it DRY, but that turns deftask into bake.core/deftask and then complains it can't find it. I might be doing something stupid, but I suspect there is some dirty hackery in Cake to get defmacro in my project.clj
10:44jweisstechnomancy: http://github.com/technomancy/dotfiles/blob/master/.emacs.old/behave/behave.el I don't suppose there's something like this in clojure? I'm looking at ways to make manually written tests (plain english) and automated tests come together
10:44LauJensenfliebel: Im not sure its such a great idea to wrap it in a macro, just use the macros that are already made available
10:46fliebelLauJensen: I don't like having the full expanded thing laying around a dozen times: (defmacro dt [hook] `(deftask ~hook (bake (:use utterson.plugin) [] (execute ~(keyword hook)))))
10:49fliebelLauJensen: Which macroes that are already available are you talking about?
10:51LauJensendeftask and bake
10:53fliebelLauJensen: So that is basically the expanded form of my macro x 5
10:54LauJensenWhy wouldn't it find deftask in bake.core ?
10:55fliebelLauJensen: It's actually cake.core, but still, no idea.
10:56fliebelLauJensen: One moment… It's even weirder.
10:57fliebelWhat is the difference with bake vs cake anyway? It's totally mixed up.
10:57LauJensencake is the outer vm, bake is your projects vm
10:57defncake is tasty
10:58RaynesI like pound cake.
10:58fliebel(hey defn)
10:58defn(hey pepijn)
10:58defnwant a peice of cake?
10:58defnpiece*
10:59fliebeldefn: nah, I've had enough (of) cake… It's not working for me
11:00defner uhh emmm, can you show me what you're trying to do and ill ask ninjudd about it?
11:01Raynesfliebel: There is a #cake.clj channel here on freenode as well.
11:01LauJensendefn: its not cake thats broken, its his macro which wraps cake
11:01fliebelRaynes: Great :)
11:02LauJensenRaynes: ninjudd is working towards a deadline at work which is about 2 weeks out AFAIK
11:02RaynesUnderstandable.
11:02fliebelLauJensen: Yea, but my macro just wraps a working deftask and replaces 2 values.
11:02RaynesHe's a ninja.
11:02LauJensenRaynes: true.. so he might actually be in here
11:03LauJensenfliebel: its still your macro
11:04fliebelLauJensen: When I expand the macro it does bake.core/deftask bit when I run the task it says ClassNotFoundException: cake.core
11:10defnfliebel: you're putting this task in your project.clj?
11:11fliebeldefn: Yea...
11:11defnmy advice: don't.
11:11fliebeldefn: so where to move them?
11:11defnput it in a tasks.clj and also -- i think something changed recently with cake's namespaces
11:11defnbecause i was mucking with it last night and couldn't find a cake.core either
11:12defnyou need to make sure to (:use cake) there
11:12LauJensendefn: When I spoke with ninjudd about this, we only discussed having tasks in project.clj, something changed since 2 weeks ago ?
11:12defnit weas my understanding that they could be in both places since the beginning
11:12fliebeldefn: So both cake and cake.core need to be used?
11:13defnfliebel: truthfully with the latest on github i dont know the answer to that definitively -- but i had trouble making tasks work in my project.clj when i tried out cake about a month ago, and i opted to put them in a tasks.clj in my src/foo/tasks.clj
11:14defnand used cake, cake.core there
11:14defnalthough as of last night, when i went to use cake.core -- it no longer was around -- there was a cake.project and cake.server, but neither contained deftask
11:14defnso im not sure without talking to lance or ninjudd
11:14fliebeldefn: I'll try
11:14octei'm trying to define a multimethod where the dispatch function is a keyword, like in the examples you see everywhere.. the problem is when my functions use more arguments than the first map
11:14octehow would i create multi functions like that?
11:15fliebeldefn: You know anything about command args? The readme says something about a mysterious opts var.
11:16mrBlissfliebel: maybe this helps: http://stackoverflow.com/questions/1341154/building-a-clojure-app-with-a-command-line-interface
11:18fliebelmrBliss: Thank you, but I'm trying to use Cake.
11:18Raynesocte: http://gist.github.com/577445 Here is a little example.
11:19naeuWhat's the most idiomatic way of taking a sequence and turning into a map where the keys are the els of the seq and the vals are the els passed through a given fn?
11:20mrBlissnaeu: something like (zipmap els (map fn els)) or (memoize fn) (lazier than the other)
11:21octeRaynes, thanks
11:21sproustI shouldn't code Clojure on the weekends, it makes coming back to my day job more difficult every monday. C-M-x, C-M-x, C-M-x, C-M-x and nothing happens. C-M-x ...
11:21Raynesocte: All I'm doing there is creating a function that just discards the rest of the arguments.
11:21defnfliebel: i dont know much about command args -- i just tried http://github.com/ninjudd/cake/blob/master/examples/test/project.clj and used the example
11:21defnit seemed to work fine for me in project.clj
11:22raeknaeu: this is what I probably would do: (into {} (for [elt some-seq] [elt (f elt)]))
11:22raekthe zipmap way looks a bit cleaner though...
11:22fliebeldefn: The readme said nothing about the asteriskses… *opts* vs opts
11:23LauJensena lot cleaner, but a little slower I think
11:23naeumrBliss: raek: Thanks both look nice
11:25LauJensen,(time (dotimes [_ 1e6] (let [x [1 2 3]] (zipmap x (map inc x)))))
11:25LauJensen,(time (dotimes [_ 1e6] (let [x [1 2 3]] (into {} (for [e x] [e (inc e)])))))
11:25clojurebot"Elapsed time: 7741.846 msecs"
11:25clojurebot"Elapsed time: 7458.186 msecs"
11:25naeuLauJensen: not too much difference then
11:26defnfliebel: you should add an issue for them to fix that
11:26defn:)
11:26LauJensennaeu: No, but it depends on the size of your collection. (map inc) spawns an entire new collection of the same size, where the for loop doesn't have that step, but I would go with the first
11:26LauJensenunless performance really matters
11:27fliebeldefn: It works fine in tasks.clj now.
11:27defncool!
11:27naeuLauJensen: when you say that (map inc) spawns an entire new collection, is that true even when it's lazy?
11:28LauJensenyea, the lazy-ness just determines when it happens, but it will happen
11:28raekmaps (the data structure) are not lazy, so the whole lazy seq will be forces (as will the for seq)
11:29raekbut maybe the head of the for seq will not be retained
11:31raekinto is basicaly just a (reduce conj ...), so the whole sequence generated by for should not be retained, afaik
11:31raek,(source zipmap)
11:31clojurebotjava.lang.Exception: Unable to resolve symbol: source in this context
11:32raekanyway, they seem to be fairly equivalent... choose the one that you think looks prettiest :)
11:32naeuraek: that'd be zipmap :-)
11:33naeubut that's probably because I'm still not entirely comfortable with list comprehension
11:33naeuright, I'm off out to buy flowers
11:33naeuthanks for your help everyon :-)
11:46LauJensen~source zipmap
11:46LauJensenraek: there's your syntax ^^
12:40anonymouse89anyone familiar with the state of complex numbers?
12:40anonymouse89that is, clojure.contrib.complex-numbers
12:47anonymouse89I'm trying to do matrix multiplication where the terms of the matrix is like e^ik where k is a constant
12:57naeuhey there, I'm sure I'm doing something incredibly stupid, but would totally benefit from some insight
12:58naeuconsider the following fn: (defn tutu [_] (println "road") (java.lang.Thread/sleep 1000) (println "toad"))
12:58naeuif executed like this: (tutu nil) it prints road, waits, then prints toad
12:58naeuhowever, things aren't so simple from within an agent:
12:59naeu(def a (agent nil)) (send-off a tutu) ;=> doesn't work as expected
12:59naeuam I doing anything obviously stupid?
13:00hoecknaeu: are you using slime?
13:00ninjuddLauJensen, defn: looks like fliebel is gone now, but in answer to your earlier question, you can put tasks in PROJECT_DIR/project.clj or PROJECT_DIR/tasks.clj
13:01naeuhoeck: yup
13:01hoecknaeu: slime does only print stuff in the simple-repl from within the repl thread
13:01ninjuddLauJensen, defn: i just recommend that you put them in tasks.clj if you want to maintain lein compatibility
13:01hoecknaeu: try to look at your *inferior-lisp* buffer
13:02naeuhoeck: I don't believe it's a printing problem - outside of the agent I see the printouts
13:02naeuyet when I run the fn from within the agent, then I don't
13:02hoecknaeu: but the fn is executed in another thread of the agent threadpool, and therefor not printed
13:03naeuhoeck: that makes sense. However, the main aim wasn't to print, that was just the example I used here. The main aim is to send bits down a wire, and that doesn't seem to work either
13:03naeuwhereas outside of the agent it does
13:05hoecknaeu: regarding the print, maybe try it on a plain repl then
13:06hoecknaeu: maybe can you paste the code that is not working as expected?
13:06naeuhoeck: (send-off (get spirits [1 1]) (fn [_] (do (poly/led-on 1 1) (java.lang.Thread/sleep 100) (poly/led-off 1 1))))
13:07naeupoly/led-on looks up an atom in the poly namespace and calls an external function with the deferenced atom as the first param which then sends some bits down a serial connection
13:07naeuthis all works find outside of an agent
13:08hoeckmhh, which IO-lib are you using for the serial connection?
13:09naeurxtx
13:09jkkramernaeu: does this work? (future (poly/led-on 1 1) (java.lang.Thread/sleep 100) (poly/led-off 1 1))
13:10naeujkkramer: perfectly...
13:10jkkramernaeu: are you sure (get spirits [1 1]) returns an agent?
13:11naeujkkramer: yep..
13:11naeu(class (get spirits [1 1])) ;=> clojure.lang.Agent
13:13hoecknaeu: and the agent is without errors?
13:13naeudoes a future explicitly create a new thread or does it use a thread from a threadpool?
13:13naeuhoeck: (agent-error (get spirits [1 1])) ;=> nil
13:13jkkramernaeu: it uses the agent thread pool i believe
13:14naeujkkramer: ah, shame - I need an explicit thread
13:14naeuperhaps I should be creating them myself them
13:15naeuI just thought it would be nice to use agents as with send-off you can specify an explicit thread and they all have message queues which would be useful
13:16naeuI just don't know why poly/led-on works on it's own, within a future, within an explicit thread (.start (Thread. #(poly/led-on 1 1)) yet not from within an agent...
13:17LauJensenninjudd: alright, thanks for weighin in
13:17ninjuddLauJensen: ah, just sent you an email
13:17LauJensenjust got it :)
13:17ninjuddLauJensen: i think it explains the problem fliebel had with his macro
13:18LauJensenYea, it sounds right
13:19ninjuddhe can likely fix it by replacing deftask with ~'deftask
13:19ninjuddthough generally, i'd recommend against wrapping deftask in macro like that unless there is a very good reason
13:20LauJensenIIRC thats what I said as well
13:21ninjuddwrapping bake may be a little more reasonable, but still bake is pretty terse, and having the namespace forms right there where they are used is a good thing in my opinion
13:22LauJensenI've had no problems with it and if you design around it you don't need macros for any use-case I can think of
13:27jkkramernaeu: future and send-off use the same executor. it's strange the latter doesn't work
13:27naeujkkramer: so send-off uses a thread-pool too?
13:28naeuo
13:30chouseryes. when a send-off completes, the thread that was running it is available again for another send-off
13:32naeuchouser: if I have n agents and I call n send-offs (one to each agent) simultaneously, will that create/utilise n threads?
13:33chousernaeu: yes
13:33chouserassuming none of the send-offs complete before you're done with all the send-offs.
13:33naeuchouser: sure
13:35naeuchouser: would you have any idea why a fn that performs serial IO would work stand-alone, from within a future, from within an explicitly created thread, but not from within an agent (and also not generate errors)?
13:35chouserhow sure are you that it doesn't generate an error. :-)
13:35chouserfns you send to an agent need to take the agent's old value as their first arg
13:36naeuchouser: only as sure as I am of agent-error reporting it to me
13:36naeuchouser: yeah, my fn is defined as follows:
13:36naeu(defn howdy [m] (do (poly/led-on 2 2) (Thread/sleep 5000) (poly/led-off 2 2)))
13:37chouserthat do is superfluous.
13:37chouserbut not your problem. hrm.
13:38naeuThe side effect is usually obvious - a light shines on an external device then extinguishes
13:38naeuhowever, from within the agent I have no illumination to enjoy
13:39chouser(send-off (agent nil) howdy)
13:39chouserlike that?
13:39naeuchouser: precisely
13:39chouserI got nuthin' Works here for println.
13:39naeuyeah, works here for println too
13:40naeuoddly, (future (poly/led-on 1 1) (java.lang.Thread/sleep 1000) (poly/led-off 1 1)) works fine
13:40chouseryou said future works? how do you call it?
13:40chouser:-)
13:41chouserwhat about (do (future (howdy nil)) nil)
13:42naeuchouser: works just like Blackpool illuminations :-)
13:42naeuI wonder why future works and send-off doesn't
13:42chouseryeah, me too
13:43chouserquite a bit more mechanics inside agents
13:43naeuthe mechanics behind poly/led-on are probably unecessarily complex
13:44naeubut one would assume that the side-effect behaviour of a future be similar to that of an agent
13:45naeuI guess I'll have to build an agent-like entity myself with n queues and n threads working on the queues
13:45raekusing agents should work. something's very strange.
13:46LauJensennaeu: One of the things which can be tricky about agents is that they can die in silence. Did you check out the new error handling stuff?
13:46hoecknaeu: is the io lib threadsafe? do you have a link to the sources?
13:46naeuLauJensen: agent-error returned nil
13:46mrBlissnaeu: you haven't issued a (shutdown-agents)?
13:47chousernaeu: (send-off (agent 1 :error-handler prn) howdy)
13:47naeuhoeck: I don't think that the io lib is at all threadsafe. However, I wrap the lib with another agent to serialise the calls
13:48naeumrBliss: why would I need to issue a (shutdown-agents)?
13:48mrBlissIf your agents went berserk (you couldn't stop them or something)
13:48mrBlissyou would have to restart your repl to get them running again
13:48jkkramernaeu: have you checked for errors in that lib-wrapping agent?
13:48chouserthat would kill future too
13:49chouser(shutdown-agents) would kill future too
13:49chousernaeu: did you see that :error-handler example? can you try it?
13:49naeuchouser: specifying the :error-handler made no difference
13:49mrBlisschouser: ok
13:50naeuthe call ran, but no beans
13:50chousernaeu: can you do a println deep in your led-on fn?
13:50naeujust to see if led-on is executed?
13:51chouserright
13:51chouserpreferrably as deep as you can insert a println
13:51chouserto make sure that led-on is called, but also whatever *it* calls is
13:51chouser...
13:51chouserI got it.
13:51chouseryou said you're using *another* agent inside?
13:51naeuchouser: yes..
13:52naeudo they not compose?
13:52chousersends in agent actions are held until the action completes
13:52chouserso you're probably sending the on and off more or less simultaneously after 5 seconds
13:52chousersufficiently deep printlns would show that.
13:52naeuchouser: ah bugger
13:53chouserso try...
13:53naeuworking on it...
13:54chouseras a quick hack, try (release-pending-sends) right before the Thread/sleep
13:54naeuchouser: your assumption appears to be entirely accurate
13:55naeuchouser: also, the release-pending-sends hack works
13:56naeuchouser: so can you briefly summarise what's going on when you compose agents?
14:02raekthe transition functions of agent either fail or succeed. sends only really gets sent if it succeeds (does not throw an exception)
14:03raeksends in transactions behave this way to
14:03raeko
14:03naeuyeah, I think I grok it now
14:03naeuso I'm wondering about the best way to proceed
14:03naeuis it wise to wrap the non-threadsafe IO lib with an agent?
14:04naeuor is there a better way to do this?
14:04raekif you want to serialize access, agents sounds resonable
14:04naeuraek: yeah, that's the intention
14:04mrBlissI built a similar system once with agents and promises
14:04hoecknaeu: not if you want thread confinement, because agent-actions are invoked in many pool threads
14:05raekimho, agents and shared output (any write-only operation) go together well
14:05naeuhoeck: what do you mean by thread confinement, and what might a potential issue be?
14:06hoeckthat means you only invoke your lib methods from within a single thread
14:06naeuhowever, if i do use an agent, do I have to litter my code with release-pending-sends to make sure the messages get sent if the IO is initiated in an outer agent?
14:07chouseranother option is to dedicate a thread to consuming a BlockingQueue
14:07naeuhoeck: I thought that with agents, if you invoke it from multiple threads then the messages get queued up and only consumed sequentially...
14:07chouserthen you can toss :on and :off events into it whenever you want.
14:07chousernaeu: the latter is true, that's how agents work.
14:08raeknaeu: only if that code happens to be inside an agent function
14:08naeuraek: so I don't fully understand the thread confinement problem
14:08raekthen the writer of the agent function should be aware of this behaviour anyway
14:08hoecknaeu: yes, but the libs methods are invoked from many different threads, and without proper synchronisation there is no guarantee that one thread reads the values set by another
14:08lyleBy any slim chance, is anyone associated with the RubyLearning "Clojure for Beginners" course in the channel?
14:09naeuhoeck: all the libs methods can only be accessed via one agent
14:09naeuwhich acts as a gatekeeper
14:09Rayneslyle: I'm a mentor.
14:09RaynesAnything I can help you with?
14:09hoecknaeu: I'd second what chouser said, just build a dedicated IO thread and use a Loop and a BlockingQueue to consume and invoke functions
14:09naeuhoeck: cool
14:09naeuThanks everyone for your insight and advice
14:10lyleRaynes: The link to the first day's exercise is broken. Several of us now have posted about it to the forum but no fix as of yet.
14:10Rayneslyle: Hrm. I didn't get any notification emails about it. I'll check it out.
14:10naeuI'm sure my objectives may seem strange and usual - but I'm trying to use Clojure to build a musical instrument, so things like timeliness matter in a different way to me :-)
14:10chousernaeu: but agents are really for managing shared state
14:11lyleRaynes: To be clear, I'm talking about the link to "Exercise 1: Clojure Syntax", at the bottom of this page: http://rubylearning.org/class/mod/resource/view.php?id=2025
14:11raekI've started programming on a lib for making BlockingQueue more clojure-y, btw: http://github.com/raek/stream-seq
14:11naeuchouser: I guess I was being too general when I saw the lib functionality as 'shared state'
14:11lyleRaynes: And the discussion is here: http://rubylearning.org/class/mod/forum/discuss.php?d=4194
14:12chousernaeu: they also serialize events, and manage thread pools. But sometimes when you want some of those feature but not all of them, agents end up behaving in ways that are unhelpful.
14:12chouser...like holding your sends.
14:12naeudamn them for holding my sends! :-)
14:12chouser(send (agent nil) ...) the 'nil' there is a little clue you might be abusing your agent.
14:13naeuFor thy who witholdeth my missives shall be subject to my fullest wrath
14:13chouserif the state of the agent doesn't matter, perhaps something else would make more sense.
14:13naeuchouser: yep, you're absolutely right :-)
14:13naeuthanks again
14:14chouserif you have one or more threads blocking, trying to pop from a work queue, agents are wrong and you should try a BlockingQueue
14:14chouserI believe I wrote that somewhere once...
14:15Rayneslyle: All of the exercise links appear to be broken. I'll fix them. I'm very, *very* sorry about this. I would have fixed it immediately if I had gotten an email notification.
14:16lyleRaynes: It's OK! I'm just glad I was able to track someone down. ;)
14:16chouserah yes, chapter 11 section 3, "When not to use Agents" :-)
14:17lyleRaynes: I have noticed that email notifications from the RubyLearning site are a little slow. It's a long way for those packets to get here all the way from India, I guess.
14:17naeuchouser: I haven't got that far yet ;-)
14:17naeuStill working my way through chapter 10
14:19kumarshantanuhi, can somebody tell me how to define test-ns-hook for multiple test files?
14:19raekchouser: I discovered that som of the macros of error-kit is missing from the docs: http://clojure.github.com/clojure-contrib/error-kit-api.html
14:20chousernaeu: fair enough. I'll let you catch up then. :-)
14:20raekit probably isn't you that I should report this to, anyway...
14:20chouserraek: how would you feel if the error-kit api changed?
14:21raekmy intention was to try if the continue stuff would make sense in my project
14:21raekI want to do error handling in ring handlers
14:22raekso something that returns an error response instead of throwing an exception might interesting
14:22Rayneslyle: Thank you very much for letting me know. :\
14:22chouserraek: ok, cool. let me know how it goes.
14:22raekwhat would the API change be? remove the continue stuff?
14:22chouserraek: pay particular attention to whether there's any value in a hierarchy of error types, or if simple "tags" work better.
14:23chouserraek: no, simplify the error object/type stuff
14:23raekis there anywhere I can read more on how continue is used?
14:23raekcontinue-with just return a value at the "raise-point", right?
14:24lyleRaynes: Thank you. Now I realize that I had already found the exercise by accident, although I didn't know that was "the" exercise. ;) I thought it was just some sort of follow-up discussion of the exercise. Thanks again for your help!
14:25Rayneslyle: I'm not sure what all that FORUMDISCUSSION nonsense was. I just put in direct links. I'm new to this mentoring stuff.
14:26lyleRaynes: Presumably some sort of template variables that weren't being replaced properly, but I don't know (not a PHP person myself).
14:26chouserraek: yes
14:26RaynesI'm sure they'll educate me.
14:26chouserraek: http://pragprog.com/magazines/2009-07/when-things-go-wrong
14:28raekchouser: I used error-kit as a replacement for exceptions once. I did not use the type hierarchy thingy then. I declared the errors hierarchically, but did not utilize it in the handlers
14:29raekthanks for the link!
14:29chouserwithout a hierarchy, you might not need to declare error types at all
14:29chousersure, I love that link -- Halloway documenting and demoing my code, so I don't have to. :-)
14:30raeka (namespace qualified) keyword for identifying the error would be sufficient for me, I believe
14:30kumarshantanuhi, can somebody tell me how to define test-ns-hook for multiple test files (namespaces)?
14:36raek~conditions
14:36clojurebotCL conditions is http://www.gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html
14:36raek~error-kit
14:36clojurebotExcuse me?
14:37raekclojurebot: error-kit is http://pragprog.com/magazines/2009-07/when-things-go-wrong
14:37clojurebotAlles klar
14:37chousererror-kit is based almost exclusively on that gigamonkeys page
14:45LauJensenalways good to base your work off monkeys
14:45raekwhere does bind-continue return from? the raise-point or the handle-point?
14:47chouserummmm
14:48raekthis calls for experimentation at the repl, anyway
14:49chouserI think the final value of a bind-continue clause is the return value of the whole with-handler. Is that what you're asking?
14:50raekyes
14:50raekbut I should be able to end the bind-continue form with a continue-with I guess...
14:51chouserman, that stuff's complicated. I think I had forgotten about bind-continue
14:53chouserI don't think you can continue-with from inside a bind-continue
14:53raekmy idea was to define stuff that can go wrong in the model as errors
14:53chouserthough tell me if you find it works.
14:53raekcode that renders an error response as bind-continues
14:53raekand connect these with handlers that call continue
14:54raek(handle form-validation-error [details] (continue bad-request details))
14:55raekbut just a handler would be sufficient, I think
14:55chouserI think when you call 'continue' control is irrevokably passed up to whereever (bind-continue bad-request ...) is
14:56chouserso no way to do a continue-with
15:01LauJensenI vaguely recall some kind of Swing Utility, or Refinery, or something similar which lets you center a jframe on the screen (dont need tips on writing it myself, just wanted to know if something exists already)
15:04raekchouser: yes, you're right.
15:05ordnungswidrigLauJensen: java.awt.Frame/setLocationRelativeTo(null)
15:05chouserbut regardless of whether it's possible, if simply calling a fn to render an error is sufficient, then that's certainly simpler.
15:05LauJensenordnungswidrig: thanks I'll have a look
15:06ordnungswidrigLauJensen: but you're right, there are quite a lot of helper that do this. It's nicely hidden in the api doc
15:07raekis bind-continue supposed to be provided by the raiser or the handler?
15:08cemerickLauJensen: just use jframe.setLocationRelativeTo(null)
15:09chousersomething in the middle, I think. the raiser provides only the error. a handler up above uses continue to send control from the raiser partway up to the bind-continue.
15:09chousergotta go. bbl.
15:11raekok, thanks! I will continue to experiment with this
15:49arkhre-seq says it returns a lazy-seq but it actually doesn't. Anyone know why?
15:49arkh,(prn (class (re-seq #"(a)(s)d" "asdf")))
15:49clojurebotclojure.lang.Cons
15:49arkh,(prn (class (for [i (range 10)] [i])))
15:49clojurebotclojure.lang.LazySeq
15:52pomyk,(prn (class (rest (re-seq #"(a)(s)d" "asdf"))))
15:52clojurebotclojure.lang.LazySeq
15:54raekah, since it knows whether the first cell is nil or not, it might as well return it
16:17dsantiagoDoes anyone have any strategies for easily building your programs in different configurations? (Like, debug/release)
16:25lancepantzdsantiago: i've actually been working on that exact feature for cake
16:26lancepantzi have it working in a branch if you're feeling adventurous
16:26lancepantzyou'd ofcourse have to be using cake for your builds, which again is for the adventurous :)
16:36amalloyi'm a bit surprised that it's tricky to combine update-in and remove. is there anything better than (update-in mymap [:key1 :key2] #(remove #{item} %))? ideally i could just end with remove #{item}
16:37raekyou have a map of maps of sequences?
16:45amalloyyes
16:46amalloyraek: since you seem curious, it's a card game thing. there is a map of players, each of whom has a map of suits, whose values are vectors of cards
16:46raekI would make the vectors sets
16:47raeksince they have fast add and remove operations
16:47raekbut you still get the rather long update-in
16:47amalloyhm. that's a good point. i was using vector for sorting, but isn't there a sorted-set?
16:47raekyes, there is
16:48raekand you can provide your own comparator if you want to sort them like 1 2 3 ... 10 :j :q :k
16:48dsantiagolancepantz, how do I find this branch?
16:48amalloyyeah, i've already got a comparator
16:48amalloythanks for the tip! but beware, you're teaching me that it's a good idea to just spew random crap about my app into #clojure and hope someone will improve it :)
16:49lancepantzdsantiago: http://github.com/ninjudd/cake/tree/f
16:49raek(update-in [player suit] #(disj % rank))
16:49lancepantzdsantiago: i'll throw a gist together that shows how to use it, just a second
16:50dsantiagoThank you.
16:51raekoh, forgot the map as the first argument to update-in...
16:52lancepantzdsantiago: http://gist.github.com/578019
16:53dsantiagolancepantz: So this works with swank?
16:53dsantiagoCuz this is like exactly what I wanted.
16:54lancepantzdsantiago: the defproject stuff is pretty straight forward, then in tasks you'll have a var called *env* that's bound to the values from the map of your current environment
16:55lancepantzyou can then set your environment in .cake/config as env=qa or from the command line with -env=qa
16:55dsantiagoBrilliant.
16:56lancepantzcake works with swank, yws
16:56lancepantz*yes
16:59dsantiagoSo this is in a branch, so to install it I'm gonna have to do some git-fu?
17:00lancepantzyeah, you'll have to clone it, the git co f
17:00lancepantzand symlink bin/cake to your path
17:00lancepantzs/the/then/
17:01dsantiagoThanks.
17:02dsantiagoHow close is this to going into the full version?
17:04lancepantzprobably a week or so
17:04dsantiagoWonderful.
17:04dsantiagoThis finally made me pull the trigger on lein -> cake.
17:05lancepantzshhhh :)
17:06dsantiagoHeh. I like them both. But this one is solving my biggest pain point right now.
17:06grignaakis there any reason conj isn't implemented as such: http://pastie.org/1156631 ?
17:07lancepantzgreat! it was a pain for me as well, glad it helps others
17:07grignaakit would make it a lot easier for (apply conj coll possibly-empty-coll)
17:07lancepantzs/pain/pain point/
17:07sexpbot<lancepantz> great! it was a pain point for me as well, glad it helps others
17:08alpheusI've got some awkward code that I think could be improved with destructuring but I don't know how. If you'd like to take a look: http://upholsters.us/pairs-to-map-of-sets.clj
17:12jkkramergrignaak: (reduce conj coll possibly-empty-coll) or (into coll possibly-empty-coll) are alternatives
17:14grignaakgreat! thanks! I had a simple two-line implemented a conj+ that forwarded to conj
17:15grignaakbut into looks to fit the bill nicely
17:17amalloyalpheus: i think you want to use language built-ins like reduce here, rather than write it yourself
17:18jkkramer,(reduce (fn [m [k v]] (assoc m k (conj (get m k #{}) v))) {} [[:bob :beer] [:bob :bread] [:alice :apples]])
17:18clojurebot{:alice #{:apples}, :bob #{:bread :beer}}
17:19jkkrameralpheus: ^^
17:19amalloy(defn make-sets [& pairs] (reduce (fn [master [who what]] (update-in master [who] conj what)) {})) is my version; it works but winds up with seqs rather than sets at the end
17:20amalloyi didn't know about the not-found feature of maps, jkkramer! neat!
17:22lpetitHello
17:23raek,(:test {} :not-found)
17:23clojurebot:not-found
17:23jkkramer,(reduce (fn [m [k v]] (update-in m [k] (fnil conj #{}) v)) {} [[:bob :beer] [:bob :bread] [:alice :apples]]) ; also possible
17:23clojurebot{:alice #{:apples}, :bob #{:bread :beer}}
17:24jkkramerupdate-in + fnil can be handy
17:24raekdidn't know about fnil... neat!
17:25raek(fnil re-find "")
17:26jcromartiewow fnil is blowing my mind
17:26alpheusthanks, all. I'll look at those and learn.
17:26jkkramerclojure.core is a treasure trove :)
17:27phobbs wow
17:29raekclojure's function-returning functions are often overlooked...
17:30raekjuxt is a recently found favourite of mine
17:30jcromartienifty
17:31raek,(let [stack [1 2], pop-peek (juxt pop peek), [stack arg1] (pop-peek stack), [stack arg2] (pop-peek stack)] (conj stack (+ arg1 arg2)))
17:31clojurebot[3]
17:32jkkramerone of my favorite snippets -- run-length encoding:
17:32jkkramer,(map (juxt first count) (partition-by identity [:a :a :a :b :b :c :d :d]))
17:32clojurebot([:a 3] [:b 2] [:c 1] [:d 2])
17:33raekman, that's beautiful...
17:36jcromartietrue dat
17:41taliosAwesome - writing IntelliJ IDEA plugins in clojure - http://bit.ly/9Zaynf
17:44lpetittalios: interesting, but it's somewhat not new that genclassed clojure is fully interoperable with pure java compiled code, or is it ?
17:45lpetithmmm, maybe I missed the point ...
17:53amaevisHi! Could someone help with interpreting how LockingTransaction.run() works?
17:53amaevisI'm trying to create a version of refs with built in durability
17:55amaevisHas there been any work with adding D to ACI identities?
17:56chouserthere have been a couple threads on the google group
17:56amaevisI think that's me.
17:56chouser:-)
17:57amaevisI'd like to get your thoughts...
17:57amaevisIs it worth pursuing? Part of the vision?
17:57talioshrm - lpetit left - oh well, what was more interesting is that Jetbrains are looking at writing plugins in clojure as part of the plugin code - even if just genclassed currently
17:57chouserthe vision isn't mine
17:58chouserI don't know what's in rhickey's head.
17:59amaevisYou've been contributing a lot longer. :)
17:59chouserI would love a simple and efficient way to persist in-memory structures to disk.
17:59chouserI don't know if I like the idea of transactions blocking until the disk flushes, though.
18:00amaevisDoes the API I put forth on Google Groups make sense?
18:00amaevisIt doesn't have to block to the disk flush.
18:00chouserwithout that it's not Durable, is it?
18:01amaevisI happen to be using BDB and that param is configurable.
18:01amaevisYou can choose your durability level.
18:01amaevisBy default it would flush per transaction.
18:03chouserwhat would be the value of tying into the STM except to flush per transaction?
18:03chouserI'm not seeing your API on the group.
18:04bartjvery off-topic, but does anyone have a statistics background here
18:05amaevisThe API is basically to use (dref <name> <initVal>) instead of (ref <initVal>).
18:05amaevisIt ties the contents of the durable ref to the <name> in the BDB store.
18:05amalloybartj: i took one graduate course in statistics but it's been a long time since i used any of it
18:05amaevisClojure would flush to the DB with every transaction.
18:06amaevisBut the DB can choose to flush to disk at will.
18:06amaevisBy default, at the highest durability, it would flush per transaction.
18:06amaevisBut it can write to log without flushing to the main pages.
18:07amaevisOr delay writing to log altogether.
18:07bartjthe question basically is about generating a representative sample of (~400) from 400K records
18:07amaevisIf performance requires it. It's a conscious choice by the app dev to offset durability for performance.
18:11chouseramaevis: Each ref would be in its own file?
18:11amaevisNo, it's a key-value pair in a BDB DB.
18:11amaevisThe key is given at create time.
18:12raekbartj: have you seen the Incanter project?
18:12amaevisWhen the same code is run later (i.e. next JVM instance), using that same key inits the dref from disk. Only if it's not found does the code-supplied initVal get used.
18:12chouserso two transactions operating on two different refs that would normally have essentially no contention will now contend over access to the db?
18:12raek...maybe you were looking for a person with knowledge rather than a library
18:12bartjraek, yes (but not thoroughly), the question is more whether the approach is correct
18:13bartjraek, yes your are right
18:13amaevisYes. I see that as a plus. Two JVMs accessing the same BDB DB and key get sync-ed.
18:13chouseramaevis: have you looked at http://github.com/gcv/cupboard
18:13amaevisYes. I don't like explicit (make-instance) calls.
18:13amaevisPlus there's no transactional safety.
18:14chouserhm, it does claim "ACID transactional semantics"
18:14amaevisYes, within a single call.
18:15chouserok
18:15amaevisBut how do you compose?
18:15chousersounds to me like you've got more bases covered than I know to look for.
18:16amaevisI have the implementation all set except for hacking the commit into LockingTransaction.
18:16amaevisI don't grok run().
18:16amaevisI see the commutes, sets, and vals collections.
18:17amaevisBut I'm unclear as to how to determine refs that have been ensured without setting, ref-sets without ensures, and alters.
18:17amaevisAs well as commutes, which I don't grok at all.
18:19chouserwell, I may be able to help you with those details later.
18:19chouserbut for now I have to go.
18:19chouserfare well.
18:19amaevisthanks!
18:22raekthe implementation of commute or what it's about?
18:22amaevisthe implementation
18:23amaeviswithin the context of the run() method.
18:23raekcan't help you there :-)
18:23amaevis:)
18:25anonymouse89is there a more concise way to do this? (assoc foo :elts (concat (foo :elts) (list a)))
18:26raek,(update-in {:elts [1 2 3]} [:elts] #(conj % 4))
18:26clojurebot{:elts [1 2 3 4]}
18:27raekvectors are faster for appending to the back
18:28lpetit,(update-in {:elts [1 2 3]} [:elts] conj 4)
18:28clojurebot{:elts [1 2 3 4]}
18:28raekupdate-in can assoc a new value to a key by applying a function to the old value
18:28raekhrm, of course...
18:28lpetitno need for #(conj % 4), conj 4 is sufficient with update-in and al
18:29lpetitbut I'd better go to bed now, cu
18:29anonymouse89raek, lpetit: perfect
18:39bartjraek, is it possible to sample a distribution in Incanter ala - http://www.exposurescience.org/heR.doc/library/heR.Misc/html/distrib.html
18:40amalloyyep, if two people give identical answers within seconds of each other, it's a good bet the answer is right :)
19:00amalloyis there a nice way to filter a seq of maps for values that have some given value? (filter (comp #{testval} :key) myseq) seems good but i wonder if it's idiomatic
19:01lazy1"values that have some given value?" I don't understand
19:02amalloyer...entries with a given value? ie i only want objects whose :name property is "David"
19:03tomojlooks good to me
19:04amalloyneato. i'm still getting my head around the idea of using objects as functions; i expect the ClassCastPolice to jump around the corner when i pass a set to comp
19:08lazy1amalloy: (filter #(= (:key %) some-value) myseq) will work as well
19:08lazy1Not sure if it's more idiomatic though
19:14jjidohow do I add one element in front of a vector or list?
19:15AWizzArdjjido: conj
19:16jjido,(conj "a" [2 3 4])
19:16clojurebotjava.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IPersistentCollection
19:16jjido,(conj ["a"] [2 3 4]
19:16clojurebotEOF while reading
19:16jjido,(conj ["a"] [2 3 4])
19:16clojurebot["a" [2 3 4]]
19:16jjidoI need to flatten it
19:17AWizzArd(conj yourlist new-item)
19:17lazy1,(cons 4 [1 2 3])
19:17clojurebot(4 1 2 3)
19:17AWizzArd,(conj (list 10 20 30) :x)
19:17clojurebot(:x 10 20 30)
19:18AWizzArd,flatten
19:18clojurebot#<core$flatten clojure.core$flatten@c09e0f>
19:18jjidothanks you two
19:18lazy1,*clojure-version*
19:18clojurebot{:interim true, :major 1, :minor 2, :incremental 0, :qualifier "master"}
19:18lazy1Note that for vector, conj will append
19:18lazy1,(conj [1 2 3] 4)
19:18clojurebot[1 2 3 4]
19:24jjidoto take all elements from list up to item n? to take all elements from item n upwards?
19:25AWizzArdjjido: .subList
19:26jjidoAWizzArd: if it starts with . it is Java isn't it?
19:27jjidoOk it is documented in the Sequences page
19:27lazy1,(doc take)
19:27clojurebot"([n coll]); Returns a lazy sequence of the first n items in coll, or all items if there are fewer than n."
19:27lazy1,(doc drop)
19:27clojurebot"([n coll]); Returns a lazy sequence of all but the first n items in coll."
19:28jjidoand:
19:28jjido,(doc split-at)
19:28clojurebot"([n coll]); Returns a vector of [(take n coll) (drop n coll)]"
19:31jjidodo names need to be unique in a let?
19:31jjido,(let [a 2, a (+a a)] a)
19:31clojurebotjava.lang.Exception: Unable to resolve symbol: +a in this context
19:31jjido,(let [a 2, a (+ a a)] a)
19:31clojurebot4
19:31jjidocool
19:56jjidoDoes Clojure come with a math-specialised library?
19:57lazy1Like http://incanter.org/ ?
19:57lazy1You have access to all the Java Math library
20:01lazy1,(.isProbablePrime (bigint 10001) 10)
20:01clojurebotfalse
20:02killownclojure is a good option for those who want start with a functional programming language?
20:02dnolen_killown: depends on what you want to explore, but I would venture a yes.
20:05killowndnolen_, just for know, I want one that offer best concepts of a functional language.
20:06dnolen_killown: unsure about "best concepts". for example, Haskell has different concepts than Clojure. From what I can tell, they're "different" not "better"
20:06jjidokillown: Clojure is v. good, it is based on Lisp which has been around for a long time
20:06jjidothe syntax is simple!
20:07killowndnolen_, jjido I want one with simple syntax :)
20:07RaynesLisp is well known for it's (lack of) syntax.
20:08jjidolazy1: it is certainly there in incanter but I don't know how to find it. I want to get all permutations of a list
20:08killowndnolen_, but I need one that forced into a functional paradigm
20:08dnolen_,(permutations [1 2 3])
20:08clojurebotjava.lang.Exception: Unable to resolve symbol: permutations in this context
20:09dnolen_,(clojure.contrib.combinatorics/permutations [1 2 3])
20:09clojurebotjava.lang.ClassNotFoundException: clojure.contrib.combinatorics
20:11dnolen_,(require '[clojure.contrib.combinatorics])
20:11clojurebotjava.io.FileNotFoundException: Could not locate clojure/contrib/combinatorics__init.class or clojure/contrib/combinatorics.clj on classpath:
20:11dnolen_darn, jjido: anyways, put that into your repl that has contrib on the classpath
20:11jjidook
20:11dnolen_killown_: yeah Clojure will push you in that direction.
20:16killowndnolen_, thanks
20:34jjido,(fact 10)
20:34clojurebotjava.lang.Exception: Unable to resolve symbol: fact in this context
20:36jjidomeh I started with 3 million permutations ;-)
20:37jjidothe fans were blowing hard until I pressed ^C
20:40jjidogn
20:59jcromartiekillown: just to chime in, yes Clojure is a good place to start learning FP
21:00jcromartieif you never use ref, agent, atom, or def (twice) you're purely functional
21:00jcromartiesome might say that memoize is cheating
21:00jcromartiebut I say it still counts
21:00technomancyor I/O, or binding, or delay, or promise, or future... =)
21:01technomancy</pedant>
21:03amaevishow is memoize cheating?
21:03jcromartie,(source memoize)
21:03clojurebotjava.lang.Exception: Unable to resolve symbol: source in this context
21:03jcromartieoops
21:03jcromartiewell, you get the picture
21:03jcromartieyes
21:03amaevislol
21:05jcromartieit uses an atom to store the cache
21:07amaevisthe side effects aren't accessible
21:07amaevisthat's fine
21:14tomojit's fine as long as the function you memoize is fine
21:26jcromartie,(let [printer (memoize (fn [x] (println x)))] (printer 1) (printer 1))
21:26clojurebot1
21:26jcromartiethere are all sorts of ways that memoize could cause surprises
21:27jcromartiebut anybody writing Clojure understands what mutable state implies
21:27jcromartieso it might not be too surprising
22:22fbru02what is the actual meaning of splice ?
22:22fbru02`(~@foo) where foo is a local, what does it do?
22:24lancepantz_oh, you mean the reader macro?
22:24wwmorgan,(let [foo (list :a :b :c)] `(~@foo))
22:24clojurebot(:a :b :c)
22:24rhudsonThe value of foo in such a case is typically a sequence, as (a b c). If you just wrote `(~foo), you'd get ((a b c))
22:24lancepantz_it's just like apply
22:24rhudsonBut `(~@foo) gives you (a b c)
22:25lancepantz_*correct me if i'm wrong
22:25fbru02thanks all, and why is it so relevant to macros ?
22:26rhudsonA typical use is when you have something like (defmacro f [bindings & body ])
22:26rhudsonwhere you want to have the forms in 'body be the code expansion of the macro
22:26rhudsonYou don't want extra parens around the body
22:27fbru02rhudson: thanks i get it
23:06iveyI am having a nasty problem with SLIME. My REPL keeps freezing, and I have to reconnect. Happens almost anytime I leave the window containing the REPL.
23:06iveyAnyone seen this? Using 'lein swank' for the backend, but that shouldn't matter.
23:07jcromartiehm, not me. sorry
23:08thunkivey: Are you able to evaluate compound forms, like (+ 1 2) , before it freezes?
23:08iveylet's see
23:09iveyi can usually do most anything as long as I don't leave the buffer
23:09iveyalthough right now i can switch back and forth and it's OK
23:11iveyfeh, of course it stops being a problem when i ask about it.
23:11thunkThere's another hanging repl issue that can be worked around with an (unlad-feature 'slime-autodoc t) (evaluated by emacs, not slime, that is), but this doesn't sound like it.
23:12thunk*unload-feature
23:12iveylet's see if that makes a difference
23:13iveyi rarely use the autodocs anyway
23:18iveyOK, I have more info. turning off autodoc didn't fix it. It's when I switch to a buffer with a clj file that it hangs.
23:19iveyIn the modeline there's a [project-name clojure N] where N is normally not there. hit c-c c-k and N goes to 1, then goes away again.
23:19iveybut as I move point around the file, N goes to 2, 3, 4...like it's sending requests to swank for some reason
23:20jlf`any info when you mouse over N?
23:22iveyjust minor mode info
23:27tomoj,(reduce #(map + %1 %2) (repeat 100000 [1 1 1]))
23:27clojurebotEval-in-box threw an exception:java.lang.StackOverflowError
23:28tomojwhy?
23:28clojurebothttp://clojure.org/rationale
23:30wwmorgan,(reduce #(doall (map + %1 %2)) (repeat 100000 [1 1 1]))
23:30clojurebot(100000 100000 100000)
23:31tomojyeah, in my case using vect to force worked
23:31tomojI still don't understand it though
23:32tomojI think I vaguely understand why it happens. it seems strange to me that I've never seen a blog post about this kind of problem
23:32wwmorganthe reduce builds up a lazy sequence whose evaluation requires going up 10000 levels in the stack. When the repl tries to evaluate it, the jvm runs out of stack space
23:32wwmorganer, 100,000
23:32tomojyeah
23:33tomojI don't think I've ever thought about stack being required to realize a lazy-seq
23:33tomojwell, I'll always be able to recognize that stack trace
23:38iveyOK, narrowed it down to something in '(slime-repl slime-presentations slime-autodoc)
23:38iveymy guess is presentations
23:41iveyYep, presentations. And since I don't actually know what that's good for...problem solved! Thanks for helping me think out loud.