2008-07-06
| 00:22 | Nafai | Yay, just wrote my first real working Clojure code |
| 00:25 | Nafai | http://paste.lisp.org/display/63330 |
| 00:26 | Nafai | Any critiques would be welcome :) |
| 00:48 | Nafai | wa |
| 00:48 | Nafai | Whoops |
| 01:11 | slava | hey nafai |
| 01:13 | Nafai | Hi |
| 01:14 | slava | i heard you moved away from austin |
| 01:14 | Nafai | Yeah, moved back to Utah. |
| 01:15 | Nafai | Got a pretty good job and I have more friends here |
| 01:55 | arbscht | Nafai: fwiw: http://paste.lisp.org/display/63330#1 |
| 01:55 | arbscht | Nafai: I make no assurance that it is in any way better, but maybe it gives you some ideas :) |
| 01:58 | Nafai | Thanks arbscht |
| 02:01 | Nafai | How do I assign a variable at the REPL? |
| 02:01 | Nafai | let won't work because the scope is over once you close the ) |
| 02:02 | jgrant | (def varname value) |
| 02:03 | arbscht | the value is optional, too |
| 02:07 | Nafai | How 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:12 | Nafai | Ah, it's happening earlier |
| 02:19 | slava | Nafai: look who's here |
| 02:19 | Nafai | Hi erg |
| 02:20 | erg | hi Nafai |
| 02:20 | erg | how's the codez? |
| 02:21 | Nafai | Not bad |
| 02:21 | Nafai | Thought I'd pick a little Clojure to see if I like it |
| 02:33 | Nafai | Any ideas on how I would do this? |
| 02:33 | Nafai | I want to have a data file that has a vector per line |
| 02:33 | Nafai | Like: [1 2 3] |
| 02:33 | Nafai | I want to be able to use the reader and process each vector |
| 02:34 | Nafai | Maybe 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:51 | arbscht | Nafai: if you wrap the contents of your file in [] you will get a vector of vectors when you (load-file) |
| 02:53 | Nafai | Oooo |
| 08:48 | ballzack3 | l |
| 08:49 | ballzack3 | hello |
| 08:56 | StartsWithK | how can i create instance of nested class? |
| 08:56 | blackdog | class$nested |
| 08:58 | StartsWithK | Unable to resolve classname: Ellipse2D$Float |
| 08:58 | StartsWithK | i have (import '(java.awt.geom Ellipse2D)) |
| 09:01 | blackdog | try Ellipse2D$Float |
| 09:01 | blackdog | try import Ellipse2D$Float |
| 09:05 | StartsWithK | blackdog, that worked, thanks |
| 09:06 | blackdog | cool, |
| 09:24 | kotarak | Is it possible to have a lazy map like lazy-cons? ie. the value is only evaluated when I access the key. |
| 11:23 | Chouser | kotarak: I was just discussing that with abrooks. |
| 11:24 | Chouser | kotarak: 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:25 | Chouser | ...and unless you're going to assoc onto it, y really might just be talking about a memoized function. |
| 11:28 | kotarak | the 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:40 | Chouser | you could return a memoized function, right? That would cover your use case? |
| 11:42 | kotarak | I would like to just get the value, w/o having to call a function. |
| 11:43 | kotarak | ie. the funcll would be transparw |
| 11:43 | kotarak | oops |
| 11:43 | kotarak | the funcall would be transparent to the program |
| 11:45 | ktne | hello |
| 11:45 | ktne | is clojure the best lisp for jvm? |
| 11:48 | kotarak | there is also a scheme, but don't remember the name. |
| 11:49 | ktne | is that a standard scheme? |
| 11:50 | kotarak | I think so, R5RS IIRC. |
| 11:50 | ktne | i see |
| 11:50 | ktne | i was thinking about something more experimental |
| 11:50 | ktne | not just a standard implementation |
| 12:12 | mac_ | ktne: experimental in what way? clojure is made to easily support concurrent and functional programming |
| 12:12 | ktne | i mean, not just standard scheme implementation |
| 12:14 | mac_ | 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:15 | mac_ | there we go: http://clojure.org/lisps |
| 12:15 | ktne | thanks |
| 12:18 | Chouser | kotarak: 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:19 | Chouser | if it's a memoized function called foo, you could call it with (foo :key) -- same syntax |
| 12:19 | kotarak | hmm... ok. That makes sense. |
| 12:51 | Chouser | hm, and there's a nice memoize already in clojure-contrib. |
| 12:55 | meredydd | Hey all. |
| 12:55 | Chouser | hi, meredydd. |
| 12:55 | meredydd | Is there an idiomatic way of modifying the value stored to a particular key in a map? |
| 12:56 | Chouser | can't modify anything. ;-) |
| 12:56 | meredydd | Chouser: Well, that's the problem. Because an in-place modify is fetch->modify |
| 12:56 | meredydd | whereas with immutability you have to do fetch->modify->writeback |
| 12:56 | meredydd | and 'fetch' and 'writeback' have quite a lot of redundancy. |
| 12:56 | Chouser | user=> (def m {:a 1 :b 2}) |
| 12:56 | Chouser | #'user/m |
| 12:56 | Chouser | user=> (assoc m :a 9) |
| 12:56 | Chouser | {:b 2, :a 9} |
| 12:57 | Chouser | oh. |
| 12:57 | meredydd | I'm doing a lot of: |
| 12:57 | meredydd | (alter map-ref assoc key (do-something-complicated-to (@map-ref key)) |
| 12:58 | meredydd | Was 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:58 | meredydd | but it strikes me as the kind of thing there might be something in the API fo |
| 12:58 | meredydd | r |
| 13:00 | kotarak | Maybe clojure wants you to do it differently? A lot of hassle is often a sign, that you work against the system. |
| 13:00 | meredydd | Indeed. Which is why I'm running it past here before doing that. |
| 13:01 | meredydd | On 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:02 | kotarak | Maybe you should pass it on to a function instead of storing it somewhere? |
| 13:02 | meredydd | so 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:02 | meredydd | kotarak: I'm familiar with the basics of functional programming. This is one of this program's three pieces of state. |
| 13:06 | meredydd | (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:10 | Chouser | meredydd: 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:11 | Chouser | the pattern you described shows up a couple times in ants.clj |
| 13:11 | meredydd | Chouser: 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:11 | meredydd | (defn alter-map-val |
| 13:11 | meredydd | [map-val key alter-fn & args] |
| 13:11 | meredydd | (assoc map-val key (apply alter-fn (get map-val key) args))) |
| 13:12 | Chouser | meredydd: 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:12 | meredydd | Seems nice to me. |
| 13:13 | meredydd | Okay, that just made the whole statement fit on one line. That's promising. |
| 13:14 | Chouser | meredydd: can you paste an example usage? |
| 13:14 | Chouser | you'll use ref-set now instead of alter? |
| 13:14 | meredydd | {:test #(assert= (alter-value {:a 4 :b 5} :b #(+ %1 %2) 1) {:a 4 :b 6})} |
| 13:15 | meredydd | Usage goes: |
| 13:15 | meredydd | (alter user-roles-by-component (alter-map-val victim #(disj % [user, role]))) |
| 13:15 | meredydd | (where the #(disj...) stuff is the application-specific stuff - removing something from taht set) |
| 13:16 | meredydd | aaand I have to go. |
| 13:16 | meredydd | bbl, might discuss this further if you're around, Ch |
| 13:16 | meredydd | *chouser |
| 13:17 | Chouser | Hm! I think it looks good! |
| 14:53 | Chouser | meredydd: I know you're not here, but that's not quite right |
| 14:55 | meredydd | ? |
| 14:56 | meredydd | Chouser? |
| 14:56 | Chouser | oh, hi. |
| 14:56 | Chouser | alter's second arg is a fn, so either alter-map-val needs to return a fn, or something else needs to be different |
| 15:08 | Chouser | (defn alter-map-val [m key alter-fn & args] (alter m assoc key (alter-fn (@m key)))) |
| 15:08 | Chouser | (dosync (alter-map-val victim :a #(disj % [user, role]))) |
| 15:11 | Chouser | You could have a commute-map-val too, I suppose |
| 15:58 | Lau_of_DK | public class MyClass implements JButton {} -- How is this done in Clojure? |
| 15:59 | Chouser | gen-class or proxy |
| 16:00 | Lau_of_DK | got a brief example? |
| 16:01 | Chouser | (proxy [JButton] []) will create a new instance of a class derived from JButton. |
| 16:02 | Chouser | xml.clj includes an example of proxy |
| 16:04 | Lau_of_DK | Thanks, exactly what I needed to know |
| 16:05 | Lau_of_DK | Chouser - Maybe you should look through the documentation on Clojure.com? I find it somewhat lacking in a few various areas |
| 16:06 | Chouser | proxy is documented on the java-interop page |
| 16:11 | Chouser | scgilardi: I noticed your memoize in clojure-contrib today. Thanks for that! |
| 16:12 | scgilardi | you're welcome! I noticed the discussion earlier about alter. does memoize show how to do something similar more simply? |
| 16:14 | Chouser | I 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:15 | scgilardi | ok, 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:16 | Chouser | yeah, the alter stuff was an different topic. |
| 16:16 | scgilardi | "commute" -> "alter" |
| 16:16 | scgilardi | ok cool |
| 16:17 | Chouser | I 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:17 | Chouser | alter-map-val or something like it just reduces the repetition. |
| 16:18 | scgilardi | alter returns the new value. is it to try to capture the previous value? |
| 16:18 | scgilardi | (actually I haven't yet used alter... I'm familiar with commute) |
| 16:19 | Chouser | both 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:20 | Chouser | ...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:22 | scgilardi | interesting ok. I'll work through an example to understand it. |
| 16:24 | Chouser | (def m (ref {:a 1})) |
| 16:25 | Chouser | (dosync (commute m assoc :a (inc (m :a)))) |
| 16:25 | Chouser | m and :a are each mentioned twice |
| 16:26 | Chouser | (dosync (alter-map-val m :a inc)) |
| 16:26 | Chouser | with the alter-map-val I gave above, m and a are only mentioned once each. |
| 16:27 | scgilardi | ok I see now, thanks |
| 16:28 | Chouser | but as you said, commute would be good too, so maybe it would be useful to also have commute-map-val |
| 16:28 | scgilardi | or to make alter or commute an argument rather than part of the function name |
| 16:28 | Chouser | sure |
| 17:37 | meredydd | Yo, Chouser |
| 17:37 | meredydd | You said you had a bug in my map-alter fn |
| 17:53 | Chouser | yep -- did you actually try your version? |
| 17:55 | Chouser | meredydd: http://clojure-log.n01se.net/date/2008-07-06.html#14:56b |
| 17:56 | meredydd | Chouser: Not yet, tes |
| 17:56 | meredydd | *not yet |
| 17:58 | meredydd | Chouser: Hmm. Comp crashed, and I've lost that file. Hold on... |
| 17:58 | meredydd | Oh, yes, you're right. |
| 17:58 | meredydd | (alter user-roles-by-component (alter-map-val victim #(disj % [user, role]))) is wrong |
| 17:59 | meredydd | (alter user-roles-by-component alter-map-val victim #(disj % [user, role])) |
| 17:59 | meredydd | That's right. |
| 18:06 | Chouser | oh! |
| 18:06 | Chouser | very well then.. that way you can use commute without needed a commut-map-val |
| 18:09 | meredydd | Chouser: ha! |
| 18:09 | meredydd | I just read that log, and was about to make the same point. |
| 18:09 | meredydd | "alter" was the wrong name to give this fn. |
| 18:09 | meredydd | It should be "replace-map-val" |
| 18:09 | meredydd | (or, in fact, "replace-assoc-val", but that's really quite long) |
| 18:10 | meredydd | I named it after "alter" because I was thinking about how you can do this: |
| 18:10 | meredydd | (alter x + 1) |
| 18:10 | meredydd | or (alter x assoc :key :value) |
| 18:11 | meredydd | You can now thread this some distance: |
| 18:11 | meredydd | (alter user-roles-by-component alter-map-val victim disj [user, role]) |
| 18:12 | Chouser | yikes |
| 18:12 | meredydd | (kinda a reverse "->") |
| 18:13 | meredydd | (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:14 | Chouser | :-) |
| 18:19 | Chouser | well, it's very hard for me to think through how that works, but it's hard to argue with the brevity. |
| 18:19 | Chouser | I suppose it wouldn't take long to get used to the pattern. |
| 21:46 | arohner | has anyone here played with compojure? |