#clojure logs

2008-07-06

00:22NafaiYay, just wrote my first real working Clojure code
00:25Nafaihttp://paste.lisp.org/display/63330
00:26NafaiAny critiques would be welcome :)
00:48Nafaiwa
00:48NafaiWhoops
01:11slavahey nafai
01:13NafaiHi
01:14slavai heard you moved away from austin
01:14NafaiYeah, moved back to Utah.
01:15NafaiGot a pretty good job and I have more friends here
01:55arbschtNafai: fwiw: http://paste.lisp.org/display/63330#1
01:55arbschtNafai: I make no assurance that it is in any way better, but maybe it gives you some ideas :)
01:58NafaiThanks arbscht
02:01NafaiHow do I assign a variable at the REPL?
02:01Nafailet won't work because the scope is over once you close the )
02:02jgrant(def varname value)
02:03arbschtthe value is optional, too
02:07NafaiHow do I find out what type objects in a seq are? I'm trying to print the sequence and I keep getting class-cast exceptions
02:12NafaiAh, it's happening earlier
02:19slavaNafai: look who's here
02:19NafaiHi erg
02:20erghi Nafai
02:20erghow's the codez?
02:21NafaiNot bad
02:21NafaiThought I'd pick a little Clojure to see if I like it
02:33NafaiAny ideas on how I would do this?
02:33NafaiI want to have a data file that has a vector per line
02:33NafaiLike: [1 2 3]
02:33NafaiI want to be able to use the reader and process each vector
02:34NafaiMaybe it's just I can't figure out the proper thing to do with loop and recur but I can't figure it out
02:51arbschtNafai: if you wrap the contents of your file in [] you will get a vector of vectors when you (load-file)
02:53NafaiOooo
08:48ballzack3l
08:49ballzack3hello
08:56StartsWithKhow can i create instance of nested class?
08:56blackdogclass$nested
08:58StartsWithKUnable to resolve classname: Ellipse2D$Float
08:58StartsWithKi have (import '(java.awt.geom Ellipse2D))
09:01blackdogtry Ellipse2D$Float
09:01blackdogtry import Ellipse2D$Float
09:05StartsWithKblackdog, that worked, thanks
09:06blackdogcool,
09:24kotarakIs it possible to have a lazy map like lazy-cons? ie. the value is only evaluated when I access the key.
11:23Chouserkotarak: I was just discussing that with abrooks.
11:24Chouserkotarak: I think you could use proxy to implement an IPersistenHash that has that behavior, but as far as I know there's no way as easy as lazy-cons
11:25Chouser...and unless you're going to assoc onto it, y really might just be talking about a memoized function.
11:28kotarakthe use would be in the return type of a function, where certain things must be done lazily. One could of course return a lazy list, but the gets ugly when the return value changes
11:40Chouseryou could return a memoized function, right? That would cover your use case?
11:42kotarakI would like to just get the value, w/o having to call a function.
11:43kotarakie. the funcll would be transparw
11:43kotarakoops
11:43kotarakthe funcall would be transparent to the program
11:45ktnehello
11:45ktneis clojure the best lisp for jvm?
11:48kotarakthere is also a scheme, but don't remember the name.
11:49ktneis that a standard scheme?
11:50kotarakI think so, R5RS IIRC.
11:50ktnei see
11:50ktnei was thinking about something more experimental
11:50ktnenot just a standard implementation
12:12mac_ktne: experimental in what way? clojure is made to easily support concurrent and functional programming
12:12ktnei mean, not just standard scheme implementation
12:14mac_It's definetly not a standard scheme. I'm pretty new to lisp and clojure myself so I can't tell you what the differences are exactly but it should be on the web page I think
12:15mac_there we go: http://clojure.org/lisps
12:15ktnethanks
12:18Chouserkotarak: if it were a hash, you'd still need to call something to get a value (get foo :key) or (foo :key) or (:key foo), right?
12:19Chouserif it's a memoized function called foo, you could call it with (foo :key) -- same syntax
12:19kotarakhmm... ok. That makes sense.
12:51Chouserhm, and there's a nice memoize already in clojure-contrib.
12:55meredyddHey all.
12:55Chouserhi, meredydd.
12:55meredyddIs there an idiomatic way of modifying the value stored to a particular key in a map?
12:56Chousercan't modify anything. ;-)
12:56meredyddChouser: Well, that's the problem. Because an in-place modify is fetch->modify
12:56meredyddwhereas with immutability you have to do fetch->modify->writeback
12:56meredyddand 'fetch' and 'writeback' have quite a lot of redundancy.
12:56Chouseruser=> (def m {:a 1 :b 2})
12:56Chouser#'user/m
12:56Chouseruser=> (assoc m :a 9)
12:56Chouser{:b 2, :a 9}
12:57Chouseroh.
12:57meredyddI'm doing a lot of:
12:57meredydd(alter map-ref assoc key (do-something-complicated-to (@map-ref key))
12:58meredyddWas just going to knock up a macro to do the round-tripping for me (based on the "alter" idea - give it a map, a key, and a fn to apply to the value, and it'll give you the new map)
12:58meredyddbut it strikes me as the kind of thing there might be something in the API fo
12:58meredyddr
13:00kotarakMaybe clojure wants you to do it differently? A lot of hassle is often a sign, that you work against the system.
13:00meredyddIndeed. Which is why I'm running it past here before doing that.
13:01meredyddOn the other hand, I can't really think of another way around it - I need to store a set of Xs for each Y
13:02kotarakMaybe you should pass it on to a function instead of storing it somewhere?
13:02meredyddso unless you can think of a better option than an immutable map of Ys to immutable sets of Xs, you're going to have to do something
13:02meredyddkotarak: I'm familiar with the basics of functional programming. This is one of this program's three pieces of state.
13:06meredydd(In fact, one piece of state. But it needs to be looked up from several directions, so it ends up being in several maps.)
13:10Chousermeredydd: I think you're doing it right, although you if you think you can get away with commute instead of alter, that would be better.
13:11Chouserthe pattern you described shows up a couple times in ants.clj
13:11meredyddChouser: Commute would be good - unfortunately, there's some conditional logic in there and I think I'd be whacking a hornet's nest if I let multiple invocations on the same value of Y intersect.
13:11meredydd(defn alter-map-val
13:11meredydd[map-val key alter-fn & args]
13:11meredydd(assoc map-val key (apply alter-fn (get map-val key) args)))
13:12Chousermeredydd: yeah, ok, as long as you're thinking about it. I've not done enough different things with refs of hashes to think easily about when I would need alter vs. commute.
13:12meredyddSeems nice to me.
13:13meredyddOkay, that just made the whole statement fit on one line. That's promising.
13:14Chousermeredydd: can you paste an example usage?
13:14Chouseryou'll use ref-set now instead of alter?
13:14meredydd{:test #(assert= (alter-value {:a 4 :b 5} :b #(+ %1 %2) 1) {:a 4 :b 6})}
13:15meredyddUsage goes:
13:15meredydd(alter user-roles-by-component (alter-map-val victim #(disj % [user, role])))
13:15meredydd(where the #(disj...) stuff is the application-specific stuff - removing something from taht set)
13:16meredyddaaand I have to go.
13:16meredyddbbl, might discuss this further if you're around, Ch
13:16meredydd*chouser
13:17ChouserHm! I think it looks good!
14:53Chousermeredydd: I know you're not here, but that's not quite right
14:55meredydd?
14:56meredyddChouser?
14:56Chouseroh, hi.
14:56Chouseralter's second arg is a fn, so either alter-map-val needs to return a fn, or something else needs to be different
15:08Chouser(defn alter-map-val [m key alter-fn & args] (alter m assoc key (alter-fn (@m key))))
15:08Chouser(dosync (alter-map-val victim :a #(disj % [user, role])))
15:11ChouserYou could have a commute-map-val too, I suppose
15:58Lau_of_DKpublic class MyClass implements JButton {} -- How is this done in Clojure?
15:59Chousergen-class or proxy
16:00Lau_of_DKgot a brief example?
16:01Chouser(proxy [JButton] []) will create a new instance of a class derived from JButton.
16:02Chouserxml.clj includes an example of proxy
16:04Lau_of_DKThanks, exactly what I needed to know
16:05Lau_of_DKChouser - Maybe you should look through the documentation on Clojure.com? I find it somewhat lacking in a few various areas
16:06Chouserproxy is documented on the java-interop page
16:11Chouserscgilardi: I noticed your memoize in clojure-contrib today. Thanks for that!
16:12scgilardiyou're welcome! I noticed the discussion earlier about alter. does memoize show how to do something similar more simply?
16:14ChouserI don't think so. There was a conversation about a lazy-cons for hashes, and I was saying that for some use cases, memoize might be sufficient (since we don't currently have a lazy-cons for hashes).
16:15scgilardiok, I haven't worked through it all yet, but it seems like "assoc" when used in a "commute" fills the role of "alter-map-val". I've been pleased with how "conj" and "assoc" have been all I've needed when commuting.
16:16Chouseryeah, the alter stuff was an different topic.
16:16scgilardi"commute" -> "alter"
16:16scgilardiok cool
16:17ChouserI don't think alter-map-val is necessary, but without it you often end up repeating the name of the map ref and the key -- once for the lookup and once for the assoc or conj.
16:17Chouseralter-map-val or something like it just reduces the repetition.
16:18scgilardialter returns the new value. is it to try to capture the previous value?
16:18scgilardi(actually I haven't yet used alter... I'm familiar with commute)
16:19Chouserboth alter and commut pass in the old value, but if your ref is of a hash you still need to look up the key you want to change.
16:20Chouser...and the thing you need to return from your alter or commute func is the whole hash, not just the new val. that's where alter-map-val would help.
16:22scgilardiinteresting ok. I'll work through an example to understand it.
16:24Chouser(def m (ref {:a 1}))
16:25Chouser(dosync (commute m assoc :a (inc (m :a))))
16:25Chouserm and :a are each mentioned twice
16:26Chouser(dosync (alter-map-val m :a inc))
16:26Chouserwith the alter-map-val I gave above, m and a are only mentioned once each.
16:27scgilardiok I see now, thanks
16:28Chouserbut as you said, commute would be good too, so maybe it would be useful to also have commute-map-val
16:28scgilardior to make alter or commute an argument rather than part of the function name
16:28Chousersure
17:37meredyddYo, Chouser
17:37meredyddYou said you had a bug in my map-alter fn
17:53Chouseryep -- did you actually try your version?
17:55Chousermeredydd: http://clojure-log.n01se.net/date/2008-07-06.html#14:56b
17:56meredyddChouser: Not yet, tes
17:56meredydd*not yet
17:58meredyddChouser: Hmm. Comp crashed, and I've lost that file. Hold on...
17:58meredyddOh, yes, you're right.
17:58meredydd(alter user-roles-by-component (alter-map-val victim #(disj % [user, role]))) is wrong
17:59meredydd(alter user-roles-by-component alter-map-val victim #(disj % [user, role]))
17:59meredyddThat's right.
18:06Chouseroh!
18:06Chouservery well then.. that way you can use commute without needed a commut-map-val
18:09meredyddChouser: ha!
18:09meredyddI just read that log, and was about to make the same point.
18:09meredydd"alter" was the wrong name to give this fn.
18:09meredyddIt should be "replace-map-val"
18:09meredydd(or, in fact, "replace-assoc-val", but that's really quite long)
18:10meredyddI named it after "alter" because I was thinking about how you can do this:
18:10meredydd(alter x + 1)
18:10meredyddor (alter x assoc :key :value)
18:11meredyddYou can now thread this some distance:
18:11meredydd(alter user-roles-by-component alter-map-val victim disj [user, role])
18:12Chouseryikes
18:12meredydd(kinda a reverse "->")
18:13meredydd(which, again, is one of those things that first made me go "yikes", then after an hour of using it, made me appreciate rhickey even more than before)
18:14Chouser:-)
18:19Chouserwell, it's very hard for me to think through how that works, but it's hard to argue with the brevity.
18:19ChouserI suppose it wouldn't take long to get used to the pattern.
21:46arohnerhas anyone here played with compojure?