#clojure logs

2010-03-15

00:04psykoticdoes map ever automagically call sorted-map like it calls hash-map and array-map? or is it only ever used when you call it explicitly?
00:12JonSmithmap is for mapping, and produces seqs
00:12JonSmithas far as i know anyway
00:19dcnstrctwhat's the most simple way to get a random element from a vector ?
00:24rfg_dcnstrct: (nth coll (rand-int (count coll)))?
00:24dcnstrctahh rand-int thnx
00:25rfg_:)
00:27psykoticJonSmith: sorry, bad formulation. i really meant (into {} ...), conjing onto a map, and so on
00:28psykoticfor example, up to size 9, it uses an array map, and then it uses a hash map
00:28hiredmanif you into a sorted-map you will get a mp
00:28hiredmanpsykotic: actually that is not something into does
00:28psykoticconj presumably?
00:28hiredmanarray map promotes under the covers
00:29psykoticright
00:29psykotici'm looking at the code actually
00:29hiredmanthe clojure or the java?
00:29psykoticjava
00:29psykoticanyway, regardless of mechanism, is there a case in which something is promoted/demoted/whatever to a sorted map if it isn't already?
00:30psykoticor is it opt-in only?
00:30hiredmaninto goes into the specified container type
00:31hiredman,(type (into (sorted-map) {:a 1 :b 2}))
00:31clojurebotclojure.lang.PersistentTreeMap
00:31psykoticyes, clearly
00:31psykoticanyway. i think i've answered my question.
00:38maxhodakit says I can't "send to channel"?
00:39maxhodakhmm. that seems to have gone through
00:44dcnstrctyou have to verify your nick with chanserv first
02:04sproustQuick question: my clj script won't exit.
02:04sproustI run a clj script I built, which invokes clojure.main with the text.clj script I wrote.
02:04sproustUNIX style.
02:04clojurebotstyle is http://paste.lisp.org/display/81021
02:04sproustclojure.main does not exit.
02:04sproustIs there anything special I need to do?
02:05sproustDo I need to exit explicitly?
02:05sproust(I'm guessing this is a common problem.)
02:06sproustAaah, oops never mind. It seems related to lazy-xml parsing.
02:07sproustIt's strange, when I invoke parse-seq, it won't exit.
02:56nipraHi
02:57tomojhello
03:02nipraM-. (slime-edit-definition) is failing with following error: ``Search failed: " clojure/core.clj$"''. It was working fine I was using Emacs starter kit. Some info here: http://pastebin.com/xMmuH9jj
04:57mauritslamershi all, is it known behaviour that fields in an SC.Query condition are camelcased?
04:57mauritslamersthat is: camelcased automatically?
05:17mauritslamersDoes anyone have problems regarding SC.Query.local? It just does not seem to work...
05:22hoeckmauritslamers: can you please give some context?
05:22mauritslamerswith pleasure :)
05:22hoeckgreat!
05:22hoeck:)
05:22mauritslamersI have a set of records loaded from my db backend
05:22mauritslamers(I'll gist some stuff)
05:23mauritslamersehhh hoeck... wrong channel :-)
05:23mauritslamersOops :)
05:23hoeckahhhh :)
05:23mauritslamersWeird Program Colluquy
05:24mauritslamershoeck: sorry about that :)
05:24hoecknever mind
05:29Licenser_aloa
05:29Licenser_morning my lispy friends
05:31hoeckGood Morning Licenser_
05:41nipraHow can I apply a function to all keys of a map recursively?
05:45esjwhat do you mean recursively ?
05:45esj(map #(...) (keys my-map)) not gonna work ?
05:47nipraesj: map may contain map(s) at any level. function should apply to all keys.
05:47esjaah, i get you now
05:53noidinipra, do you want to apply the function to all the values that are not maps themselves?
05:56nipranoidi, I want apply function to keys of a map at any level inside the map. So value may be a map or seq of map(s).
05:57esjsomething like
05:57esj(defn t [x]
05:57esj (if (map? (second x))
05:57esj (map t (second x))
05:57esj (first x)))
05:57esj?
05:59esjcall it with (may t my-nested-map) and it will spit out the keys, nested
05:59esjs/may/map/
06:06hoecknipra: http://paste.lisp.org/display/96405 ?
06:06noidiheh, here's my version with another interpretation of the spec :) http://gist.github.com/332691
06:06noidifun puzzle!
06:07esja nice sedge into Monday
06:09noidiyup, writing that was a fun way to get back into coding mode after lunch break :)
06:09esjhahah, I'm still winding up (only one coffee down)
06:10bobo_http://gist.github.com/332692 any clue why the values dont get stored in the session? even if i print them in the line below they are nil
06:14nipranoidi, (map-keys keyword {"a" 1 "b" [{"c" 1}]}) => {:a 1, :b [{"c" 1}]} ;; "c" doesn't get keyfied :-(
06:15noidiah, so you want to recurse into seqs, too
06:15nipranoidi, yes
06:18noidinipra, I updated the gist http://gist.github.com/332691
06:21nipranoidi, (map-keys keyword {"a" 1 "b" [{"c" 1}]}) => {:a 1, :b [{"c" 1}]} ;; Same as earlier
06:22noidiare you sure you're not using the older version of the function?
06:22noidiI copied that example out of my REPL
06:25nipranoidi, opps.. my bad. Thanks a lot! That works. :-)
06:33noidinipra, great!
06:50nipranoidi, I think that function should be included in clojure.contrib.map-utils as deep-apply-to-keys. And there should be deep-apply-to-vals too. :-)
06:52psykotici'm watching the interview with stuart on infoq and want to stab the interviewer in the neck.
06:52niprapsykotic, why?
06:52psykotiche's a horrible interviewer.
06:52nipraIt's a nice interview.
06:52psykoticstuart is great
06:53psykoticall the infoq interviews by this guy have the same problem.
07:07noidipsykotic, yeah, that interview seemed really weird to me, too
07:07noidiit seemed as if the interviewer was just coming up with the questions off the top of his head
07:08noidiwhile stuart had clearvoyantly anticipated his questions and prepared good answers to them :)
07:08noidi*clairvoyantly
07:13psykoticnoidi: that guy is _always_ like that.
07:14psykoticusually they have fantastic interview subjects. it's a shame to waste opportunities like that with bad questions and an interviewer who just parrots the prepared questions without engaging the interviewee.
07:38licoresseLooking for a smarter way to do:
07:38licoresse,(zipmap (range -1 -9 -1) (repeat 8 -1))
07:38clojurebot{-8 -1, -7 -1, -6 -1, -5 -1, -4 -1, -3 -1, -2 -1, -1 -1}
07:40noidiyou can at least drop the "8" because the range is fixed
07:40licoresseok
07:41noidi,(zipmap (range -1 -9 -1) (repeat -1))
07:41clojurebot{-8 -1, -7 -1, -6 -1, -5 -1, -4 -1, -3 -1, -2 -1, -1 -1}
07:42licoresseit still feels rather thorough
07:45licoressewould this be possible to do using the juxt function?
07:51hoecklicoresse: can't see how to use juxt here
07:52hoecklicoresse: the zipmap can be a bit shorter by using (range -9 -1)
07:52licoressehoeck: yes, thats even better
07:52ulfster,(range -8 0)
07:52clojurebot(-8 -7 -6 -5 -4 -3 -2 -1)
07:54licoresseanyhow, it's now in reverse order
07:55ulfsterdoes not matter since it is a map
07:55licoresse,(zipmap (range -8 0) (repeat -1)
07:55clojurebotEOF while reading
07:55licoresse,(zipmap (range -8 0) (repeat -1))
07:55clojurebot{-1 -1, -2 -1, -3 -1, -4 -1, -5 -1, -6 -1, -7 -1, -8 -1}
07:55ulfsteryou access it via the keys, so the order of entries should not matter
07:55ulfster,((zipmap (range -8 0) (repeat -1)) -3)
07:55clojurebot-1
07:56licoresseok
07:56licoresseI need to think this through, thanks
08:02licoressealtering the range, the final result should look like this:
08:02licoresse{1 [-4 -1] 2 [-3 -1] 3 [-2 -1] 4 [-1 -1] 5 [1 -1] 6 [2 -1] 7 [3 -1] 8 [4 -1] 9 [4 1] 10 [3 1] 11 [2 1] 12 [1 1] 13 [-1 1] 14 [-2 1] 15 [-3 1] 16 [-4 1]}
08:03licoresseor something similar where I have indexed access
08:04licoresseit's four quadrants
08:05ulfster,(zipmap (range 17) (for [x (range -4 5) y '(1 -1)] [x y]))
08:05clojurebot{0 [-4 1], 1 [-4 -1], 2 [-3 1], 3 [-3 -1], 4 [-2 1], 5 [-2 -1], 6 [-1 1], 7 [-1 -1], 8 [0 1], 9 [0 -1], 10 [1 1], 11 [1 -1], 12 [2 1], 13 [2 -1], 14 [3 1], 15 [3 -1], 16 [4 1]}
08:05ulfsternot quite
08:05licoresse:-)
08:05ulfsteris the indexing fixed?
08:06licoresseyes
08:06ulfsterleft -> right, top -> bottom?
08:06licoresseyes
08:06licoressethen right -> left again
08:07licoresseclockwise
08:07licoressethe (for construct is interesting though
08:08ulfster,(for [y '(1 -1) x (range -4 5)] [(* x y) y])
08:08clojurebot([-4 1] [-3 1] [-2 1] [-1 1] [0 1] [1 1] [2 1] [3 1] [4 1] [4 -1] [3 -1] [2 -1] [1 -1] [0 -1] [-1 -1] [-2 -1] [-3 -1] [-4 -1])
08:08ulfsterwohoo ;)
08:08licoresseulster: great stuff! :-)
08:08ulfsternow just zipmap that with the indexrange
08:09licoressethanks a lot
08:09ulfsterno prob
08:09ulfsterbut beware, just works because 1 and -1 are the only indices of the second coordinate
08:09licoresseyes, I see that
08:10ulfsteroh, and you need to invert y as well
08:10ulfsterit is switched now
08:11licoresseyup
08:24dkchi, vimclojure question
08:24dkcrepl works but "el" or similar give the following error: http://pastie.org/870161
08:24dkcthis is using "lein nailgun" to run the ngserver..
08:28sattvikdkc: Is the base directory of your clojure sources in your classpath? I don't know how 'lein nailgun' sets up your classpath.
08:29dkcyep .. it must be because the repl in vimclojure works fine, and i can run code directly in there
08:41licoresseseems real life is always more difficult :)
08:41licoresse,(let [r (filter #(not (= 0 %)) (range -4 5))] (concat (for [x r] [x -1]) (for [x (reverse r)] [x 1])))
08:41clojurebot([-4 -1] [-3 -1] [-2 -1] [-1 -1] [1 -1] [2 -1] [3 -1] [4 -1] [4 1] [3 1] [2 1] [1 1] [-1 1] [-2 1] [-3 1] [-4 1])
08:41licoresseulfster: ^
08:43licoresseit's still shorter than the list it's going to produce, guess that's a good thing
08:47chouser,(into {} (map #(vector %1 [%2 %3]) (iterate inc 1) (concat (range -4 5) (range 4 -5 -1)) (cycle [-1 1])))
08:47clojurebot{1 [-4 -1], 2 [-3 1], 3 [-2 -1], 4 [-1 1], 5 [0 -1], 6 [1 1], 7 [2 -1], 8 [3 1], 9 [4 -1], 10 [4 1], 11 [3 -1], 12 [2 1], 13 [1 -1], 14 [0 1], 15 [-1 -1], 16 [-2 1], 17 [-3 -1], 18 [-4 1]}
08:48licoressehehe, nice
08:48chouseroh, that's not quite what you want is it.
08:48licoresseno
08:48licoresse:)
08:48licoressehard to read those numbers
08:48sethssitting at the Clojure training session :-)
08:49chouseris it ok except for the second item of each vector?
08:49chouserseths: ooh!
08:49licoressechouser: it has to be excactly as my version
08:49chouserseths: when does it start?
08:49seths10 min
08:49sethsposting pic to twitter
08:51licoressechouser: yours goes through 0, mine does not
08:52ulfster,(for [y '(1 -1) x (range -4 5)] [(* x y) (* -1 y)])
08:52clojurebot([-4 -1] [-3 -1] [-2 -1] [-1 -1] [0 -1] [1 -1] [2 -1] [3 -1] [4 -1] [4 1] [3 1] [2 1] [1 1] [0 1] [-1 1] [-2 1] [-3 1] [-4 1])
08:52licoresseulfster: still the 0
08:52licoressethe problem is range
08:52ulfsteroh, now i see
08:52licoressethat's why I use the filter
08:53licoressebut just replace the range, and it's cool
08:53ulfster,(for [y '(1 -1) x (range -4 5) :when (not= 0 x)] [(* x y) (* -1 y)])
08:53clojurebot([-4 -1] [-3 -1] [-2 -1] [-1 -1] [1 -1] [2 -1] [3 -1] [4 -1] [4 1] [3 1] [2 1] [1 1] [-1 1] [-2 1] [-3 1] [-4 1])
08:54licoresseah, did'nt know you could :when....
08:54licoressehmm
08:54ulfsterthis should be the shortest ;)
08:54licoresseyeah, you win ulfster!
08:55licoresseamazing
08:55chouserseths: at the day-long tutorial in Boston alomst exactly a year ago, people were mostly also in here chatting in parallel to rhickey's presentation.
08:56chouserulfster: way to seek out a deeper pattern in the series!
08:58ulfsterchouser: more like blind luck + a little intuition :)
08:58sethschouser: any problems with me giving a live feed of sorts?
08:59chouserseths: heh, I don't see how my opinion matters. You're paying good money to be there, you should do what makes sense for you.
08:59sethsjust didn't want to spam the channel
08:59sethsfogus asked me via twitter for a live feed
08:59chouseroh, I see. I doubt people here would mind.
09:00fogusseths: I was just joking... but also would not complain to see one. ;-)
09:01sethsfogus: howzabout I put my comments into a lazy sequence, and you can just consume them as needed
09:02chouser:-)
09:02cemerickchouser: wow, that *was* a year ago. Yikes.
09:02chouserhm, but that's more of a work queue than a lazy seq.
09:03chousercemerick: :-/ yeah.
09:03fogus"If you need a work queue, then use a work queue" --chouser
09:04chouserheh, that sounds lame. from the book isn't it. :-P
09:04fogusI'm paraphrasing -- but I think that is in there somewhere
09:04chouseryeah, I think you're right.
09:05chouseroh well. I guess it's at least hard to refute.
09:05cemerickthat's a pretty fine line, no?
09:05chousercemerick: between a work queue and a lazy seq?
09:06dkcis there a way to figure out the cwd from a clojure repl?
09:06cemerickyeah. The latter is the former sometimes. It's all about how you use it, IOW.
09:06cemerickor, abuse it, perhaps
09:07chouserI think the main difference is that "consuming" a seq (that is, calling 'rest') doesn't change anything visible to anyone else -- others walking the same seq will see the same items
09:08chouserWhile consuming a work queue (.take or .pop or whatever...) is meant as an atomic operation such that other threads will never see that same item and instead get their own.
09:09fogusSeems to me that since that line is in the book, we pretty-much have to show an example at some point.
09:10chouseryou can indeed build a work queue out of a lazy seq plus a reference of some sort (agent? atom? cell?) but why when Java comes with perfectly good work queues already?
09:10cemerickchouser: Ah, sure. 'course, I just drop a (cons nil (some-lazy-seq)) into an atom, and then pound away at it with (first (swap! my-atom rest)) :-)
09:11chousercemerick: that's all fine until rhickey catches wind of it starts shooting mildly disapproving looks at you.
09:11chouser:-)
09:11cemerickchouser: because having a fn that returns a lazy seq is a lot easier than bothering with producers or "manually" pushing items into a queue.
09:11chouserfogus: yeah, I guess you're right.
09:11cemerickI'm happy to be shown how that's bad, but it seems too elegant to give up lightly.
09:12fogusOne of those images I sent to you should be accommodating to a work queue
09:12fogus(with some modification)
09:13cemerickbesides, the tagline under my name should be "getting mildly disapproving looks from rhickey since 2008" :-P
09:13chouserhehe
09:13foguscemerick: wear it like a badge of honor
09:13cemerickfogus: oh, I do :-D
09:14cemerickjust like I can reminisce about how there used to be < a dozen folks here
09:14cemerickThinking about it that way, it's pretty amazing how far things have come in just a couple years
09:15tomojis putting a PersistentQueue under an atom evil?
09:15cemericktomoj: encouraged, I'd say :-)
09:15tomojok
09:15chousertomoj: no, but do consider the features provided by java.util.concurrent.BlockingQueues and make sure that's not closer to what you want.
09:16tomojthat does look pretty cool
09:18cemerickchouser: see, the thing about the BlockingQueues for me is that .add is a pointless operation in a multi-node/multi-vm environment. e.g. the next item is whatever the idle node can grab next from the datastore, not what has been pre-emptively reserved for it locally.
09:21tomojwhat's a good way to represent a cursor into a cyclic linked-list ?
09:21mattreplthat's where having multithreads becomes a pain when fitting into the message/job queue paradigm that usually relies on multiple processes
09:21mattreplre: local queue
09:22chousercemerick: I'm wavering
09:23dkchi ... are there any vimclojure / lein-nailgun users around?
09:23chousera p-queue in an atom still doesn't feel quite right, because adding to the queue is a side-effecty thing, as is popping from it. If that's what you want, why not use a BlockingQueue and that hand blocking behavior?
09:23cemerickmattrepl: not sure I follow -- why are multiple threads an issue?
09:24chouseron the other hand, if your queue filler is more natural as a lazy seq ...indeed, why would you not drop that in an atom?
09:25cemerickchouser: yeah, that's the right balance. If I were in a single-process env, then a BQ would be the way to go.
09:25mattreplcemerick: I'm thinking from the standpoint of a system where there are multiple worker processes. you'd have some external queue (rabbitmq, beanstalk, gearman)
09:25chouseresp if you want the fill work fully delayed until the moment of consumption -- that work then actually being done by the consuming thread.
09:26cemerickmattrepl: yes. We're hoping for a queue abstraction to go with the sequence abstraction eventually. :-)
09:26cemerickmattrepl: feel free to take a crack at it, tho ;-)
09:26mattreplcemerick: if each worker process is really a pool of many worker threads then the threads will need to access the external queue. using a BlockingQueue or such inside the JVM process introduces an opportunity for error and losing jobs, etc
09:27cemerickmattrepl: right, which is why I don't use BQs
09:27mattreplcemerick: I have been. And I'm now getting back into Hadoop. =)
09:27cemericksorry :-P
09:28mattreplthe queue abstraction would be nice
09:30mattrepldoes it deal with multiple consumer processors? or any idea how one would use the queue abstraction in the manner?
09:31cemerickmattrepl: there is no queue abstraction yet. It's only been mentioned conceptually by rhickey AFAIK.
09:32mattreplcemerick: right, sorry. I meant if that was within its scope. wasn't sure if someone had begun fleshing it out
09:32cemerickno idea
09:32cemericknot AFAIK
09:47djpowelldkc: (.getAbsolutePath (java.io.File. ".")) - works for me
09:48dkcdjpowell: thanks :)
09:48djpowellor maybe: (.getCanonicalPath (java.io.File. "."))
09:49dkcdjpowell: i wound up using (sh "pwd") after importing the shell libs
10:03psykotichas anyone played with clojure/compojure on google appengine, had an app work fine with the local devserver, but get a class-not-found server when it was deployed to appengine?
10:04psykoticserver error, even
10:14chouserok, it just struck me how deeply wrong it is that in normal OOP all the methods live in the same namespace.
10:15chouserI mean, I know this is something rhickey already identified and Clojure already solves, but I just now connected that to a kind of ugliness I've been seeing lately.
10:15foguschouser: care to elaborate?
10:15psykoticwhat kind of ugliness?
10:15psykotici admit that aspect of oo has never been a problem for me
10:16chouserany time that you want to combine groups of methods from two different sources
10:16psykoticwell, that's prevented at a more fundamental level by most OO languages, unless you are talking about insane ruby-style monkeypatching
10:17Licenser_if I try to make a nice and clean namespace concept I always seem to run into circle issues
10:17chouserfor example, a remote object stub or proxy that has methods defined by some IDL but also some common API methods provided by the framework
10:18chouseryou end up with one group or the other getting ugly method prefixes or something -- always feels like a hack.
10:18foguschouser: Isn't the class itself a sort-of namespace?
10:19psykoticchouser: but you have the same problem here if you wanted to merge two namespaces' worth of generic functions into a single one
10:19chouseror if you're implementing interfaces from two different libs, maybe most of the time you're lucky that the method names don't clash, but if they *do*, then what?
10:19chouserpsykotic: but why would you do that?
10:19psykotici might as well ask why you'd use inheritance in your example
10:19chouserin clojure you can have a single object respond to both your-namespace/doathing and my-namespace/doathing
10:20psykoticsure
10:21psykoticand you can use proxies/adapters to get a similar level of explicitness
10:21psykoticnot that i think that's nice or anything. i hate most of what passes for oo at a funamental level.
10:21chouserpsykotic: I could provide a number of examples. :-) How about trying to build a single object that can be stored by some persistence lib over here, and also be sent across the wire by some rpc lib over there -- both want me to define "getId", but one wants a string and the other a byte array.
10:22psykoticlike i said, a solution is always to use adapters, which is explicit
10:23psykotici.e. you call persistentAdapter() or whatever and it returns an instance of that persistence interface for your object
10:23psykoticnot pretty but hey :)
10:23chouserpsykotic: sure, or for each lib to use a unique method name "persist_getId" vs "rpc_getId". Exactly, not pretty.
10:23chousernobody's arguing Java's not Turing complete. :-)
10:24chouserBut Clojure's solution is so clean. No adapters, no extra allocations, nothing required of either lib that they wouldn't already do naturally.
10:25sparievhow could I access POST request body in Compojure ? There is :body stream in request map, but it looks like it is empty
10:25chouserfogus: yes, a class acts as a namespace. But that's kind of the problem -- I want to merge two namespace only because the class is *also* used to identify the methods an object implements.
10:26noidichouser, that reminds me of http://threebrothers.org/brendan/blog/death-by-duck-typing/
10:26chouserfogus: Clojure's namespaces are just namespaces, so there's no need to merge them. For implementing functions on types, you can use multimethods or protocols.
10:28sparievIs that true that input stream from ServletRequest (accessed via getReader or getInputStream) could be read only once ?
10:28noiditl;dr version: when the duck typed object's methods have the names you expect but different semantics, you get in trouble
10:28cemerickspariev: given the servlet spec, yes
10:28noidiclojure sidesteps that problem nicely
10:29psykoticchouser: generic functions are definitely awesome. i only wish clojure core wasn't so shy about them :)
10:29psykoticbut i guess you can actually rebind the vars if you want to offer something more generic
10:29psykotic(for arithmetic say)
10:29foguschouser: I understand. I suppose that my typical way to handle your original scenario has been some sort of delegate/proxy... lots of infrastructure.
10:30sparievcemerick: thanks, I couldn't remember that. so it looks like my problem is Compojure reads body before I access it
10:30chouserpsykotic: that'll change some. multimethods were "too slow", but protocols will be used more heavily by core.
10:30chousernoidi: yeah, interesting.
10:30cemerickspariev: compojure doesn't do much of anything by default. If you're using some middleware (like the file upload middleware), then yes, that will read the body before you get the request.
10:31chouseractually, Clojure side-steps that with constant vigilance, not through anything automatic.
10:32chouserthat article's actually an argument for not having a single function that does both (some #{k} coll) and (contains? coll k)
10:32cemerickspariev: actually, I'll bet it does always read the body on at least most POSTs in order to parse params
10:35sparievcemerick: yep, I found it in the sources. There is should be a way to declare routes without params parsing
10:37noidichouser, also, namespace prefixes become a sort-of hungarian notation that might also help a bit
10:37noidii.e. (bar/do-something (foo/update my-foo)) looks wrong
10:38chousersorry, what's wrong with that?
10:38sparievoops, should have searched compojure group first - The (request :body) input stream only gets consumed if the content
10:38sparievtype is "application/x-www-form-urlencoded"
10:42noidichouser, ok, bad example :) if functions dealing with a data structure are in a namespace named after it, and they take the structure as their first argument, (document/print (person/set-age bob 42)) looks wrong because document/print expects a document but gets a person
10:42chouserah. hm.
10:43noidimaybe that's too OO-like for clojure code, but that's what I've been doing
10:44chouserI don't know that that looks wrong. To the extent that it does, perhaps "document" is mis-named.
10:46sethsfrom Rich's talk. Clojure is (overstrike) was a solo effort
10:49noidion a related note, is it considered good style to have abstract data that is treated as a black box outside its accessor functions?
10:50stuarthallowaynoidi: less often than most languages would suggest
10:50noidicurrently I do that, but extract as many generic helpers operating on collections from the "abstraction code" as possible
10:51noidiI'm still having trouble adjusting to non-OO programming, but so far this style seems to hit the sweet spot between narrow interfaces and many functions operating on few data types
10:52psykoticstuarthalloway: i saw the infoq interview. you were great but that interviewer... :)
10:52noidiI agree, great interview!
10:53stuarthallowaythanks!
10:54psykoticstuarthalloway: were you there to give a talk?
10:54noidibut yeah, every time I try to write code with non-encapsulated domain data structures, I always get the nagging feeling that I won't be able to change the representation later without breaking all the clients
10:54stuarthallowaypsykotic: yeah, and that is supposed to get posted online too
10:54stuarthallowayit was a talk about experience with clojure in production, I think lots of people would be interested
10:55psykoticcool
10:55noidiif someone can suggest something like the SOLID principles of OO but for functional programming, I'd love to read it :)
10:55stuarthallowayI am going to reprise it at the end of the pragmaticstudio this Wed
10:55iceystuarthalloway: during the studio or at the talk over at oracle?
10:55fogusstuarthalloway: Looking forward to that talk
10:55stuarthallowayicey: hmm, good question, how about both? :-)
10:55stuarthallowayhaven't really decided what to talk about at oracle
10:55iceystuarthalloway: I would love it during the stuio :D
10:56iceys/stuio studio
10:56stuarthallowayif you know someone at infoq you could ask them when they plan to post it
10:58chouserstuarthalloway: tea-break at the pragmaticstudio?
10:58stuarthallowaychouser: nah, just ignoring rich talk
10:58stuarthalloway:-)
10:59stuarthallowayI have "continuous partial attention disorder"
10:59chouserheh
10:59stuarthallowayrich is doing a cool job of interleaving fun nuggets of detail in the overview talk
11:00fogushas he mentioned Whitehead yet?
11:00stuarthallowaykeeping it interesting for people who already know clojure while bringing the beginners up to speed
11:00stuarthallowayfogus: that's tomorrow
11:00fogussweet
11:02tjg,(= 0.8M 8/10)
11:02clojurebotfalse
11:02tjg,(= 0.9M 9/10)
11:02clojurebottrue
11:03rysmmm, floating point
11:03tjgIs that supposed to happen?
11:04tjgI thought that ratios and bigdecimals were somehow "exact".
11:05zmilainteresting, our company has survey on what trainings the employe want: what languages/technologies are interesting. From about 300 answers there are 4 interested in FPL (scala,haskell,clojure,scheme).
11:05tjgI kinda thought it was just my b0rken Clojure build, or something. ;)
11:05noidican anyone recommend some good, open source clojure _application_ code to study? I'd like to see how others deal with domain data instead of generic things like the built-in collections.
11:05stuarthallowayzmila: what were the most requested?
11:06stuarthallowaynoidi: the current dev edge of compojure
11:06noidistuarthalloway, thanks
11:07zmilathere were questions for junior and senior developers: what direction they want to progress. the most are the languages, used in our company production: c# and java. but i was pleased that 4 people are familiar with names clojure/scala
11:08tjgAh, no, sorry, didn't read BigDecimal's javadocs...
11:12stuarthallowaynoidi: here is a fun one-off example: http://github.com/relevance/labrepl/blob/master/src/solutions/rock_paper_scissors.clj
11:14noidistuarthalloway, thank you!
11:22noidithe main reasons why I encapsulate my domain data are that: 1) often updating one piece of data requires that others are updated so the object remains valid, 2) I want to be able to change my data's representation without breaking its users
11:23stuarthallowaynoidi: still valid ideas in clojure, but...
11:23stuarthalloway(1) you could tie validations to identities (reference types) instead of data itself
11:23stuarthalloway(2) you could allow multiple representations and provide transformation functions
11:24chouseris data encapsulation in direct conflict with solving the expression problem?
11:24noidichouser, expression problem?
11:24stuarthalloway(3) as soon as you persist or go out of process you make a long run commitment to the data as a contract
11:25chousergetting libraries from providers A and B to work with your code while avoiding endless adapters, conversions, etc.
11:25chouserI'm sure that's a bad definition of the expression problem, but that's the right general space.
11:26stuarthallowaychouser: I expect to see a better definition in an advanced clojure book someday :-)
11:26chouser:-P
11:27noidistuarthalloway, regarding (3), in an encapsulated version only the import/export code needs to know how to deal with many versions of the data structure
11:27noidiwhereas without encapsulation the whole program needs to be prepared to take an older version and convert on the fly if needed
11:28stuarthallowaynoidi: but what about multiple processes, in multiple languages
11:28stuarthallowayI would rather get data from your program as json and convert it to a shape I want
11:28stuarthallowaythan have your provide import/export code in my language
11:28noidiah, now I see your point
11:30noidiwhich implies that instead of OO API's, I should look at how data-oriented APIs like REST APIs work
11:30patrkrishow would I go about setting a property for the JVM when invoking lein? Specifically, I need to use the -D switch for java to set UTF8 encoding
11:31noidistuarthalloway, thanks for the great idea -- now I have to go cook dinner, but after that I'll read a bit about web service architecture, maybe that'll lead me to the path to enlightenment :)
11:33stuarthallowaynoidi: please it up if you find it :-)
11:33noidiI'm starting to sound like scratched record, but I think Clojure would really benefit from a resource like http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
11:33stuarthalloway...please [write] it up ...
11:33dnolenpatrkris: the lein shell script looks for a shell environment variable JAVA_OPTS
11:34patrkrisdnolen: thanks!
11:34noidistuarthalloway, hehe, I will :)
11:34stuarthallowaynoidi: we are slowly convincing Uncle Bob to love clojure, maybe he'll do it
11:49chouserhm... I want something like a multimethod, but the bodies need to be macro expansions. ...but dispatch has to happen at runtime.
11:53hiredmanwhy not a multimethod?
11:54foguschouser: Can you instead use multimethods as your macro aux functions?
11:56chouseryes, and I think that will be sufficient, but I think it will defeat potential call-site caching
11:57chouser(defmethod xget* "foo" [x] (:foo x)) (defmacro xget [x] `(xget* ~x))
11:58chouserif the value of x there can be of different types, the call-site caching in xget* would be defeated
12:00fogusSeems like a natural fit for mms... that's too bad.
12:00chouserwhile if the macro were (defmacro xget [x] `(condp = (xtype ~x) "foo" (:foo ~x) ...)), I would get keep call-site caching but would lose multimethod openness
12:01chouserwhich suggests (defmethod xget* "foo" [x] `(foo: ~x)) ...but then how do I define xget? I guess I could build a condp from (methods xget*)
12:08ordnungswidrigre
13:07headiustechnomancy: twbray mentioned ohai in his google blog post
13:09technomancyheadius: yeah, I'm excited to see what he does there
13:09technomancydefinitely a good thing for polyglot android!
13:09headiushe seems pretty excited about duby lately
13:09headiusand we've added a lot since ohai
13:10technomancyyeah, I've been meaning to dive back in, but I'm still way behind on pull requests for swank-clojure and leiningen
13:21sethsgeez, Rich is giving a really great introduction to the reader
13:23iceyhaha reading through clojure core is "an interesting journey"
13:30remleduffseths: What were you referring to when you said Rich is giving a really great introduction to the reader?
13:30nteonseths: where is that happening?
13:30nteonheh
13:32technomancyhttp://pragmaticstudio.com/clojure <= probably here
13:32iceytechnomancy: aye that's it
13:35remleduffAh yes, I was just short the 1000 bucks to attend that ;)
13:42sethsyes, it's only been a few hours but I already highly, highly recommend this course
13:44nteonseths: did you have experience with clojure before this?
13:46sethsnteon: yes, many months of playing with it. nothing really serious.
13:46sethsbut that has made this training much more immediately absorbable
13:46nteonseths: cool. just wondering
13:47iceynteon: they started with a pretty basic level of discussion and then ramped up the detail fairly quickly
13:47fogusseths: Are there many questions, or mostly lecturing?
13:48sethsfogus: @goodmike said it well that it was like the blip.tv videos, turbocharged
13:48sethsquestions have been sporadic but at a variety of levels
13:49fogusseths & icey: Are there a high ratio of blown-minds?
13:50chousera lot of rhickey's blip.tv stuff is getting a bit dated now
13:50sethsfogus: not sure, the room doesn't feel uncomfortable
13:50sethsnewbies are asking some questions, and I see people around me tinkering with the repl
13:51sethsfogus: but the labs have started and I need to get busy :-)
13:51technomancydon't forget your lab coat
13:51fogusseths: enjoy!
13:53nteongoggles are important too
14:13Licensergeetings my lispy friends!
14:14esjsalute
14:19vyFor those about to lisp, I salute you!
14:21Licenser:)
14:26seths,10r3
14:26clojurebot3
14:26sethszomg
14:26seths,10r16
14:26clojurebot16
14:26chouserheh
14:30seths,#(%&)
14:30clojurebot#<sandbox$eval__6295$fn__6297 sandbox$eval__6295$fn__6297@25951f>
14:31chouser,36rXYZ
14:31clojurebot44027
14:33fogus,(#(apply (first %&) (rest %&)) + 1 2 3 4 5)
14:33clojurebot15
14:33hiredman:(
14:33chouserwhoa. you just wrote a clojure interpreter
14:33hiredmanapply using apply
14:34fogusYou can write a Clojure interpreter in exactly 1 line of code
14:34fogus:p
14:34sethseval
14:35rhickey_%& ?
14:35sethsI started the nonsense with
14:35seths,#(%&)
14:35clojurebot#<sandbox$eval__6309$fn__6311 sandbox$eval__6309$fn__6311@4bfba>
14:35chouserI guess to be a useful claim, you'd have to specify which parts of clojure you're not allowed to use in your clojure interpreter
14:36sethsand then fogus said:
14:36seths,(#(apply (first %&) (rest %&)) + 1 2 3 4 5)
14:36clojurebot15
14:36fogusGeneral IRC silliness
14:36rhickey_fun
14:37brian__Hi, does anyone know if/how stuart sierra's hadoop-clojure integrates with apache mahout? Thanks
14:52chouser,(reify clojure.lang.IMeta (meta [] {:my :meta}))
14:52clojurebotjava.lang.Exception: Unable to resolve symbol: reify in this context
14:52chouserHm, I get: java.lang.ClassFormatError: Duplicate method name&signature in class file user$eval$reify__738
14:57hiredmanchouser: maybe reify self mixes in IObj?
14:58hiredmanor, I should say, an implementation of same
14:58hiredmanhmm
15:00chouseryeah, (.meta (reify)) doesn't crash
15:01hiredmanhuh
15:02radsI put (with-ns 'leiningen.snapshot (defn snapshot [project & args] ...)) in my project.clj, but when I try to run lein snapshot I get a no namespace found error
15:02radsam I doing it wrong?
15:02chouserwith-ns is a little scary
15:03hiredmanrads: use create-ns
15:03hiredmanchouser: (supers (reify)) just says Object though
15:04chouseroh, my. (show (class (reify))) shows a lot though
15:04radsis there a better way to create leiningen tasks?
15:05chouser(.meta (.withMeta (reify) {:no :way!}))
15:05technomancyrads: I think it's actually best not to use with-ns but just to use ns
15:06radstechnomancy: so I'd put each task in a separate file in src/leiningen?
15:07technomancyrads: no, you can use ns inline in project.clj. it's a bit unorthodox, but it works for short tasks. for longer more involved tasks you should use a separate file.
15:07technomancyif you do it in project.clj just be sure to switch back to the user ns afterwards or it won't be able to find defproject
15:07hiredmantechnomancy: I would use in-ns over the ns macro in that case
15:08chouserbut with in-ns you don't get any of clojure.core
15:08technomancyyeah, in-ns means you have to refer manually
15:15radshmm, the classpath isn't set in project.clj, but I have to use some functions from my project in my task. I tried moving the task to a separate file, but leiningen doesn't seem to recognize the task
15:16chouserbleh. dep management may be worse now than before.
15:17chouserI had clojure, contrib, and ring all integrated into a non-java-centric build system, with ant being to only extra requirement. Now it looks like I need ant, lein, and maven.
15:19drewrchouser: I had the same reaction
15:20chouserdoes lein work on Mac?
15:20drewrdoes for me
15:20radsyeah, I'm on a mac too
15:20chouserok. hopefully it will for our Mac-based devs.
15:22danlarkinthe sooner you embrace the separate environments for each project the better off you'll be :)
15:22drewrdanlarkin: already had that :-)
15:23drewrbut my team moved to lein and I submitted
15:24radsany idea on how to use my project code in lein tasks? it seems the classpath isn't set within the project.clj file
15:24danlarkinI don't indent to flame, but I just don't see what the disadvantages are to everyone having a sane build system
15:24technomancychouser: why are you building those deps yourself? can't you just get stuff from build.clojure.org/clojars?
15:25danlarkins/indent/intend
15:25danlarkinwe can see my mind's still on code :)
15:27technomancyoh, except you're probably working on changes to clojure itself that you want to have available without making public first, right
15:27technomancyedge case! =)
15:28danlarkinsymlinks might be sufficient for that case
15:29technomancyyou'd still need ant installed
15:35remledufftechnomancy: Do you think it would be feasible to make the shell script/bat file simpler by taking a strategy of "just try to get to clojure ASAP and do all the logic in clojure?"
15:44chouserhm... no, I don't need a custom-patched clojure, just something with refiy, defprotocol, etc.
15:45chouserreify
15:45hiredmanchouser: lein can grab that from build.clojure.org
15:45chousercan I name specific non-release versions of clojure or contrib?
15:46hiredmanhmmm
15:46arohnerchouser: I've started building snapshots, and set their version number to the git SHA1
15:47chouseractually, I may not need that.
15:47hiredmanI don't know
15:47chouserarohner: on build.clojure.org?
15:47arohnerchouser: I upload them to clojars
15:47chouserah
15:47drewrarohner: I do something similar, although I shorten the digest and put the timestamp first for sortability
15:47arohner[org.clojars.arohner/compojure "40083894d100d89347dad9748110fe06b9aab323"]
15:47cemerickchouser: yes, you can fix a maven dependency version to a particular snapshot
15:49drewrmy zsh fn to do that: http://gist.github.com/333247
16:28chousercan I configure lein to use a different local repository directory?
16:29ChousukeI think there's an environment variable or something
16:30chouserHm. $HOME :-/
16:30Chousuke... or you get to write an XML configuration file ;P
16:31Chousukehttp://maven.apache.org/settings.html
16:31chouserit still installs itself in to $HOME/.m2/...
16:32technomancyremleduff: I have tried to take that strategy, but things accumulate over time, and it's not always obvious _why_ some stuff is implemented in .sh. If you've got some specific ideas of things that could be moved that'd be great.
16:32remleduffI'm most curious about the repl task, would it work as a plugin using "eval-in-project"?
16:33chousercan I tell lein to operate on a project in a different directory?
16:33chouseror must I cd there first?
16:34technomancyremleduff: there are issues with *in* and *out* not getting bound correctly from an eval-in-project call. it's probably possible, but I haven't had the time to investigate.
16:34technomancyremleduff: if you have a chance to look at the problem that would be awesome.
16:35technomancychouser: currently you need to cd there first, but we could add a way of specifying a non-cwd project root
16:35chouserI can probably work around it
16:39remleduffNo promises, but I'll try to take a look :)
16:40technomancyremleduff: I think that might be more of a messy ant API issue than anything clojure-specific unfortunately
16:40chouser"lein deps" in ring seems to fetch a lot of SNAPSHOT libs. I assume that if others run this same command at a later date, they may get different versions of these libs?
16:41technomancyyeah, it's generally discouraged to add snapshot deps to stable releases unless you absolutely must
16:41technomancythat's one of the things stuart H complained about; maintainers not pushing out actual releases often enough
16:41technomancychouser: you can lock to specific versions though
16:42chouserok, it's not as many as I thought. I saw org.clojure:clojure:1.1.0-master-SNAPSHOT go by, but it looks like 1.1.0 is explicitly named in the project.clj
17:04LauJensenEvening gents
17:05dakroneEvenin' Lau
17:17neotykevening Lau
18:33crowbar7Good evening
18:56dysingerhey rberger :) I heard you guys got funded - congrats
19:01dysingerrhickey: I need an invoice for feb - did you send me one ? I don't have it.
19:13crowbar7Who got funded?
19:13crowbar7dysinger: Don't you work for a company that uses clojure?
19:53etateello people
19:57Fossihi etate
19:57crowbar7Hello
23:04rfgAnyone played with clojure + jogl on Windows (7)? I'm getting inconsistent results.
23:06crowbar7nope
23:06crowbar7i'm a bag of help
23:07rfgThis is quite frustrating :)
23:37crowbar7this place is sure a ghost town right now.
23:38rfgOne problem is that when I launch my JOGL window from the repl it's fine initially, but if I close that window and relaunch from repl the rendering is all messed up. Anyone care to guess at any possible reasons why?
23:38dnolencrowbar7: heh it often gets like that. other times a deluge.
23:38crowbar7yeah, so it seems.
23:39dnolenrfg: have you looked at Penumbra, might save yourself some headaches.
23:39dnolenhaven't tried it on Windows, but it works great on Ubuntu and OS X
23:39crowbar7I mean it's not some social channel, but some life is nice here and there.
23:41rfgdnolen, the latest versions of penumbra use LWJGL instead of JOGL. LWJGL has some issues that mean I'm leaning towards JOGL. I'll see if I can grab an old JOGL version of penumbra from github.
23:41replaca_dnolen: I like the enlive tutorial! Wish I'd had it when I was writing autodoc :-)
23:43dnolenreplaca_: thanks! Happy at response it's been getting. cgrand's Enlive has a crazy punch for only 800 LOC!
23:43dnolenrfg: what issues do you have with LWJGL over JOGL?
23:44technomancydnolen: wow, only 800 LOC? nice.
23:45technomancynote to self: write a loc task plugin for lein
23:45rfgWell, and this may be due purely to my ignorance, I can't seem to set arbitrary sized windows, nor can I get a resizable window.
23:46technomancy(or note to anyone who's listening and is looking for a simple project that would be useful to contribute to)
23:46dnolenrfg: definitely in there, just a problem of documentation
23:47dnolenrfg: you should look at this, http://github.com/swannodette/clj-nehe. As far a resizeable windows you should bring that up on the Penumbra ML, I haven't looked into that myself. but it must be there since there's "reshape".
23:48rfgdnolen,
23:48rfgTwo seconds.
23:53crowbar7So, as soon as I did (doto (Thread. #(func arg)) (.start)) the first time in Clojure I pretty much became super fanboy because it made threading painless.
23:53arohnercrowbar7: it gets even easier
23:54crowbar7arohner: as I found
23:54hiredmanpffft
23:54hiredmanjust use future
23:54rfgdnolen, any idea if you can mix lwjgl and swing/awt components?
23:55technomancy_atooooooooooooooooo!
23:55technomancywhere are you?
23:55crowbar7I really hope this language takes off because I could program in this for the rest of my life at a job at this point.
23:56dnolenrfg: haven't gotten that far. but that's come up recently on the Penumbra ML, the overtone guys want to use it.
23:56technomancycrowbar7: the rest of your life is a long time (hopefully)... don't go overboard. =)
23:56crowbar7technomancy: good point
23:58crowbar7jobs seem to be quite scarce in the clojure depaprtment.
23:58rfgdnolen, cheers, found it.
23:58crowbar7department*
23:58rfgcrowbar7, just get a java job and don't tell them what you're really using. They'll be amazed at your productivity. :)
23:59lancepantzcrowbar7: i used to think the same about ruby re: rest of life thing
23:59lancepantznow it annoys the hell out of me
23:59lancepantzsince i started doing clojure
23:59dnolencrowbar7: tho perhaps better than it was for Ruby in oh, I dunno 1998 ;)
23:59dnolenrfg: np