#clojure logs

2011-02-11

00:09TimMc,(update-in {:foo 5} [] identity)
00:09clojurebot{nil nil, :foo 5}
00:09TimMcThat's annoying.
00:10TimMcShouldn't update-in pass the whole collection in to the function in that case?
00:10TimMc(I see why it *doesn't*, reading the source, but I'm wondering if there's a good reason for it.)
00:13rata_TimMc: why should it do that?
00:14amalloyTimMc: update-in is effectively (assoc m (some-magic-stuff))
00:14TimMcrata_: 1) Consistency, 2) it would be damn useful in my code. :-P
00:17rata_TimMc: but normally the function you pass to update-in is expecting a value, not a map
00:17amalloyTimMc: how would your behavior be any more consistent?
00:18TimMcrata_: The value could be a map.
00:18TimMcamalloy: Because ##(update-in {:foo 5} [:foo] identity) gives you back the thing unchanged.
00:18sexpbot⟹ {:foo 5}
00:18rata_yes, but a "value-map", not the whole map containing that map
00:19TimMcrata_: What's the difference? update-in can handle 1+ levels.
00:19TimMcI just think it should also handle 0 gracefully. :-)
00:19rata_TimMc: but not the top level
00:20amalloyTimMc: get back to us when you've gotten division to handle 0 gracefully too
00:21rata_what update-in is interpreting there is that you want the nil key to be modified, because you gave it the nil key implicitly in []
00:24rata_I see your point now... you want that to mean "no go any deeper, stay here at the top level of the map"
00:25rata_s/no /don't /
00:25sexpbot<rata_> I see your point now... you want that to mean "don't go any deeper, stay here at the top level of the map"
00:28tomojI found a good source of random names for projects
00:29tomojI have a bunch of empty lein shells sitting around, and no clue what they were going to be or how I came up with their names
00:31amalloy&(take 5 (repeatedly (partial apply str "cloj" (repeatedly #(char (rand-int 0xff))))))
00:31sexpbotExecution Timed Out!
00:31amalloyhm. i guess not, huh?
00:31amalloyoh heh
00:32amalloy&(repeatedly 5 (partial apply str "cloj" (repeatedly 8 #(char (rand-int 0xff)))))
00:32sexpbot⟹ ("clojÜ7OtÁt" "clojÜ7OtÁt" "clojÜ7OtÁt" "clojÜ7OtÁt" "clojÜ7OtÁt")
00:32amalloyman, that didn't work at all. but tomoj, that's a good source of names if you get it right :P
00:34tomojI saw "compojure" is now allowed by lein
00:35tomojthe issue I think suggested getting rid of the restriction with "compojure" as an example, so "compojure" was special cased :)
00:36tomojbut there are so many terribly punny names it still allows
00:36tomojs/still//
00:36sexpbot<tomoj> but there are so many terribly punny names it allows
00:38tomojI think I'm just going to stop using sed style altogether
00:39amalloytomoj: it wouldn't be too hard to add a "don't sed these users" list if it bugs you
00:41TimMcrata_: Exactly, I just want it to do nothing when there's nothing to do. :-P
00:42tomojI should be able to remember to use different delimiters, and it shouldn't bug me anyway
00:42_msttime for a delimiter-changing erc extension? :)
00:42rata_TimMc: no, when you say it so, it doesn't make sense to me
00:43TimMchah, OK
00:43TimMcBut yes, "don't go any deeper" is what I mean.
00:48rata_TimMc: you could easily do a wrapper fn around update-in like (defn my-update-in [m ks f args] (if (empty? ks) (apply f m args) (apply update-in m ks f args))
00:48TimMcI'll probably do that.
00:49rata_sorry, I missed a & before args
00:49ossarehwoo @ wine and code.
00:49dnolenTimMc: but you have to ask yourself, why would you pass an empty seq of keys to update-in ?
00:49dnolen(empty? ks) is less idiomatic than (seq ks)
00:49TimMcdnolen: I already have a need for that in my code.
00:50dnolenTimMc: why would want to propagate empty seqs around. Why do you need that?
00:51TimMcdnolen: I have a function that takes in another function that can change the state of the userdata, and also the level at which it knows how to change it.
00:52TimMcSome functions operate on the entire state, some on just pieces of it.
00:52TimMcupdate-in would be a *perfect* call to make if not for that flaw.
00:53dnolenTimMc: only if you think letting empty seq float around through your code instead of filtering them out seems useful.
00:54TimMcdnolen: [] is a perfectly valid selector. It's not floating around, it is being used in this one corner of the program.
00:54rata_dnolen: I prefer empty?, it's clearer... and it's the schemer way at the same time =P anyway, seq is not more idiomatic than empty?, but more than (comp not empty?)
00:55dnolenrata_: Clojure isn't Scheme.
00:55rata_dnolen: that's not the point, just a joke
00:56rata_the point is seq is not more idiomatic than empty?
00:56dnolenTimMc: sure, I'm just saying you're ok with running an operation that doesn't do anything, when really you could just filter it out.
00:56dnolenrata_: it's come up before, seq as far I can tell is considered more idiomatic.
00:57rata_I have been here for those discussion as well, and it's not
00:58TimMcdnolen: I'd prefer to have consistent behavior in a library function than to add a conditional in my own code.
00:59rata_doing (empty? ...) is idiomatic, doing (not (empty? ...)) is not
01:01dnolenrata_: ah yes, it depends on how you do you branch, I tend to do (if (seq x) ...)
01:02rata_yes =) for me it depends on which case comes first to my mind, the empty or non-empty case
01:10amalloytomoj: sexpbot should refuse to sed you now
01:11tomoj:O
01:11amalloytryyyyy it plz
01:11tomojs/:O/thanks/
01:11amalloycoolio
01:11amalloys/o/q
01:11sexpbot<amalloy> cqqliq
01:11tomojit's not a hardcoded list, is it?
01:11amalloytomoj: it's in the config file
01:12amalloy:dont-sed #{"tomoj" "hiredman"}
01:13amalloywas like a two-minute fix, plus fifteen minutes of trying to find a bug that wasn't there because i was testing wrong
01:15tomojI'll buy you a beer at the next mutual clojureconj :)
01:16amalloydeal
01:16amalloyhardcoded list, indeed. i'm insulted :)
01:17brehautamalloy: at least its a hardcoded set rather than a list
01:18amalloybrehaut: config file! if you're suggesting i should let users opt-out without asking a sexpbot admin, then...well, i invite you to fork sexpbot :P
01:18brehauthaha
01:19brehautim fine; have enough unfinished code on my plate ;)
01:19amalloy(the gauntlet is down)
01:20Raynestomoj: I am convinced that some people are born with a gene that causes them to have an involuntary and negative reaction to a bot doing something that they didn't actively want it to do. Thus, it is impossible to satisfy everybody with stuff like s/// replacements and title scraping.
01:21RaynesBut, because of that gene, you are forgiven. amalloy and I <3 you.
01:21RaynesEspecially amalloy. :>
01:21amalloyRaynes: actually, having a config area for user preferences is an interesting idea
01:21amalloybut i guess he can only really control who he responds to, not who hears him
01:22Raynesamalloy: Actually, having decent and consistent configuration in general would be a nice idea.
01:22RaynesSomething I'm still thinking about.
01:22RaynesAnyways, back to fringe.
01:25brehautwhat you should do is create a custom filesystem like database, and let plugins stash things wherever they want, optimally with random UUID keys
01:26amalloybrehaut: you laugh, but sexpbot is running on top of mongodb
01:26brehautahahaha :(
01:27amalloyyou don't approve?
01:27brehauti actually have no opinion on mongo
01:28brehautive only heard the hype and horror stories
01:29amalloybrehaut: it's okay
01:29amalloynothing special, but perfectly usable
01:30brehautand as a bonus, its web scale!
01:30amalloyi certainly had a much easier time getting the hang of mongodb than cassandra, probably because it's more like sql
01:31brehauti dabbled with couchdb
01:31amalloythat one scares me
01:31brehautyeah im… ambivilent about it
01:31amalloybut hey, couchbase should be available soon, or something like that
01:31tomojI miss the mapreduce looking at cassandra
01:32amalloytomoj: what do you mean, miss it?
01:32brehauthowever futon, couch's webbased admin interface, is pretty nice
01:33tomojamalloy: coming from couchdb
01:34amalloyoh. i piled hadoop on top of it for m/r
01:34amalloydidn't really know anything about couch at the time, and maybe it would have been a better choice
01:36tomojmaybe I just haven't wrapped my head around hadoop yet
01:36brehautim going to head off. night everyone
01:37tomojI feel like there are neat things couch's mapreduce does well that are hard in hadoop, but I can't think of a single example
01:37amalloyi doubt you are wrong
01:37amalloyeverything is hard in hadoop
01:38tomojwere you using clojure with this too?
01:38amalloyno
01:38tomojshucks
01:38amalloyyeah, the clojure libs i looked at didn't look very good at the time
01:38tomojI haven't liked clojure-hadoop at all
01:39tomojbut I think part of the problem is just the way I use it, and part is just that it's still hadoop, after all
05:08TobiasRaedermorning
05:24ejacksonyo
05:43carkhHello
05:44carkhDid anyone manage to set gzip compression for jetty using compojure ?
05:50xkbhi
05:51xkbwhich lib should I use for OAuth? Clojars shows quite alot of em
05:52ejacksonxkb: I'd go with mattrepl's version
05:52ejacksoni think its the original
05:53xkbOk, ill tinker around with it
05:54ejacksoncool
06:40bartjah, bitten by this:
06:40bartj, (flatten #{1 2 3 4 5})
06:40clojurebot()
06:40bartjwhat gives ?
06:44ejacksonbartj: i don't think set is a sequential thing ?
06:44ejackson,(flatten (seq (#{1 2 3 4 5}))
06:44clojurebotEOF while reading
06:45ejacksonbah
06:45ejackson,(flatten (seq #{1 2 3 4 5}))
06:45clojurebot(1 2 3 4 5)
06:45bartj,(flatten (seq #{1 2 3 4 5}))
06:45clojurebot(1 2 3 4 5)
06:45ejacksonyeah.
06:50bartjejackson, is there any way I can check if something has multiple values ?
06:50ejacksonis a composite value ?
06:50bartjfor eg: "abc" is a single value and '(1 2 3) are multiple values and so is [1 2 3]
06:50bartjI was hoping to do a (seq? ) and check it
06:51mrBliss`bartj: sequential?
06:51ejacksonyeah, as good as a say
06:51bartjI also have the type #{1 2 3}
06:51bartjwhich for all practical purposes are multiple values
06:51bartj, (sequential? #{1 2 3})
06:52clojurebotfalse
06:54bartjanyone ?
06:55mrBliss`,(map (partial instance? java.util.Collection) (list '(1) [1] #{1} {1}))
06:55clojurebot1
06:55solar_seawhat's the best way to create a list/vector of n items ?
06:55mrBliss`#(map (partial instance? java.util.Collection) (list '(1) [1] #{1} {1}))
06:55mrBliss`&(map (partial instance? java.util.Collection) (list '(1) [1] #{1} {1}))
06:55sexpbotjava.lang.ArrayIndexOutOfBoundsException: 1
06:55bartjsolar_sea, vector
06:55bartj,(vector 1 2 3 4 5)
06:55clojurebot[1 2 3 4 5]
06:55solar_seaI currently use loop, recur and conj, but this doesn't seem right
06:56solar_seaoh well, n is defined later :)
06:56mrBliss`solar_sea: repeat
06:56bartj; (vec (range 1 n))
06:56bartj, (vec (range 20))
06:57clojurebot[0 1 2 3 4 5 6 7 8 9 ...]
06:57mrBliss`,(repeat 5 'x)
06:57clojurebot(x x x x x)
06:57solar_seaah, repeat does the job fine, thanks :)
07:11solar_seaCan I add documentation to defstruct ?
07:14raeksolar_sea: don't think so. I usually put documentation regarding data conventions and contracts in the ns docs
07:22solar_seais there any guide about a proper coding style ? I'm just starting with clojure, doing a simple connect 4 playing app to get my feet wet :)
07:26solar_seahowever, the repeat way of creating a vector creates a lazyseq, which I can't use assoc later on ..
07:26ejacksonsolar_sea: the quick workaround is (into
07:26ejacksonwhich will put the seq back into a concrete type
07:27TobiasRaederhttp://www.assembla.com/wiki/show/clojure/Clojure_Library_Coding_Standards
07:27TobiasRaederits a bit older but seems fine on a quick look
07:28solar_seathanks both of you
07:28solar_seaejackson, I got around it by (vec (repeat ..))
07:28ejacksonyeah, vec is the same as (into []
07:44solar_seahow can I get the size of a vector / list, so I can avoid an index out of bounds exception ?
07:45opqdonutcount
07:46solar_seaor should I use get instead of nth and just check for nil ?
07:46clojurebot⟹ "Returns the metadata of obj, returns nil if there is no metadata."
07:53hoecksolar_sea: nth does also support a default
07:53hoeck,(nth [] 100 :default-value)
07:53clojurebot:default-value
07:54solar_seadamm the cheat sheet explains none of this, looks like I'll have to (doc check every one of these functions :D
07:55khaliGi'm after a small project to look at how files and code are laid out in a typical clojure project
08:02CozeyIs there a function doing this: (fn [d kw f] (assoc d kw (f (d kw)))) in standard library? what's it's name?
08:04MangeCozey: If the kw arg is instead a vector you can use update-in: (update-in d [kw] f)
08:04Cozeythanks!
08:48pdk,(re-seq #"[t[we]]+" "twisters")
08:48clojurebot("tw" "te")
08:48pdk,(re-matches #"[t[we]]+" "twisters")
08:48clojurebotnil
08:48pdkwhat's the story here
08:51incandenzapdk: from the java docs, looks like the matches one has to match the entire string
08:51incandenza,(re-matches #"[t[we]]+.*" "twisters")
08:51clojurebot"twisters"
08:52pdkregexes
08:52pdkone day i will master your dark arts
08:55fogus`goneincandenza: sweet nick :-)
08:55incandenzaheh, thanks :)
08:56fogus`goneI try to read that once every 5 years
08:56fogus`goneThat is, it takes that long. :-O
08:57incandenzaright :) I read it in like '97, so if someone asks me some followup question, I'm like, "uhh... I don't remember"
09:34clgvhow much would you estimate the impact on performance of using a map as a datastructure in a place where an array could be used? if there is pretty much read access to it?
09:39jweiss_is there a full-featured repl for the command line? paren matching would be great, but i'd settle for color highlighting
09:40Fossiyeah, it's called "emacs" :>
09:40jweiss_i'm trying to take it easy on my co-workers and not make them use emacs :)
09:41clgvEclipse with CCW is working well for me ;)
09:41cemerickjweiss_: netbeans and eclipse both have good plugins
09:41raeksyntax highlighting and paren matching sounds like a feature for the text editor for me...
09:41jweiss_clgv: which version? the official one doesn't have paren matching on the repl
09:41jweiss_the RC seem to but keeps popping up error messages
09:42jweiss_(although they don't seem to hurt anything)
09:42cemerickjweiss_: RC6 was released yesterday…maybe that'll resolve any issues you had?
09:42raekwhat editors beside emacs (and eclipse, I've heard) has convenient key bindings for evaluating an expression (from the source file) in the repl?
09:42clgvoh right. you just meant the repl and not the editor. well it has nothing except copy&paste... :(
09:42jweiss_cemerick: yeah that's what i'm running
09:42cemerickjweiss_: that's the refresh folder error?
09:42jweiss_cemerick: no, it's a project build error on labrepl
09:43cemerickah
09:43clgvI am using the latest stable version.
09:43cemerickjweiss_: have you sent a msg to the list?
09:43jweiss_i'm trying to point my coworkers at labrepl but the instructions are a bit out of dat
09:43jweiss_e
09:43jweiss_try-clojure.org is down
09:43arohnerclgv: from my benchmarks, maps are about 4x slower
09:44arohnerbut who knows how similar my workload and yours are
09:44clgvarohner: thanks for that fact.
09:44cemerickjweiss_: I know Laurent is working towards a final 0.2.0 release, so now's the time to get your issues in
09:44cemerickclgv: records/types should be a fair bit faster than maps
09:44clgvI have around 5 Million accesses in a small run
09:45fliebelclgv: Still optimizing that loop?
09:45solar_seajava.lang.IllegalStateException: Nested #()s are not allowed - is this by a technical reason, or to force a coding style ?
09:45fliebelsolar_sea: How would you match the arguments?
09:46jweiss_cemerick: any idea what this error means from CCW? seems to be labrepl related, but i'm not sure why CCW is trying to build the project over and over
09:46jweiss_http://www.fpaste.org/cIO0/
09:46clgvfliebel: another part now. I ordered the possible performance bottle necks by total time consumption starting with the biggest ;)
09:46cemericksolar_sea: parameters would be ambiguous given nested function literals
09:46cemerickjweiss_: yuck. No idea. It only happens with labrepl?
09:46Chousukesolar_sea: I think it's both easier to implement and prevents people from writing confusing code.
09:47fliebelclgv: Can we see teh codez somewhere?
09:47raeksolar_sea: having nested map + #()s? if so, consider 'for'
09:47jweiss_cemerick: no idea, i use emacs. I am just trying eclipse to work out the kinks before i let my coworkers try it.
09:47Chousukeevery time you'd like to nest #()s there is a better way to write your code.
09:47clgvfliebel: nope. it's my current research project. code might be released after the first couple of publications
09:48cemerickjweiss_: I use the RC full time. *shrug* It may be a simple issue. Definitely worth pinging the ML.
09:48solar_searaek, precisesly, iterating over a 2d vboard :)
09:48jweiss_cemerick: k thanks
09:48fliebelraek: Using for would give you a 1D seq, how would you use for in a place where you'd need nested #()?
09:48fliebelclgv: I see...
09:48raekhrm.
09:49raekanyway, (for [x xs] (do-complicated-stuff ...)) looks better than (map #(do-complicated-stuff ...) xs)
09:50raekespecially if the fn spans multiple lines in the source code
09:50raekthis would be my main point.
09:50fliebelraek: Very true. Let me dig up some example...
09:53fliebel&(map (fn [k] (map #(* 2 %) k)) [[1 2 3] [4 7 2] [2 5 2]])
09:53sexpbot⟹ ((2 4 6) (8 14 4) (4 10 4))
09:55raekyes. see what you mean. I would like to write at least one of those maps with a for
09:56raek&(let [m [[1 2 3] [4 7 2] [2 5 2]]] (for [row m] (for [cell row] (* 2 cell))))
09:56sexpbot⟹ ((2 4 6) (8 14 4) (4 10 4))
09:56raek&(let [m [[1 2 3] [4 7 2] [2 5 2]]] (for [row m] (map #(* 2 %) row)))
09:56sexpbot⟹ ((2 4 6) (8 14 4) (4 10 4))
09:57raekI'm inclined to the symmetry of the for-for one...
09:57fliebelOkay, I must agree with you that it looks cleaner.
09:59raekyeah, I hardly used it at all during my first 6-8 months of clojure
10:00fliebelraek: I won't take that as an insult ;)
10:00fliebel&(clojure.walk/postwalk #(if (number? %) (* 2 %) %) [[1 2 3] [4 7 2] [2 5 2]])
10:00sexpbot⟹ [[2 4 6] [8 14 4] [4 10 4]]
10:01raekfliebel: hrm. let me put it this way: at the point where I felt that I knew about most of the stuff in the language, I had not begun to use 'for'.
10:03raekit wasn't meant an insult. I just begun using 'for' relatively late
10:05fliebelraek: That still sounds pretty smug, because it implies you felt you knew the whole of Clojure in 6-8 months. I knew it wasn't an insult, I just realized you could interpret it as one.
10:05fliebeloh, well, 6 months is a long time, actually...
10:07fliebelHm, is there any case where one would prefer prewalk over postwalk, or the other way around?
10:08raekhrm. "knew about" might not be the exact word either. more like "having a feeling for what exists in the language and what does not"
10:08fliebelraek: Never mind, it's alright. :)
10:10fliebelBut it's fun how some things in Clojure have always been there right in front of you, and only after a long time you start to use them. I guess for is one of them, amongst things like multiple arguments to a lot of functions tat take only 2 in most languages.
10:13clgvlol ;)
10:13clgvit's pretty short written for its effect. clojure.walk is definitely interestign.
10:16fliebelhrm… "XML reading/writing." Where is the writing part? http://clojure.github.com/clojure/branch-master/clojure.xml-api.html
10:17fliebelThere is emit still, but it's not listed… https://github.com/clojure/clojure/blob/master/src/clj/clojure/xml.clj#L111
13:59kryftamalloy: Well, like you said, I don't even see my parents
14:00chouserI wonder if it would be more clear for stack traces to be printed as root cause, rethrown as, rethrown as ... instead of final cause, caused by, caused by...
14:00markskilbeckchouser: definitely
14:01amalloychouser: maybe
14:01dsantiagoI've always wished the stack traces were upside down, since you've always gotta scroll upwards to see what caused them.
14:01chouserjava prints them half-upside-down
14:01amalloychouser: yes, that's what i was about to say
14:02amalloyonly i was going to be more verbose and less clear
14:02markskilbeckamalloy: would (vec (concat ... )) work then?
14:03markskilbeckEven if it did, it feels dirty having to change the type.
14:03amalloymarkskilbeck: it feels dirty for a reason :P
14:04markskilbeckLe sigh.
14:04amalloymarkskilbeck:
14:04amalloyer
14:05amalloymarkskilbeck: anyway, you can surely do all this with vectors if you want
14:06amalloyuse subvec instead of take, pass around two separate vectors instead of concat'ing them, and so on
14:06chouserfliebel: heh. good point.
14:09markskilbeckamalloy: thanks for the pointers
14:10fliebelTalking about subvec… say I have 2 vectors named a and b, made from c by subvec. They now share structure with c. Now we delete c, will all nodes not in a and b be GC'd?
14:11amalloyno
14:11amalloythey keep a pointer to c, with no special information that lets the gc know only some of its objects are needed
14:12fliebel:( So this has the same problems as taking a substring from the works of Shakespeare.
14:12chouseryes
14:13fliebelDoes the same solution apply? (vec (subvec))
14:13amalloyfliebel: i was just about to suggest that
14:13amalloy(the answer is yes)
14:13semperos1any way to "reset" Clojure's memo cache while working at the REPL?
14:14chousersemperos1: re-memoize the function
14:14fliebelSo, I guess we have arrived at the reason that vec takes linear time, even if the thing is already a vector.
14:14technomancysemperos1: you need to use an alternate memoization implementation.
14:14amalloyfliebel: not necessarily the reason, but at least a nice side effect
14:14semperos_technomancy: yeah, I was just reading about them
14:15semperos_the function isn't one I wrote
14:15fliebelamalloy: You know *the* reason then?
14:15semperos_chouser: not sure I understand what you mean by re-memoize
14:15chouserif you have (defn foo* ...) (def foo (memoize foo*)), just rerun the def foo
14:15mattmitchellhow can i get the first 2 chars of a string?
14:15semperos_ah
14:15amalloymattmitchell: substr, or take
14:15amalloy&(take 2 "hey dude")
14:15sexpbot⟹ (\h \e)
14:15mattmitchellamalloy: thanks
14:15mattmitchellexcellent
14:16amalloy&(subs "hey dude" 2)
14:16sexpbot⟹ "y dude"
14:16amalloyi guess that's the opposite. but you can adjust args to subs to make it work
14:16fliebel&(subs "hey dude" 0 2)
14:16sexpbot⟹ "he"
14:49mattmitchellhow can i turn [:one 1 :two 2] into a map like {:one 1 :two 2} ?
14:50dnolen,(apply hash-map [:one 1 :two 2])
14:50clojurebot{:one 1, :two 2}
14:51mattmitchelldnolen: thanks!
15:07dnolenanybody read through Art of the Propagator and applied it's ideas to Clojure?
15:08fliebeldnolen: Not me, what is it about?
15:10dnolenfliebel: a very interesting model of computation (useful for constraint based programming, as well distributed search) http://lambda-the-ultimate.org/node/3250
15:13dnolenfliebel: Prolog-style search is useful, but you want to constrain the search space very quickly before committed to a real search, propagators can help you do that.
15:13cemerickdnolen: I stole some ideas from it for a constraint-based system I built last year. Was a great perspective.
15:13dnolencemerick: nice did you put anything into a library?
15:14cemerickAlexey gave a talk based on that paper at ILC 2009, was very compelling. Sadly, no video. :-(
15:15cemerickdnolen: hrm, nothing I would inflict on anyone at this point. It was pre-Clojure 1.0 code, IIRC.
15:15dnolencemerick: heh
15:15cemerickThe implementation of it is very straightforward, really. Translating from the scheme impl to something reasonable given what we have now warrants some thought though.
15:16dnolencemerick: was your implementation concurrent?
15:16fliebeldnolen: http://lambda-the-ultimate.org/node/3250#comment-47804
15:16cemerickdnolen: yeah, used refs extensively.
15:17cemerickWhich meant that it was dog slow for what I was using it for, unfortunately.
15:17dnolenfliebel: of course Peter Van Roy will say that, but the the paper is done in a approachable tutorial-style.
15:19dnolencemerick: I wonder if agents are a better fit, tho I imagine even they would have a sizeable overhead.
15:19dnolenfliebel: http://lambda-the-ultimate.org/node/3250#comment-47997
15:20cemerickdnolen: a lot of my data was very fine-grained numerics. I never really profiled it (dog slow and working was good enough for me at that point), but I suspect the boxing was brutal.
15:33CaseySquick question regarding a lein uberjar error I'm getting: LEIN_SNAPSHOTS_IN_RELEASE, how can I set this?
15:34technomancyCaseyS: $ LEIN_SNAPSHOTS_IN_RELEASE="I am responsible for my own actions" lein uberjar
15:34technomancyit's just an environment variable
15:35technomancyCaseyS: better yet, switch to using locked number snapshot versions if available ("1.0-20110121" instead of "1.0-SNAPSHOT")
15:37CaseySthanks - it's just a toy project, so I'm not too concerned. I'll try to sanitize my project.clj of snapshots eventually though...
15:37tomojis it possible to `:omit-default-repositories true :repositories {}` without changing project.clj? :(
15:38tomojoh, maybe some more settings.xml magic will help
15:48TimMcOK, unit testing question.
15:49TimMcMy program has a bunch of (def foo (ref ...)) and I want to write tests for some functions that read those refs.
15:50TimMcShould I refactor my code to use helper functions that pass refs in to combinators?
15:51mefestoTimMc: maybe using binding to override the refs for the test?
15:53mefestosomething like: (binding [myns/foo (ref 1)] (some-func))
15:53TimMcOooh, I can do that?
15:54tomojyour idea sounds better to me
15:54CaseyStechnomancy: your suggestion to use locked number snapshot versions - am I cheating if I used a 1.0-SNAPSHOT when running lein deps then switched to the locked number version once I had the jar in my lib/ directory?
15:55TimMctomoj: I like the idea of state-locked helpers that call combinators... but the binding macro is pretty seductive.
15:56TimMcIt also means I wouldn't have to create extra helpers.
15:56tomojwith binding, won't you have to start worrying about state leaking out of the tests?
15:56tomojoh, no, not at all
15:56mefestowell you could do the binding with :each fixtures
15:56mefestothey are setup/torndown on each test
15:57mefestobut still, if your functions just need a snapshot of the value of the ref then you should just pass that to them
15:57mefestotesting becomes much easier then :)
15:57TimMcCrap, have to run... will read backlog later.
15:57mefesto(my-func @myns/foo)
15:58TimMcI really should not miss the talk my girlfriend is giving.
16:00chouserOne should also no preceed such a statement with "Crap"
16:00chouser;-)
16:08fogus-It seems that people (cough... me) are interested in AOP facilities in Clojure.
16:10fogus-https://github.com/fogus/clojure-aop
16:16cemerickfogus-away: I've never thought AOP in clojure needed much of anything special.
16:16cemerickor, rather, that the *aims* of AOP needed anything special
16:17qedsorry for all the join/part noise.
16:26fliebeldnolen: Why does an unsuccessful statement return an empty seq rather than nil, as is common in Clojure, I believe. An empty seq would make sense in Scheme because it is falsey I think. < Lots of thinking and believing there… I should do my research before uttering things.
16:36dnolenfliebel: I could do that, but the results are simply a lazy-sequence - I'd need to hear more compelling reasons.
16:36qeddnolen: i missed this discussion
16:36fliebeldnolen: So, if I do (take 5 (run*)) on an infinite computation, it'd work?
16:37qedwhatjoo talkin bout?
16:37brehautfliebel dnolen: thats consistent behavior with other operations on lazy seqs that dont return anything
16:37dnolenfliebel: yup.
16:37dnolenand it's truly one at a time lazy.
16:38brehauteg (filter (constantly false) (range 1000)) => ()
16:39fliebelOkay, you are totally right. Only rest and seq return nil, that I know of.
16:40fliebelor was it next… ##(rest [])
16:40sexpbot⟹ ()
16:41bytecoloris there a latest and greatest blog for getting clojure+slime up?
16:42bytecolorI just installed lein. I'm assuming that's a piece of the puzzle.
16:42technomancybytecolor: just the boring old swank-clojure readme
16:45qedwould anyone mind parting/joining #clojure to test out something for me?
16:45qedwhen you're done just say: yeah!
16:46companion_cubehello back!
16:46qed:( i dun configured incorrectly
16:57fdI've a question about ->
16:57sarcher|workask away :)
16:57fdtrying to wrap my head around this..
16:58fdI have some functions that return functions
16:58fdI'm trying to chain them together with ->
16:59fdit works but the resulting function calls the functions in the chain in reverse order
16:59fdI understand why that is, but is there a way to have the functions be called in order that I pass them?
16:59brehautfd, first question, you understand that -> rewrites forms, rather than performing function compositions?
17:01fdbrehaut: ah.. perhaps it is function composition I am after?
17:01brehautfd perhaps
17:01brehautthey perform two distinct roles
17:02bytecolorwell, at least I can kill a program withough killing clojure now. That was worth the price of admission ;)
17:02brehautand a -> that threads backwards (say (defmacro -< [& body] `(-> ~@(reverse body))) ) gains little compared to the actual form
17:02fdbrehaut: I probably need to explain better what I am trying to achieve
17:03technomancybytecolor: suggestions for improving the docs are welcome of course
17:03brehauteg (-< inc (* 3) 4) and (inc (* 3 4))
17:03brehautfd: always good practise
17:03fdI have handlers which take other handlers as a parameter and return a function. in that function, I do something and I may or may not invoke the next handler.
17:04amalloyoh no, now brehaut will start talking about maybe-m :)
17:04fdI want to chain these handlers together. if somewhere down the chain, the handler doesn't invoke the next one, the chain just stops.
17:04brehautamalloy: i was going to suggest -?> first ;)
17:05brehautfd: -?> is in clojure.contrib.core and it is like -> except that if any form results in nil, non of the following forms are evaluated
17:06fdbrehaut: it is not the abortion of the chain that is the problem, it is the order. if I list in reverse order, it all works as expected.
17:07fdI just find it counter-intuitive to have it work that way. maybe I should just try your -<
17:07brehautmy -< is horrible. i wouldnt recommend it
17:07amalloybwagh no do not try his -<
17:07brehautit merely existed to prove a point
17:07brehautif you really are just dealing with functions use comp
17:08amalloygranted any macro that looks like an electric guitar is appealing, but this one is evil
17:08fdheh
17:08brehautits worse than evil, its maliciously stupid
17:09fdok
17:09brehaut-> is designed to thread forms so that the inside most form is on the left and you read left to right rather than right to left
17:10brehautturning it round so that you can read right to left is self defeating
17:10brehautand being a rewriting operator, provides more room for error
17:10amalloyfd: why don't you put together an example of a few functions you have, and how you would chain them together manually
17:10fdfor example, (defn handler1 [handler] (fn [ctx] (if something (dosomething) (handler ctx))))
17:11brehautare your parens wrong there?
17:11amalloybrehaut: they look right to me
17:11fdalso (defn handler0 [handler] (fn [ctx] (let [start (System/currentTimeMillis) _ (handler ctx) end (System/currentTimeMillis)] (println "that took..."))))
17:12brehautah i missread handler as handler1
17:12fdand so on.. so I want to chain handler0 handler1 handler2 into one function.
17:12raekfd: if these are Ring handlers, I'd suggest taking a look at Moustache
17:12amalloyso you want your end result to be (handler0 (handler1 handler2))?
17:13raekmaybe it could be interesting anyway, since it composes middleware functions (which have that exact structure) in this way
17:13fdyes, but the end result has to be a fn [ctx]
17:13fdraek: yes it is very similar to ring middleware
17:13amalloyfd: it is
17:14amalloymy example above resolves to a function of ctx, so what's the problem with writing it that way?
17:14fdamalloy: oh, you're right. so yes that is what I want.
17:15fdamalloy: gee you're right (I think). is there a nicer way to chain them so that with 10 functions I don't have a ton of nesting?
17:15amalloyfd: reduce comes to mind but i can't get it quite right
17:15fdsomething along the lines of what (.. obj getA getB getC getD) solves
17:15amalloysomething like (reduce #(%2 %1) handlers)
17:17amalloythe trouble is i think you want reduce to fold in the other direction. brehaut, do you have foldl/foldr implementations in clojure lying around somewhere?
17:17brehauti dont sorry
17:19fdthere's gotta be something to call (f0 (f1 (f2 (f3 (f4)))))
17:19brehautcomp
17:19brehautoh no i see
17:21brehautyou'd have to do a filthy ((comp f0 f1 f2 f3) f4)
17:23amalloybrehaut: that doesn't solve the problem. comp goes in the wrong order
17:25brehauti must have missed something
17:26fdthis has helped a lot, thanks very much
17:27brehautwow really? im more confused now than i was before!
17:29amalloybrehaut: oh no i'm just dumb
17:29brehautphew
17:30amalloythat's what i get for trying to do actual work while i'm in #clojure
17:30brehauthah
17:32fdha! seen in moustache: middlewares (reverse middlewares)
17:32fdquack
17:34semperos_using clj-time and joda time, trying to simply print out a DateTime with a specific format *and* timezone
17:34semperos_but all printing with formatters changes the timezone to UTC by default
17:34semperos_anyone know how to print the date with a specific format and timezone?
17:39tomojsemperos_: with-zone
17:40semperos_tomoj: thank you
17:42bytecolortechnomancy: I've got an older version of slime I installed for sbcl, could I grab *only* slime-20100404.1.el and slime-repl-20100404.el from your emacs repo and install them manually without any other dependencies? I tried package.el, but my emacs is too old: 22.2.1. It craps out on the :risky keyword in a defcustom.
17:42technomancybytecolor: that should work; yeah.
17:42technomancyI don't know if sbcl will like it though
17:44bytecolorok, I'll give it a shot. Yep, getting sbcl *and* clojure running with slime/swank doesn't seem to want to work well. My old version of slime worked ok with clojure-swank, though.
17:44bytecolorI'll burn the other bridge when I get to it
17:45technomancyworking theory is getting clojure working will be so awesome that you'll lose interest in CL
17:49bytecolorclojure has kept my attention for a couple months now. Don't really have any gripes. Even the extra [] {} are ok. They actually have semantics tied to them instead of what scheme is trying to do: make lisp more readable by adding [].
19:28tomojwonder how I can figure out when I found clojure
19:28ossarehdoes anyone use the emacs starter kit?
19:43tomojRaynes: missed your gene comment before. that explains it
19:44mattdwossareh: yes
20:37bytecolorthe emacs starter kit says run: M-x slime, but the swank-clojure README says run: M-x slime-connect. How is the swank server being started? If I run the shell script swank-clojure, then in emacs M-x slime-connect, everything is peachy.
20:37technomancybytecolor: where does the starter kit say M-x slime? that's out of date.
20:38bytecoloroh? hrm... lemme look again
20:38technomancythe swank-clojure shell script or "lein swank" are both good ways to start a swank server, depending on whether you're in a project or not.
20:40bytecolorI was reading it from this blog: http://freegeek.in/blog/2009/08/setting-up-emacs-clojure-with-emacs-starter-kit/ which actually linked to your git repo
20:42hiredmannever read blogs posts, they never contain correct up to date information
20:43technomancyhiredman: at least this one is up-front about containing out-of-date info.
20:44bytecoloryes, later in the blog. I'm playing catch-up! ;)
20:45bytecolorso, it seems you were using the common lisp swank backend, then ported it to clojure
20:46technomancybytecolor: that would have been jochu
20:47bytecolorah
20:47TimMcSo here's my proposal for rewriting my ref-using code so that I can do unit tests: https://gist.github.com/823389
20:48TimMcAlternatively, use the binding macro when calling update-stuff! from testing code.
20:48clojurebotpeepcode is a commercial screencast series; see the Clojure one at http://peepcode.com/products/functional-programming-with-clojure by technomancy
21:04TimMcAnd if the first, is there a good naming scheme for all these extra functions? :-P
21:08amalloyTimMc: binding is a lot less gross than this
21:15cheezeyim using leiningen and im trying to start a new project but for some reason, it can't download clojure.jar nor the cljoure-contrib saying they're nto found. im using mac os x (new machine) so i dont know if im missing something or what..
21:15cheezeyany ideas?
21:30amalloycheezey: get an up-to-date version of lein. whatever version is easiest to get on the mac is way old
21:31cheezeyamalloy: it's the most recent version
21:33amalloyno idea then
21:34amalloymaybe gist an actual error message instead
21:35cheezeyit just tries to download those jars from the repos, fails, then tells me the standard maven missing jars stuff (try to manually do it, etc)
21:35tomojhow could it be easier than wget + chmod?
21:35cheezeyoh wells :_;
21:35tomojI guess some crazy mac package system with one step is less than two steps if you've already got the crazy
21:50TimMcamalloy: It is certainly more succinct.
21:52echosystmso, i've started with some clojure tutorials
21:52echosystmthis will be the first functional language i have learned
21:52cheezeyechosystm: nice =)
21:52echosystmi have a few questions...
21:53echosystmis clojure a very "strictly functional" language?
21:53echosystmie. is it to functional programming what java is to OOP ?
21:53TimMccheezey: You've done lein self-install, then lein new?
21:53cheezeyTimMc: rofl i think ti's because mac didn't include wget by default
21:53TimMccheezey: oh wow
21:54cheezeyyeah im kinda angry now
21:54cheezeyhopefully that's the problem tho*
21:54TimMcechosystm: Clojure interoperates tightly with Java, you know.
21:54echosystmyes
21:55tomojlack of wget => maven errors?
21:55cheezeytomoj: i don't know. it didn't fix it so ;_;
21:55echosystmso does that imply that it isnt very strictly functional? in terms of side effects and so on
21:55TimMcechosystm: Indeed.
21:55echosystmi dont really know much about functional programming, im trying to guage where clojure sits in comparison to others
21:55tomojas amalloy said, you should gist the entire output with the errors
21:56TimMcYou can do all the great functional stuff too, of course.
21:56tomojmost likely you're just depending on something that doesn't exist
21:56amalloyechosystm: you can make side effects whenever you want, but by default there are no side effects, and it's easy to manage them when they are necessary
21:56Raynes$wiki purely functional programming
21:56sexpbotFirst out of 409 results is: Functional programming - Wikipedia, the free encyclopedia
21:56sexpbothttp://en.wikipedia.org/wiki/Functional_programming
21:57RaynesPurely functional programming is the most hardcore of functional programming. Like Haskell.
21:57TimMcechosystm: Clojure uses all sorts of immutable (persistant) data structures by default, which is awesome.
21:57RaynesClojure isn't purely functional.
21:57RaynesHowever, it strongly encourages functional programming and that is the predominate paradigm.
21:58cheezeytomoj: https://gist.github.com/823439 ( amalloy too)
21:58tomojoh, I didn't realize clojure was the problem
21:59echosystmi often hear people talking about print/println in terms of side effects
21:59tomojcheezey: you're just starting out, right? if so, try deleting ~/.m2
21:59echosystmcan someone explain what they mean by that?
21:59tomoji.e. rm -rf ~/.m2
21:59tomojthen try again
22:00cheezeytomoj: nice that seems to have fixed it
22:00cheezeyweird, i must have a corrupted version of clojure or something
22:00echosystmhow can you write software without side effects it you need to print something to the screen?
22:00greghechosystm: it means that sending data to an output device is a side effect. If you have a pure function f(a) followed by g(b), the runtime could run them in whatever order is convenient. If they both also print some output, then it *does* matter what order they're run in.
22:00tomojsometimes maven will do blacklisting if there's an error when it first tries
22:01echosystmah
22:01echosystmso how would you print something to screen without creating "side effects" ?
22:01TimMcechosystm: Monads!
22:01greghif you want to drink the purely functional kool-aid *and* worry about IO, I recommend Haskell :)
22:01cheezeyechosystm: issuing multiple commands?
22:01TimMcAnd you would use Haskell. :-P
22:01tomojI don't really understand it but deleting the appropriate pieces of ~/.m2 (or the whole thing if you can afford to lose it) seems to get rid of the blacklists
22:02cheezeytomoj: heh, no worries. new install anyway so not much in there :D
22:02echosystmdo you think haskell is a better language to learn as ones first functional language?
22:02greghlearning haskell will give you a solid foundation in pure functional programming, allowing you to easily evaluate and compare other languages with some functional features
22:02TimMcechosystm: Side effects are not inherently bad, they are just something to be aware of and avoided in certain scenarios.
22:03cheezeyi think clojure is awesome for first language but i don't know haskell so :\
22:03TimMcechosystm: Scheme is a pretty standard first functional language. Lots of good teaching books.
22:03greghmost programming languages have *some* aspect of functional features (even C). However, different languages emphasize the functional aspect more strongly
22:06Kowboyis there a compelling reason to use keywords as map keys if you are eventually going to need them as strings anyway?
22:06Kowboyor is it better in that case just to use string keys?
22:07echosystmso, what is the equivalent of monads in clojure?
22:08amalloyechosystm: monads are the equivalent of monads :P
22:09echosystmso there is no way to do side-effect free IO in clojure?
22:09TimMcechosystm: It's probably not the Clojure way of doing things.
22:09greghyou can think of functions in haskell being so pure that when a function wants to make a side effect, it takes the whole universe as a parameter and returns a new copy of the universe with the side effect changed
22:10TimMcechosystm: Why do you want functional I/O?
22:10echosystmlearning purposes i suppose
22:11TimMcAh, then check out Haskell.
22:11TimMcNota Bene: I am mostly a Clojure n00b.
22:11pdkdoesn't io imply side effects
22:12greghyes, "side-effect free IO" is an oxymoron
22:12cheezeyq
22:13cheezeywhere can i learn all about leiningen's proejct.clj options?
22:14amalloy$google leiningen project.clj example
22:14sexpbotFirst out of 474 results is: sample.project.clj at master from technomancy's leiningen - GitHub
22:14sexpbothttps://github.com/technomancy/leiningen/blob/master/sample.project.clj
22:16cheezeyk remind me to scroll down in github next time cuz i was searching around in testprojects ;|
22:43tomojhow do you indent your arrows?
22:43mattdwechosystm: http://brehaut.net/blog/2010/welcome_to_the_machine is a look at monads in clojure
22:44tomojto first-arg or defn style?
22:44mattdw,(doc io!)
22:44clojurebot"([& body]); If an io! block occurs in a transaction, throws an IllegalStateException, else runs body in an implicit do. If the first expression in body is a literal string, will use that as the exce...
22:44amalloytomoj: first-arg, personally, but defn style is probably nicer
22:44mattdw^ io! might also be of interest to you
22:44tomojmy thoughts exactly
22:45tomojeh, I dunno
22:46tomoj"->" is maybe a bit too short for defn style
22:46tomojlooks kinda funny
22:46mattdwmy problem with first-arg is that -> and ->> end up with different indent levels
22:46mattdw(although it's what I tend to use)
22:47mattdwalso, first arg is treated differently to the rest, makes sense to keep it on the first line
22:47amalloymattdw: of course first arg should be on first line
22:47amalloybut how far do you indent second+ args is the question
22:48mattdwsure
22:49tomojI feel like emacs is a tyrant when it comes to indentation
22:49tomojif I try to make a patch to a clojure project that wasn't made with emacs it will almost certainly be a nasty diff
23:13cheezeythis is a really dumb question but im still messing around with leiningen. so i have a core.clj and i want to import another file (derp.clj) which has namespace derp.derp and soem function is declared in it, how does core.clj import and use that function (basically how do i do imports if the 2 files are in the same folder.. simple stuff)?
23:15tomojnamespaces and paths should correspond
23:15technomancycheezey: (ns derp.core (:use [derp.derp :only [derp-fn]]))
23:15tomojderp.derp should go in src/derp/derp.clj for example
23:15technomancycheezey: but in general you should read more existing code probably if that isn't clear
23:17tomojif your core.clj is derp.core then I guess you already knew that..
23:17cheezeytechnomancy: ugh that's what i did and it says the files are not in its classpath
23:17cheezeyi dunno i thought since core was found, it would be fine :|
23:25tomojdoes anyone else find that zip-filter lacks composability?
23:25tomojxml-> in particular
23:27tomojhmm.. guess if I wait as long as possible to call node and accept mapping xml-> over intermediate results it will compose fine
23:27amalloytomoj: xml-> is shorthand for some publicly exposed functionality
23:28tomojoh
23:28tomojdidn't think of trying that, thanks
23:29tomojactually mapcat-chain just looks less useful, still only takes a single loc
23:30tomojfor obvious reasons I guess :(
23:34anthony__I have some utility functions in a Clojure project. I built a JAR out of it (non-runnable). I want to execute a script that uses some of those functions, but I can't get it to work. Is there a catch?
23:34anthony__I'm using java -cp clojure.jar:my-utils.jar clojure.main myscript.clj
23:39cheezeytechnomancy: can you point me to a project that uses leiningen and is relativel simple? i honestly cannot find one; github just keeps finding stuff from leiningen itself :\
23:39amalloycheezey: more or less every clojure project on github
23:39hiredmanthe lein repo includes some sample lein projects
23:39amalloyuses lein or cake, and the layout is similar
23:47bytecoloranthony__: do all those jars, have to be in ./ when you execute that?
23:49anthony__bytecolor: Which jars?
23:50bytecolor-cp resets CLASSPATH, correct?
23:50bytecolorclojure.jar and my-utils.jar
23:51bytecolorso if not ./clojure.jar and ./my-utils.jar, it will fail, no?
23:53cheezeyamalloy: i know i've been trying to follow them but nothing i do seems to work. https://github.com/cheeze/nom is the code. it's really simple :\
23:54anthony__bytecolor: True. But my JARs are in ./ Sorry about that
23:54anthony__The problem is when I reference functions from my-utils.jar
23:54anthony__How do I import that namespace? Do I need to do something special to load the my-utils.clj file?
23:54anthony__So I can use the ns?
23:56amalloycheezey: the code all looks fine to me, but i don't do much gen-classing so i dunno. you certainly shouldn't need to gen-class for any namespaces other thancore
23:57amalloyand i sorta question why you're gen-classing there either. you can use clojure.main to launch if all you want is a main()
23:57cheezeyoh i dunno i think there was a compiling issue earlier and i got lost in it
23:58cheezeyamalloy: http://pastebin.com/4QbcxiEw is the ouput when i lein compile so
23:58cheezeyi must be missing something really obvious
23:59replacain any case, I gotta crash. G'night all!
23:59amalloythen those files weren't on your classpath. but stop trying to compile anything, you're just making life harder for yourself. take out the gen-classes, and play around in a repl
23:59amalloyuse clojure.main if you want to run it outside a repl