#clojure logs

2008-06-19

07:12asbjxrnyrb, I don't think so. That is what rhickey suggested I use.
07:23yrbasbjxrn: I am divided if I like it or not, on onehand it makes it explict that I am using a nested class
07:50asbjxrnI guess there have to be some sort of separator anyway as clojure need to find thr class
08:37cemerickChouser: Yesterday you wrote "(Math/pow 2 10)" -- which I assume is treating the Math class as a namespace, and all of its static functions as functions in that namespace. How is that set up (just evaling that sexp on my end yields an exception)?
08:37blackdogit's new in svn
08:38cemerickah-ha
08:38cemerickblackdog: thanks
08:38blackdogthere's no setup it just works :)
08:41cemerickYeah -- Rich's checkin comment for r910 indicates that that feature is "experimental". Is there a discussion of it somewhere?
08:42blackdogyes http://groups.google.com/group/clojure/browse_thread/thread/bc005da4989468c7#
08:56cemerickfeh, I don't know how I missed that.
09:34cgrandhmmm, good to know: sets can't be used to implement canonicalizing mappings
09:34rhickeycgrand: ?
09:35cgrand(meta (#{#^{:id "in set"} []} #^{:id "not in set"} [])) returns {:id "not in set"}
09:35cgrand(contrived one liner)
09:37cgrandI expectied taht a set would return the key and not the arg if found
09:42rhickeythat's what I get for enabling get on sets, eh?
09:43cgrand?
09:44rhickeysets as functions of their keys
09:44cgrandyup
09:49Chouser_aren't you passing two args to a hash-set?
09:51rhickeycgrand: fixed
09:53drewrIn general, does a NPE signify a bug in Clojure, or could I be doing something wrong to cause it?
09:54rhickeythe only thing that is certainly a bug in Clojure is a verify error, for all else check your code first :)
09:55drewrLet me rephrase the question. Even if my code isn't correct, should Clojure be handing out NPEs?
09:56drewrIsn't that akin to my writing something in Python and getting a segfault?
09:56rhickeyChouser: that's a set with a metadata-tagged empty vector member being used as a function of another metadata-tagged vector, yielded arg (broken) rather than set member (fixed)
09:57drewrI'm willing to spend the time writing bug reports if clojure could handle the situation more gracefully.
09:57rhickeydrewr: no, NPEs are often user bugs, and they are catchable by user code - what should Clojure do with them?
09:59Chouser_drewr: python libs don't hand out segfault. Java libs often throw NPEs.
10:00drewrChouser_: Ah, I didn't know that was a common failure for Java libs.
10:01cgrand1rhickey: thanks for the fix
10:01Chouser_Well, that's my impression anyone. Someone that actually knows Java may correct me. :-)
10:01Chouser_s/anyone/anyway/
10:02rhickeySo in Python you get a TypeError thrown - what's the real difference?
10:03Chouser_don't we get type errors in clojure too?
10:03Chouser_ok, thanks for the set explanation. I get it now. :-)
10:03rhickeyyou can get all sorts of errors, my point is they throw exceptions, you get stack traces etc, there's no magic to Python here
10:04rhickeyneither dumps core
10:11yrbrhickey: have you got any plans to implement nested class access along the lines of the recent static member access?
10:17yrband do you think it would be a good idea for import to load the nested classes into the namespace automatically?
10:33rhickeyyrb: no, nested classes have composite names - why, don't like $ ?
10:37cemerickTrain of consciousness: I've got an interface with methods foo and bar. My impulse is to use a map (or structmap) so I can do stuff like (:foo obj) rather than (. obj (foo)), and so that changes are easy and efficient. However, I then need a function that will pop off proxied instances that implement that interface so as to interoperate, and a function that will unpack instances coming in from Java into a map (or structmap). This basically sucks -- I a
10:37cemerickI guess this is getting back to the data-design topic. I'm probably making this harder on myself than it needs to be.
10:39rhickeycemerick: you can say (.foo obj)
10:39rhickeyboth Clojure and Java code create instances of this interface?
10:39cemerickYeah, potentially.
10:40cemerickThe nice thing about using simple maps is that changes are so efficient. Copying on changes is not something I want to do (although I guess that'd be required if I subclassed PStructMap).
10:42cemerickA bunch of multimethods would essentially give me everything I want, except it'd require more code than what seems reasonable for this case.
10:44yrbrhickey: it isn't the $, (I actually like the distinction) it is more not having to explictly import the nested classes of an class already imported
10:45yrbthought I am not sure if I would want that now...
10:47yrbI have mostly finished my awt/scene graph wrapper, and I don't think that style of java is very common outside the gui libs
10:48rhickeycemerick: so you want to use this interface functionally?
10:49rhickeyJava implementations of the interface are unlikely to be functional
10:49cemerickrhickey: well, this particular interface is read-only, so that's something
10:49rhickeybut you can implement an imperative interface with a ref to a map as its state
10:50cemerickFurther, the interface is ours, so that helps, too :-)
10:51rhickeythat's good, I guess my 2 cents is, don't hide/avoid/wrap the interface, use Clojure goodness in your implementation of it
10:51cemerickrhickey: Sure, and considering the general case, where we implement the interface and use a ref and map as a backing store -- it's obviously preferable to touch that ref and map when you're on the clojure side of things.
10:52cemerickThe tricky part is being able to route and process instances that are implemented differently -- which brings me back to multimethods, I guess.
10:52rhickeycaring about how they are implemented is a warning sign
10:53cemerickI know -- that's why I'm floundering a bit here :-)
10:54cemerickI could just not care how anything is implemented, and always copy on every mutation. Of course, that sucks -- perhaps an eager optimization, but perhaps not.
11:00rhickeyah, I see, your interface is read only and you'd like to treat instances persistently?
11:00cemerickindeed
11:01rhickeyI'm running now, perhaps can follow up later...
11:01cemerickYeah, we'll see how the rest of the morning goes. :-)
11:17cemerickThis is (mostly) spurious, but shouldn't reduce take the initial value first, then the function and sequence? The way it is now, the (typically concise) initial val is in between two (potentially) verbose sexps.
11:22cgrand1cemerick: the current args order is mnemonic (at least for me :-) )
11:23cemerickcgrand1: it's just the opposite for me, but it's all moot now :-)
11:24cemerickdoes the literature generally use [fn, val, seq] order, or is that ordering typical from other lisps, or...?
11:24Chouser_the initial value is immediately before the seq that forms the rest of the values. it does make a kind of sense.
11:25Chouser_(reduce list 0 [1 2 3])
11:25cemerickChouser: Yeah, I can see that. I always think of seed values as binding more to the fns that they travel with. A totally personal mental model sort of thing.
11:26Chouser_I admit I generally have to look it up.
11:27cemerickFrom a totally practical standpoint, if you've got a fn of any complexity, finding that lonely initial value that follows it requires a little squinting.
11:27cemerickAt what point does a hash map tip over into a tree map?
11:27Chouser_never, I think.
11:28Chouser_PTreeMap is sorted, PHashMap is not, and I don't think there's any automatic conversion from one to the other.
11:29cemerickMy apologies -- I forgot that PHashMap is a tree, internally.
11:31Chouser_I thought that might be it. I don't know how quickly it grows to what kinds of depths.
11:34Chouser_it'd be interesting to ask a particular hash what it's shape and depth is.
11:35cemerickOne of Rich's screencasts goes into a couple of details about height and big-O guarantees.
11:39cgrandmax depth: 6 (or 7, not sure of the details), 32 chlidren per node
11:40Chouser_but surely being a hash means the first node won't have a full 32 before it starts getting sub-nodes, right?
12:56Chouser_(double 2) is not equal to 4
12:57drewrHeh.
13:15Chouser_and so far I've had friends guess that it returns: 22, (2 2), and T
13:16abrooks2.0?
13:16abrooks:)
13:16Chouser_cheater.
13:17abrooksNot at all. I hadn't been in #noise yet. I just started here.
13:18Chouser_well, I guess I have to take your word for it, don't I? ;-)
13:18abrooksIndeed you do, unless you're snooping my gnu screen sessions.
13:19abrooksI did know that the unboxed numbers made their recent debut and you eliminated several alternatives above.
14:01Chouser_If I want to refer generically to a sequential collection, including things like Java array, Clojure vectors, Clojure lists, etc. what's the best word to use?
14:02Chouser_I would use "list" but that has specific meaning in Clojure.
14:03rhickeyChouser: 'sequential collection' ?
14:04Chouser_and so my variables can be named seqCollA, seqCollB. ;-)
14:04rhickeythese are Java variables?
14:04Chouser_well, I was trying to use the same name in both. Maybe I shouldn't bother.
14:05rhickeyfred/ethel/ricky/lucy works for me :)
14:05Chouser_yeah.
14:06abrookslittlericky gets a bit long though.
14:06jmbrhi
14:06Chouser_hi
14:22cgrandchouser_: about hashmap depth, I remembered I had a heap dump somewhere, so I ran some queries on it: hashmaps of ~400 elements seems to have nearly no (ie 1-3 per map) node of depth 4
14:22Chouser_cgrand: cool, thanks.
14:23rhickeyif hashes are good, depth should be roughly log32N
14:23rhickeynever more than 6
14:26Chouser_if two things hash the same, is there a linear bucket at the bottom of the tree?
14:26rhickeyyes
14:26Chouser_I'm looking at the code and still can't tell. :-)
14:27Chouser_ok, thanks.
14:27rhickeysorry the persistent data structure code is lean and, well, mean
14:28Chouser_hm, but probably only if the hash is fully identical, right? You get more depth in the tree before you get the linear bucket?
14:28rhickeyright, that's the 'trie' aspect
14:41abrooksThis has bugged me since I came across JudyArrays long ago. Unfortunately, I'm not getting any traction. :-)
14:41rhickeyyes, it's very annoying
14:42Chouser_can we also rename map or map, and perhaps double?
14:43Chouser_other sciences go and invent new latin-like words, don't they?
14:56Lau_of_DKEverything needs to stay exactly the way it is
14:57Lau_of_DKIve had enough trouble learning Clojure, coming from Lisp
14:57abrooks:)
14:58abrooksLau_of_DK: Perhaps we could use Danish terms instead of Latin?
15:07Lau_of_DKhaha - you obviously dont know Danish
15:07Lau_of_DKSpeaking 100% objectively: Its one of the most disgusting languages on earth
15:10abrooksLau_of_DK: You are correct. My Danish vocabulary is (). :)
15:11Lau_of_DKuser> (. Integer (toString 11121231230000))
15:11Lau_of_DK"1560900656"
15:11Lau_of_DKThis is not what I expected...
15:12Lau_of_DKrhickey, is this your doing? Something is broke in the BigInt module?
15:15Chouser_Lau_of_DK: I think your BigInteger is being converted to an Integer in order to be passed to Integer/toString
15:15Chouser_Perhaps you wanted (.toString 11121231230000)
15:16abrooksLau_of_DK: I thought English held the record for "Most Disgusting Language on Earth" (or maybe it was Klingon...).
15:16Lau_of_DKChouser, ... Sure - so .toString is related to what.. if not Integer?
15:16Lau_of_DKabrooks, I think it might actually be Perl, then Danish :)
15:17Chouser_.toString is being called on whatever the actual type of its argument is -- in your example, BigInteger
15:17rhickeyuser=> (int 11121231230000)
15:17rhickey1560900656
15:17Lau_of_DKAah I see
15:17Lau_of_DKSo as I was just about to complain about Dynamic typing, its just because I dont really understand it, Clojure is a bit more clever than I had anticipated
15:19rhickeyuser=> (str 11121231230000)
15:19rhickey"11121231230000"
15:20Lau_of_DKthanks rhickey
15:41Lau_of_DKrhickey, would it be possible to compare the speeds of C, Python and Clojure for some computations? Have anything along those lines been done?
15:50rsynnottLau_of_DK: there was a python/clojure one on reddit recently,I think
15:52Lau_of_DKThanks rsynnott , I'll go look
15:57cemerickI *think* the data-design issues I was going on about earlier *might* be more general than I thought -- similar issues arise if one were to implement (for example) a tree data structure in Clojure whose interface is defined in Java, but should ideally have a richer interface in Clojure. This might just be the cost of doing business with Java callers and callees, I suppose.
16:00lisppaste8Lau_of_DK pasted "Java Heap...?" at http://paste.lisp.org/display/62507
16:00Lau_of_DKGents- Simple task. Euler style. Find the first x that produces an x! that has 7^20 trailing zeroes... My code fries the Java Heap in about 5 - 7 minutes, so I assume Im doing something wrong ?
16:11Lau_of_DK(14 minutes actually)
16:13Chouser_thats a lot of zeros
16:13Lau_of_DKYes ma'am
16:15rhickeycemerick: one option is to offer persistent 'mutation' in the interface, e.g. like IPersistentMap does
16:15Lau_of_DKMaybe its not supposed to be bruted though - There's a pretty clear pattern showing in the number of trailing zeroes
16:17cemerickrhickey: Yeah. Over time, we'll be doing exactly that for those interfaces we control and we can change in that way without freaking out our users.
16:20cemerickIn the general case though (or simply when you don't have that option), it feels like there should be a relatively direct way to pass around proxied maps (for example), and when you get such an object back, be able to dereference the proxy to get a hold of the underlying map again. Totally doable with a couple of macros and multimethods (and probably an interface to allow the dereferencing bit). We'll see how motivated I get as I go along.
16:20cemerickrhickey: Any further suggestions you have are certainly welcome. :-)
16:21rhickeydefine and implement another interface for access to that implementation stuff
16:23rhickey(ah, you got that already, nevermind)
16:26cemerickrhickey: times like these, I wish clojure had a gen-and-save-interface ;-)
16:27rhickeyI might consider that
16:28cemerickIn a year or so, clojure will be the best interface to asm around.
16:36Lau_of_DK(gen-and-save) = (save-lisp-and-die) ?
16:38drewrLau_of_DK: No. It's for created a (non-proxy) Java class.
16:39Lau_of_DKAh ok
16:40drewrIt's actually GEN-AND-SAVE-CLASS now.
16:41drewrThe -SAVE part refers to the fact it actually writes the bytecode to a .class file.
16:41drewrPretty cool. Check out genclass.clj.
16:42drewrThe world would be a different place.
16:42Lau_of_DKdrewr, did you know that rhickey is an alias for Skynet ver. 1.0 ?
16:44drewrLau_of_DK: Surely he's at least r2 or r3.
16:55cemerickIs there a way to install a method by referring to an existing fn that I'm missing somewhere?
16:56rhickeycemerick: a proxy method?
16:57cemerickhrm, no -- for multimethods. So as to say (defmethod foo :bar some-fn)
16:58cemerickJust if I happen to have an appropriate fn floating around that is independent as well as useful as a multimethod.
16:58rhickeynot right now, you'll have to forward to it
17:39meredyddHey
17:39meredyddWho's responsible for the 'set namespace?
17:40Chouser_rhickey himself
17:40meredyddI just discovered it today, and it's The Shit.
17:40meredyddAh.
17:40meredyddThat...doesn't surprise me at all.
17:41meredyddIt's that beautiful :)
17:41Chouser_:-) Gotta run.
17:42meredyddIn any case, I'd like to *beg* rhickey to make more noise about that feature. It's really something.
18:55shizzy0I have a weird idea, that I'm trying to do. Can I make an anonymous macro? (mac [x] ...)
18:56rhickeyshizzy0: no, how would it be called?
18:57shizzy0(let [m (mac [x] ...)] (m stuff...))
18:57shizzy0?
18:58rhickeyah, local macros like CL macrolet, and symbol-macrolet - nope, don't have those yet
18:59shizzy0(defmacro mac [parameters & body]
18:59shizzy0 `(let [f# #^{:macro true}(fn ~parameters ~@body)]
18:59shizzy0 (. (var f#) setMacro)
18:59shizzy0 f#))
18:59rhickeyit's not that simple
19:00shizzy0That's what I was playing with, but it doesn't like (var f#).
19:00shizzy0Right, it seems like a good opportunity to understand more of how things work.
19:01rhickeythe compiler needs to participate in macroexpansion, right now there are no local macros
19:02shizzy0[nods] ok.
19:02shizzy0I'm just trying to stretch out in clojure, and see what I bump into.
19:02rhickeyglobal vars can be tagged as macros, and their global definitions treated as macroexpanders, but local functions are not available to the compiler as macroexpanders
19:03rhickeyIt's something I would have to add, not something you can do with macros
19:04rhickeythe concept is sound - I particularly miss symbol-macrolet
19:06shizzy0good to hear.
19:09shizzy0that the concept is sound. I hadn't used it in CL. :)
19:13shizzy0btw, rhickey, I really like what you've done. I haven't done anything with Java for a long time now, but I could see myself actually working in the JVM now.
19:14rhickeygreat!, thanks
19:22meredyddrhickey: By the way, I just discovered the 'set namespace, and am very impressed.
19:22meredyddAlthough I am somewhat confused by the (->) macro. The docstring is a bit, um, opaque.
19:22rhickeycool, I don't think anyone else has looked at it
19:23meredyddYeah...I'm really hoping you'll change that - write it up as one of the pages in the sidebar, perhaps?
19:23rhickey-> threads the argument and successive returns as the first arg of subsequent forms
19:23meredyddI really think that having the relational algebra expressible natively is a really powerful thing
19:23rhickeyyeah, I hope to do more with it
19:24meredydd(plus, it provides something I can point to and say - "Look! Native sets and maps in a Lisp is a beautiful thing"
19:25rhickeypersonally I think it is a shame that Lisp has been tied to lists for so long
19:26shizzy0ok, I don't know if this was intended, but I think this is pretty neat.
19:26shizzy0(map eval (map and '(true false) '(true true)))
19:26meredyddrhickey: right...so if I did (-> 1 (- 2) (+ 1)) it comes out as 3
19:27shizzy0The fact you can apply and map macros, and you'll get something weird out of them, but if you eval them, you get the actual results you'd naively expect.
19:27meredyddOh, yeah...actually, that was something I wanted to say, too.
19:27meredyddI tried to do (map) with (and), and got some *mighty* funny results.
19:27rhickeymeredydd: 0, no?
19:28meredyddTook me quite a while to figure out what went wrong. Any chance we could have a warning when some stupid programmer tries to do that kind of thing?
19:29shizzy0I got 0 for meredydd's expression.
19:29meredyddIt's not always obvious which ops are macros and which are fns, and I could conceive of certain calls changing from one to another, say, between library releases
19:29meredydd(Yes, sorry. I meant 0, which is what the interp gave me)
19:29rhickeyand is a macro, so can't be mapped, but you can do (map #(and %1 %2) ...)
19:29rhickey(map #(and %1 %2) [true true] [true false])
19:29meredyddI know - that's what I did. Trivial change, once I figured it out.
19:30meredyddBut as it stands, if you try to use a macro as a fn value, it lets you
19:30rhickeyI might be able to catch attempted use of macros as values...
19:30meredyddIt just uses the macro's code-munging function instead
19:30rhickeyright
19:31meredyddwhich caught me somewhat by surprise.
19:31shizzy0rhickey: but if you eval the expression you get from using a macro as a function, you get the right value it seems like. I actually kind of like that unification of macros and functions.
19:31meredyddAny chance of a molly-guard for the rest of us? I agree with shizzy0 that it might be cool to be able to throw macros around and do interesting things with them
19:32rhickeysomething being a macro or function is part of its interface
19:32rhickeyin practice things don't toggle between
19:32shizzy0For instance, (apply and '(true false)) doesn't work but, (eval (apply and '(true false))) does.
19:32rhickeyyes, as I said above, I might be able to flag it
19:32meredyddPerhaps like the reflection warnings - some explicit flag to say "I know what I'm doing, don't warn me about the fact that I'm taking this macro"
19:32meredyddThat'd be great AFAIC.
19:33meredyddOh, and one more, while I have you here. Looking at the doc for (->), I understand why I was so confused.
19:34meredydd...oh, no, scrub that. The doc's right, my brain's wrong. Ignore.