#clojure logs

2008-09-10

07:49rhickeyChouser: js persistent vector is neat!
08:59ChouserI was surprised at how much of the code ended up almost identical to the Java.
09:28Chouserrhickey: oh, I didn't notice you weren't here.
09:29ChouserI was surprised at how much of PersistentVector.js ended up almost identical to the Java.
09:29rhickeyright
09:29rhickeythat's good
09:29ChouserI'll have to do some timing tests to make sure using a closure structure like that isn't too slow
09:30ChouserI'm also not sure about trying to mimic the Java inheritence heirarchy.
09:30rhickeyslow vs what? what's the alternative?
09:31Chouserusing prototypes, which is the "normal" way to do "classes" in JavaScript.
09:31rhickeywhy didn't you use prototypes?
09:32Chouserthey expose all object data as public mutable fields -- nothing private, no protection from assignment
09:33ChouserLast time I looked into performance, closures were slightly slower to create, but slightly faster for making method calls. But JS engines have changed since then.
09:34rhickeyYeah, I have a feeling you're not going to get the perf from V8-like things without prototypes
09:35aking
09:36Chouserok, we'll see. The textual difference in the .js isn't very big, so it'll be easy enough to try some different arrangements.
09:36rhickeyI wouldn't worry about access - JS is kind of a free for all anyway. Accident vs malice...
09:37Chouserhm.
09:37rhickeybut there is a certain elegance to the closures for sure
10:05StartsWithKto use genclass with ns, do i create /package/subpack/Class/Class.clj or /package/subpack/Class.clj
10:05StartsWithKand inside it do i deklare (ns mypack.Class) or (ns mypack) and write functions like (defn init[this] ..) or (defn Class-init [this] ..)
10:09Chouser/package/subpack/Class.clj
10:10Chouser(ns package.subpack)
10:10StartsWithKand (ns package.subpack) with (defn Class-init[this]) ?
10:10Chouser(defn Class-init ...)
10:10Chouserright, except init doesn't get "this"
10:11StartsWithKwait, init is constructor?
10:11StartsWithKwhat is 'init' method then
10:13Chouserit gets called at object construction time with the args given to the constructor call
10:13ChouserMust return [ [superclass-constructor-args] state]
10:23StartsWithKand, how will i implement real init method?
10:23StartsWithKsorry, maybe i didn't understand this (defn Class [..] ..) is constructor, or (defn Class-init ..)
10:24Chouserdon't do (defn Class ...). Use (defn Class-init ...) to define what should happen when your object is constructed.
10:25StartsWithKhmm..
10:26StartsWithKwhat should i do about applets init method then?
10:26cemerickStartsWithK: you can name the "constructor" function anything you want in the gen-class spec
10:26cemerick:init 'my-init-fn
10:27Chouser...and then (defn Class-my-init-fn ...)
10:34StartsWithKoh i see
10:34StartsWithKthanks
11:35drewrOh wow. I love how merging a map into a sorted map keeps the sorted map.
11:41cemerickThe fact that the generated API docs don't filter back into the topical pages (Data Structures, Sequences, etc) is unfortunate
11:49ChouserI was thinking it might be useful to tag functions with related keywords (types they operate on plus some other categories) and then have a page per tag
11:50Chouserthat way if you have a vector and want to know what you can do with it, you'd have some place to look that would be up-to-date
11:50rhickey_Chouser: just hopped on - context?
11:50ChouserThis was one of my gripes about CL -- finding the one function you need out of the hundreds available was daunting.
11:50rhickey_Chouser: did you use apropos?
11:51Chouserrhickey_: cemerick just noted the topical pages don't get updates from the generated API docs.
11:51Chouserrhickey_: I don't think so.
11:51rhickey_Chouser: right, and moving forward I;d like the topical pages to be more prose and less reference, letting the latter fall to API page
11:52ChouserI agree with that, except for the whole it leaves in getting from an idea to the existing function that implements it.
11:52Chousers/whole/hole/
11:52cemerickapropos never worked for me (not that I was in CL-land very long) -- i.e. (apropos "map") in clojure wouldn't list assoc, etc
11:53cemerickChouser's notion of tagging fns sounds very appealing, at first blush.
11:54rhickey_Chouser: but see the (newer) doc for sets, which contain links to API sections
11:55rhickey_cemerick: but (find-doc "map") does
11:56cemerickrhickey_ has a magic ability to inject into my running clojure repl exactly the functions I'm looking for! That's what I call remote code loading. :-P
11:57rhickey_cemerick: tagging is like semantic web - manual extra work, find-doc and things like it are like google - automatic, based on work already being done
11:57cemerickFor me, an ideal reference would be the prose-oriented topical sections, with some abbreviated output from find-doc appended to each section
11:58Chousergah, I've still got a bug in PersistentVector.js. Debugging this might me easier if I had a clue what it's doing. ;-)
11:58rhickey_one problem is the huge overlap in the abstractions - so many functions can be used on almost anything
12:00Chouser1000 items work fine. above 10000 something's broken.
12:00rhickey_cemerick: see the section on sets here: http://clojure.org/data_structures, lots of links in prose
12:01cemerickrhickey_: yeah, I saw -- but those links fall into that manual extra work category, so the new super-nifty fn related to sets won't be noted there until you decide to revisit the prose
12:02rhickey_cemerick: well, the prose is going to exist anyway. Maybe a browser plugin that, given a highlighted word, went to API#theword ?
12:03cemerickhrm, greasemonkey to the rescue
12:03rhickey_cemerick: but yes, for new stuff its find-doc
12:03Chouser(find-doc "set") is pretty noisy
12:04cemerickChouser: moving a search like that out of the repl will do wonders; I think I have my next 2-hour side project :-)
12:29cemerickI need to read the docs more often. I didn't realize that named anonymous fns were available until 5 min ago.
12:39shoovercemerick: what are you doing with greasemonkey?
12:41cemerickshoover: nothing at the moment. We use it for a couple of ad-hoc integrations between internal systems here. I have an idea to use it to build an easy/fast clojure API lookup tool.
12:43pjstadigok
12:43pjstadigi made a .deb of clojure
12:44pjstadigit wasn't as hard as i expected
12:44Chouserpjstadig: great!
12:44pjstadigi used the bin scripts from http://github.com/jochu/clojure-extra/tree/master
12:45pjstadigi'm extremely newb at this though, so i'm not sure what to do next
12:45pjstadigi was thinking of setting up a personal package archive on launchpad.net
12:46pjstadigand i guess maybe the debian build infrastructure should be merged back into the clojure source?
12:46pjstadigor I guess i could maintain it separately
12:47kotarakIs there a way to delegate method calls of an interface to a specific component? (More a Java question....)
12:54Chouserpjstadig: I'm not sure either -- can you submit it to the debian project itself?
12:55Chouserkotarak: what do you mean by component?
12:55pjstadigto get clojure included in debian i, or someone, would need to become a debian developer and the official maintainer of the package
12:56pjstadigit would also be fine (i think...for now) to just build a .deb along with a .zip and distribute them on sf.net or in whatever way people can download clojure
12:57kotaraksay I have: class A implements IFoo { AFoo f /* <- implements IFoo */; delegate IFoo to f /* ?? Possible? Instead defining all IFoo functions wrappers. */; void someIFooFunc() { return f.someIFooFunc(); } /* <- very tedious and boring */ }
12:58Chouserahhh... hm.
12:58ChouserI imagine you could cook up a macro to generate a proxy form that would do that.
12:59kotaraksomething like snit for Tcl would be nice.
12:59Chouserkotarak: ever written a macro? they're fun
13:00kotarakchouser: have written lot's of macros. They are fun. :)
13:00Chouserthe problem is that it's pretty rare to run into a problem where a macro is the right solution.
13:01ChouserBut I think you found one. If you don't write it, I just might.
13:01kotarakLet me try.
13:01kotarakI will have a look and some inspirations from snit.
13:02kotarakIt's pretty nice in this respect. (It's actually a OOP system for Tcl, which does not have inheritance but only delegation)
13:02Chouserhuh.
13:07kotarakWhat's the typical OOP example? class Human { method eat() { hungry = false }; lots of other stuff... }; class MaleHuman { method eat() { super(); say "Buuurp" } }
13:07achim_prhickey_: what about a bit of markup for clojure doc strings to avoid the tagging extra work? it had to be very lightweight though ...
13:08achim_ppeople writing docs could add hints about terms refering to clojure types or functions, something like: "Returns a :map: that consists of the rest of the :map:s |conj|-ed onto the first."
13:09kotarakWith snit this looks like: class Human (the same)...; class MaleHuman { component Human h; delegate * to h; method eat() { h.eat(); print "Buuurp" } }
13:10kotarakachim_p: maybe something, which is already used? like restructered text or something along the lines...
13:11rhickey_achim_p: I'd hate to reduce the readability in the repl
13:14blackdogcemerick, is enclojure compiling using clojure head right now?
13:15blackdogoh, that's not really the question, are you using it with the netbeans RC
13:35Chouserrhickey_: PersistentVector.root shouldn't get longer than 32?
13:35cemerickblackdog: I haven't built enclojure in a while; we're using it in conjunction with clojure r1006, I believe.
13:36blackdogok, thanks, i had troubles with nb6.5 and decided to leave it
13:37cemerickI'm using it with 6.5 right now -- it required a small patch so as to not break all debugging (including java debugging)
13:37blackdogah, that's what i ran into then
13:38blackdogi didn't have the gumption to investigate
13:38cemerickblackdog: here's the discussion; I describe the patch we're using right now at the end of my message: http://groups.google.com/group/enclojure/browse_thread/thread/b17883c64f80c2af
13:38blackdogta, coolio, I'll give it a shot once the latest downloads
13:48achim_pkotarak: restructured text looks nice (at first glance), i.e. very much like plain text. i didn't intend to propose using || and ::, they were merely examples of what i meant by lightweight.
13:50achim_prhickey_: yes, repl readibility would be a problem. print-doc could be changed to cull the markup, of course. tool support could benefit from doc markup altogether (editors with highlighting, cross references in doc browsers etc.)
13:50achim_pbut i certainly understand your concerns
13:51kotarakachim_p: no offence intended. But before one invents new formats, one should check what's already there. restructered text, markdown, etc... I use NaturalDocs to extract the docs from the sources. That provides indexes etc. w/o disturbing the REPL readability too much.
13:56rhickey_Chouser: no, no node should ever get longer than 32, it's a 32-way tree, 5 bits per level
13:56achim_pas long as it's not javadoc/html, i'm fine with it ;-)
13:57kotarakachim_p: yeah, javadoc is not the best choice....
13:59rhickey_kotarak: do you have a clojure config file for NaturalDocs?
13:59Chouserrhickey_: ok, thanks. I think my problem is when the tree depth goes to 3
14:00hoeck_rhickey_: have you looked at print.clj?
14:01rhickey_hoeck_: yes, will incorporate soon, thanks! Looking to get a release out and may not change anything but bugs before then
14:03kotarakrhickey_: Well...., I have to work around some issues with the docstrings. I don't want to duplicate the docs. So I decided to use | as additional "comment". I can live with |, but it's not perfect of course.
14:03lisppaste8kotarak pasted "docstring with naturaldocs" at http://paste.lisp.org/display/66606
14:04kotarakBut I like the way it looks in the source. Although it's pretty verbose. I don't know. That's the price for something like nd or robodoc, I guess.
14:05rhickey_kotarak: so what does NaturalDocs do for you?
14:05hoeck_rhickey_: aha, ok, thanks too, learned a lot about *warn-on-reflection* and multimethods
14:06rhickey_hoeck_: although it would be nice to have in as a practical example of multimethods
14:07kotarakrhickey_: it recognises the foo is a function belonging to a namespace. It uses this information to create a set of html files with indexes for namespace, functions, structs, whatever. One can easily link to a function (<foo>), even to another namespace (<other.namespace.foo>) (Note: last ., not / another limitation, I guess).
14:09hoeck_rhickey_: so will you keep the original RT.print()?
14:09kotarakOne could probably write a Perl module for full support. But to be honest: my Perl is too rusty and I'd rather spend my time with Clojure instead of Perl...
14:11rhickey_hoeck_: at the end of the day, no
15:23kotarakIn case I have a jar with some .clj inside and a running REPL. When I update the jar, is this available in the Repl? Or do I have to restart?
15:40cemerickkotarak: if the updates are to .clj files, then you just need to re-load those files; if you update already-loaded classfiles, then you have to restart the jvm
15:40kotarakcemerick: That's ok. Thanks.
15:41cemerickThere's ways around that with subordinate classloaders and such, but if you need generalized code reloading, then you're better off using a framework that already supports that (OSGI, etc) (although I don't know what the status is on clojure/osgi compatibility)
15:42Chouserusing the (new) load doesn't seem to run the new .clj from an updated .jar
15:42kotarak-.-
15:43cemerickDoesn't lib have a :reload flag or somesuch?
15:43kotarakIt's more about the jar being recognised, I think. (At least I would suspect this.)
15:43cemerickSo, I have an interface that defines two overloads of a method, both taking one argument (of different types). Is there a way to pair this up with a gen-class implementation?
15:44ChouserI've got a .jar in my classpath with t2.clj inside. I can use (load "/t2.clj") to load it.
15:45rhickey_cemerick: yes, you can distinguish method implementations by name, just append the types MyClass-myMethod-X MyClass-myMethod-Y
15:45ChouserIf I then change the .jar, and re-run (load "/t2.clj"), it doesn't seem to get the new changes.
15:47cemerickrhickey_: OK, I'll give that a try; just out of curiosity, will that work with init fns as well?
15:48rhickey_cemerick: no, one ctor
15:49rhickey_cemerick: hold on...
15:51cemerickrhickey_: OK, thanks. FWIW, that'd be very nice to have -- I often have two constructors for a genclass: one that takes some initialization value, and another that takes a PSM that's swapped in as the state of the new instance when "mutating" it
15:52cemerickI end up adding a dummy Object argument to the latter to distinguish the arity...
15:54rhickey_cemerick: if same arity will be routed to same fn, then you can switch on type
15:56cemerickrhickey_: Yeah, I suppose. Having the extra dummy argument is cleaner IMO, by just a hair (especially since only clojure code calls it).
16:27StartsWithKwhat am i doing wring error: http://pastebin.com/d4834a728 genclass: http://pastebin.com/d6bb3915f client: http://pastebin.com/m45f76093
16:28StartsWithKit was all working with old genclass, i don't know what revision i was using before of clojure, but with trunk i can't make it work anymore
16:35Chouserit looks like maybe your gen'ed .class files are out of date
16:36Chouseryou might try deleting them and re-running the gen-and-save-class
17:19Chouserwow, using prototypes intead of closures speeds up V8 by around 25%
17:20rhickey_hmm
17:21Chouseroops, I mean to about 25% of the CPU time. 75% improvment.
17:21rhickey_ok, wow
17:21Chouserrhino only gets a 14% bump.
17:22abrooksChouser: Rhino??? Clojure in JavaScript in Java on the JVM? Nooo!
17:22pjstadighaha
17:27ChouserIn V8, reads of a raw array are only 40% faster than reads of PV
17:28rhickey_cool
17:28Chouserwrites to PV are 36 to 61 times slower than the raw array.
17:28rhickey_ouch
17:30Chouserbut that's because V8 is doing something really impressive with the raw array. On Rhino, writes are only 10 to 25 times slower.
17:30Chouserdinnertime
17:30rhickey_append is more important than write at index