#clojure log - Nov 10 2008

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

0:43 danlarkin: what's a good way to add generic dispatch to my json-encoding function. Like if you've got a way you want to have JFrames encoded then you define it and I'll know to call it. I know I could define a multimethod using #'clojure/class but that ties it to type

8:23 Cark: it's ironic i'm writing a tool to search the meta tags in clojure and i don't know how to add a doc string to multimethods

8:24 kib2: look at that blog post (last paragraph is talking about Clojure) : http://spotless-spots.blogspot.com/2008/11/why-i-like-f.html

8:42 StartsWithK: Cark: (defmulti #^{:doc "doc string"} fn-name dispatch-fn)

8:43 Cark: yay thanks StartsWithK

8:44 StartsWithK: works for defmethod too, (im at rev1086)

8:46 Cark: lisppaste8: url

8:46 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

8:47 cark pasted "a tool to search docs string and other meta data" at http://paste.lisp.org/display/70071

8:48 Cark: if someone has anything to say about it, i'll gladly take it !

10:18 Chouser-away: rhickey: are print-method and print-dup fairly settled down now, or not yet?

10:19 Chouser: well, what I'm asking is if it's a bad time for someone to start looking at pretty-print.

10:20 leafw: can't svn handle branches properly? It's a bit odd to see all this "interim checkin" warnings on the latests commits

10:20 I would have done them on a separate branch and then cherry-pick them into the master ...

10:21 Chouser: leafw: how well svn handles branches is perhaps a matter of some controversy, but anyway rhickey doesn't like branches.

10:21 svn certainly doesn't handle cherry-picking nearly as well as git.

10:21 rhickey: Chouser: basically print-dup removes from print all of the goop required for 'serialization', so print-method goes back to what it was. I'm not sure of the relationship between print-method and a pretty-printer though

10:21 leafw: that is evident. Never mind, just a comment.

10:22 we have our own git mirror of clojure ... had to checkout an earlier commit today.

10:22 to avoid the interims.

10:23 Chouser: leafw: yeah, I have a "stable" branch in my git mirror right now, so I can flip back and forth pretty easily.

10:24 rhickey: I didn't check in anything that didn't run, if you have problems you either have to change something to work with the breaking changes or report a problem

10:25 leafw: no obvious problem so far Rick; just didn't want to include a version whose commit mesage was a "warning do not use"

10:25 in fiji.

10:27 rhickey: leafw: thus the warning, there's absolutely no reason to take head unless it fixes a bug or adds a feature you need

10:27 OR - you want to help test the changes

10:27 leafw: I know, I know, I'm shutting up.

11:12 danlarkin: I saw your post about Gorilla, kotarak, congrats on release #1

11:13 kotarak: danlarkin: thanks. The Repl is still, ehm, experimental... I have to work on this. Noticed already some issues.

11:13 danlarkin: now let's get going on Parser! :-D

11:13 kotarak: danlarkin: hehe, sure

11:14 danlarkin: heh, just kidding on the square... no pressure or anything :)

11:17 kotarak: danlarkin: certainly not, this is a hobby. But Parser will get it's time slice in the near future. :)

11:17 danlarkin: woo hoo!

12:20 kib2: kotarak: ping ?

12:21 kotarak: kib2: pong

12:21 kib2: ok, have you tried to compile Vim on Windows with Ruby support ?

12:21 I've got lots of errors

12:21 kotarak: kib2: the self-installer vims come with Ruby enabled

12:22 never compiled vim on windows

12:25 kib2: kotarak: the problem is that I need Python support too, and I have to compile Vim from source to have Python support. But the Ruby one does not work.

12:26 kotarak: kib2: the self-installer vims com with Ruby *and* Python enabled

12:26 kib2: they do it over some dynamic loading thing.

12:26 kib2: when it's there it's used, otherwise, well, it's not

12:27 kib2: kotarak: are you *sure* it comes with native Python support ?

12:27 kotarak: kib2: I think so. But I can't check now, since I'm already at home. But I think they have everything enabled. Also Tcl and Perl. But you can also ask on #vim.

12:29 kib2: kotarak: ok, but last time I've tried, Python was not natively supported.

12:29 kotarak: see here http://showmedo.com/videos/video?name=1850010&fromSeriesID=185

12:34 Chouser: I don't know how to make this available for review without it being fully public. ...so here it is

12:34 http://blog.n01se.net/?p=33 -- Writing a macro: for vs. doseq

12:34 if anyone spots any errors, let me know.

12:38 kib2: Chouser : nice blog posts on Clojure !

12:39 Chouser: If by "nice" you mean "too long", then I agree! :-) Thanks, though.

12:41 kotarak: Chouser: awesome. Cosmetics: In the "nested loops" section, the formatting is a bit messed up. It least there is one paragraph in all monospace. Is this intentional?

12:43 Cark: chouser : that's cosmetic too but ...the code divs are very small, hard to read

12:44 using firefox

12:45 rhickey_: Chouser: very nice, you might want to warn people that doseq a la for is not the most trivial macro

12:46 also another tip about macros (that you observed) they often can and should be written in terms of functions, not a giant syntax-quote

12:52 drewc: rhickey_: amen!

12:54 * drewc always tries to write non-trivial macros in terms of a 'funcall-with-*' function.

12:55 drewc: the biggest reason is to avoid recompiling the world every time the macro changes, and as a side effect you get clean maintainable code and a functional interface to your abstraction.

13:08 Chouser: thanks, guys. The formatting should be cleaned up now.

13:12 Cark: easier to read, thanks !

13:14 chooser : ", so until they are you much choose to use my-doseq as shown above."

13:14 rhickey_: Chouser: hmm, the code is huge now for me, with much spillage out of the white box. Camino 1.5.1 OS X 10.5.5

13:14 Cark: that's not making sense

13:15 there is some spilling here too btw

13:15 Chouser: ok

13:16 Cark: the problem is with this smallish column width you got there !

13:16 Chouser: Cark: grammar fixed

13:16 yeah, no kidding.

13:17 default Wordpress width. :-/

13:18 Cark: mhh, i can't seem to find a neat way to manage changing state in a complex swing window

13:20 i'd like to keep the state imutable, and at the same time change the reference in the window

13:20 is there a field in those swing components that can be used at the programmer's discretion ?

13:21 like in delphi there was this tag field to every component, and you could store pointers in there

13:26 ah got it, putClientProperty and getClientProperty !

13:46 askentasken: im implementing prolog in python,clojure and haskell. im thinking i need some state. or soem container to store allf acts and rules. what would that be in Clojure where i dont have traditional OO? im thinking multimethods mgiht be of use in the implementation. Perhaps I just have a : (def State {:rules nil :facts nil})?

13:48 Cark: or a (def state (ref {:rules nil :facts nil}))

13:48 Chouser: or (def rules (ref {})) (def facts (ref {}))

13:53 askentasken: but i want a "struct" clause which canab a rule or a fact. and i want to be able to define new structs within this predefined form. im not making much sense am i? i want to abstract out the defintiion of a rule but be able to define different rules. a Class i python does this nicely. In clojure, what do ido?

13:53 Chouser: probably a hash-map.

13:54 clojure has a thing called a struct, but it's really just a performance enhancement of a hash-map.

13:55 sohail: askentasken, a useful model is to understand that clojure does not let the user define new types

13:55 Chouser: (without resorting to proxy or gen-class)

13:56 sohail: you probably wouldn't want to do that too often!

13:57 Chouser: right. proxy and gen-class are generally the wrong tools for defining application-specific data.

13:58 askentasken: how do i define atsruct? i dont get it fromt he API?

13:59 Chouser: askentasken: http://clojure.org/data_structures#toc75

14:00 but don't get too distracted by StructMaps. They're really just another kind of PersistentMap, so when designing your solution that's all that really matters.

14:00 The Struct part is a small optimization on the same core concept.

14:09 askentasken: and {} is syntactic sugar for hash-map?

14:09 Chouser: yes

14:12 askentasken: ah wait

14:12 (def State {:rules [] :facts []})

14:13 i can then create new State a lot of times and it is not the same State?

14:14 Cark: by doing this you create a var state, and it has the value you gave to it

14:14 it's not a good idea to re-def it afterwards

14:14 sohail: I'm told you want to use refs

14:18 askentasken: how do i update the value of a key?

14:19 Chouser: assoc returns a new hash-map with you value updated in it.

14:21 askentasken: #'user/s

14:21 user=> s

14:21 {:2 [10 10]}

14:21 (def s (assoc s :2 (conj (get s :2) 10)))

14:22 seemscomplicated for adding a value to a key

14:23 Chouser: (update-in s [:2] conj 10)

14:24 but don't use def to update values in application logic -- use an agent or ref for that.

14:25 wwmorgan: askentasken: you could also use java.util.HashMap

14:25 rhickey_: best to define your model and a set of functions that transform your model, then, later, put your model in a ref

14:25 Chousuke: that's throwing away all the concurrency benefits though.

14:25 Chouser: (def s (ref {:2 [10]}))

14:25 (dosync (alter s update-in [:2] conj 10))

14:26 askentasken: what is? using refs?

14:26 update-in doesnt work like that though

14:26 Chousuke: askentasken: using java.util.HashMap instead of clojure's maps

14:26 rhickey_: wwmorgan: then when you want to run queries in the background while editing your rulebase in a gui you've got threading trouble

14:27 or fact db updated from incoming data feeds, etc etc

14:27 wwmorgan: yes

14:27 rhickey_: If you use the Clojure model from the start then adding these things is easy

14:28 askentasken: (defn add-value [coll key val]

14:28 (assoc coll key (conj (get coll key) val)))

14:28 well update-in is the same i get but i dont see how to use it

14:28 (update-in s [:2] conj 10) -> wrong number of args

14:28 and if i do(conj 10) i get wrong nbr of args for update-in

14:28 Chouser: you're probably running from a release version. hang on.

14:28 rhickey_: askentasken: think about (add-fact db fact stuff), yielding new db

14:29 Chouser: (dosync (alter s update-in [:2] #(conj % 10)))

14:29 rhickey_: you should leave the ref out of it until later

14:31 danlarkin: I asked this last night and didn't get any responses (I think everyone was asleep :))... what's a good way to add generic dispatch to my json-encoding function. Like if you've got a way you want to have JFrames encoded then you define it and I'll know to call it. I know I could define a multimethod using #'clojure/class but that ties it to type

14:31 rhickey_: e.g. first define assert-fact, retract-fact, add-rule, drop-rule, all taking and returning a fact/rule base

14:32 danlarkin: you can dispatch on an attribute or metadata

14:34 danlarkin: would dispatching on metadata require adding that key to the metadata for every object you want encoded?

14:35 rhickey_: danlarkin: If you have a default, then no, just for the special cases

14:39 danlarkin: ideally I'd like to have a way to define additional ways to define a dispatch

14:39 but maybe that's just overengineering

14:39 rhickey_: danlarkin: how would you find out about them?

14:40 danlarkin: not sure :)

14:41 rhickey_: one meta option is that dispatch functions can themselves be multimethods

14:43 askentasken: what is the diff between ref and agent?

14:43 rhickey_: askentasken: you've read the docs?

14:48 danlarkin: dispatch functions being multimethods would buy me allowing the user to define an encoding method based on whatever options I choose... class, a key in the metadata, but not their own way of dispatch

14:48 but maybe that's good enough

14:51 rhickey_: danlarkin: you can have your first-line multimethod be spec'ed to return a fn to be called in turn

14:52 get-encoder-getter

14:53 danlarkin: let me whip up a paste to see if I get it

15:02 Heh, I'm getting lost in abstraction, could you show me an example?

15:04 rhickey_: danlarkin: {:encoding-system :mine} {:encoding-system :yours}

15:05 (defmulti get-encoding method :encoding-method)

15:06 (defmethod get-encoding-method :mine [_] my-dispatch)

15:06 (defmulti my-dispatch whatever-I-want)

15:07 AWizzArd: What I didn't understood, regarding AOT was, if it will be possible to reaload .class files. It sounded as if the jvm does not allow this.

15:07 rhickey_: (defn encode [foo] ((get-encoding-method foo) foo))

15:08 AWizzArd: jvm doesn't

15:08 AWizzArd: okay, so for patching an application one should restart it

15:09 rhickey_: AWizzArd: no

15:09 AWizzArd: Clojure works hard to provide an indirection that avoids the rigidity of the JVM class system in most cases

15:10 AWizzArd: I see.

15:10 rhickey_: right now only genclass sigs have the same static nature as the rest of Java, even their method implementations can be dynamically redefined

15:11 but it's nasty and hard

15:11 * rhickey_ goes back to it

15:11 walters: AWizzArd: JDWP allows it in some limited circumstances

15:12 AWizzArd: there is some initial work in openjdk in allowing classes to implement new interfaces at runtime as well

15:13 danlarkin: rhickey_: thanks, I understand now. I appreciate it

15:13 AWizzArd: I see... well, it's nice that rhickey_ already has some good ideas about it. Although honestly I regard it as acceptable to restart an application from time to time. When Lisp compilers get updated (Allegro, Lispworks, sbcl) then they all need a new version/a restart and can't hotfix themselves while running.

15:14 drewc: AWizzArd: i have an application (still) running sbcl 0.8.something that has yet to be restarted.

15:15 AWizzArd: i do, of course, have to keep around an old emacs/slime installation for the odd patch, and it could be restarted without harm or loss of income.. but it's been an experiment :)

15:16 AWizzArd: nice :-)

15:16 drewc: and i could see applications for which any downtime is not acceptable.. i'm just glad i don't have to write them! :)

15:19 AWizzArd: I'm glad about my internal software.. it needs some downtimes at nights, but in reality the system is even working them. Never rebooted so far..

15:28 bradbev: rhickey_: I was trying to make prettier slime backtraces by changing user.foo_QMARK___1234.invoke -> user/foo?. I used a heuristic to do it, but is there an internal map of java symbol names to clojure names?

15:31 rhickey_: bradbev: clojure.lang.Compiler/CHAR_MAP

15:32 bradbev: oh, I found that. I was really meaning the __1234 part

15:32 I assume that is a gensym, and I can't rely on it being 4 digits

15:32 rhickey_: bradbev: right

15:34 bradbev: actually, I guess I use #"__\d+" to remove it, so the amount of digits won't really matter

15:42 SnowBuddy: the lazy programmer in me wants to know if macro-fu is necessary for Clojure programming. i mean, unless i totally don't understand the point of macros, they don't seem like a requirement for getting things done. i'm usually wrong, so could somebody correct me?

15:43 AWizzArd: SnowBuddy: you never need macros. In all cases you can solve your programs with pure functional programming.

15:43 The difference is, that macros allow you to remove ' and #(..) and (fn []) from your code

15:43 SnowBuddy: how much of a difference is that?

15:44 AWizzArd: (if (= a b) (fn [] (then)) (fn [] (else))) vs (if (= a b) (then) (else))

15:45 jgracin: does the work on enabling AOT imply there will be a nicer/easier way to do what gen-and-save-class does?

15:45 AWizzArd: For some constructs it is ugly to pass in functions, and that's why macros win in such situations.

15:46 SnowBuddy: ok, that helps. i still think i'll avoid that part of the language. i'm not smart enough for functional programming, much less macros on top of it ;)

15:48 AWizzArd: in the end you can solve the program by functional programming and then have a one-line macro which just calls your functions and therewith removes the need for manually making expressions lazy

15:49 SnowBuddy: can you run that by me again? :P

15:51 AWizzArd: solve the problem I meant

15:51 SnowBuddy: heh, i didn't even see that. it's the whole latter part that i didn't get

15:52 AWizzArd: a macro does not evaluate its arguments

15:52 (if true (print "Hello") (print "World")) does print only one of them

15:52 if "if" were a function then always both strings would get printed.

15:53 but you can make them lazy.. stop them from being evaluated

15:54 (if-function bool #(print "Hello") #(print "World")) - in this case you can decide which one you want to call inside if-function.

16:00 bradbev: the macros section in "Practical Common Lisp" was illuminating for me. Skim read that to get a feeling for what macros can do for you, SnowBuddy

16:01 SnowBuddy: that's the problem. i feel i understand what they can do, but i don't see myself using them. it's kind of like inheritance in C++; i fully understand it, but so few of my problems require that feature

16:02 but with all of the talk about macros, i thought i might have been missing something

16:05 Chousuke: at the very least, you can use macros to make your code more expressive

16:05 alec: SnowBuddy: I find myself using macros in Clojure much less than in Common Lisp because Clojure provides easier lambdas and general sequence operators

16:07 Chousuke: rather than writing the logic as is, you can write something that expresses more clearly the meaning of your code, and under the hood expands into something clojure can actually run.

16:07 SnowBuddy: speaking of general sequence operators, let's say i want to print the namespaces from (all-ns) all on a separate line. i can do it, but everything i've come up with seems overly complicated. is there a quick and easy way with the standard functions like (this doesn't work quite right btw) "(apply println (all-ns))"?

16:10 wwmorgan: SnowBuddy: (doseq n (all-ns) (println n)), before revision 1090. (doseq [n (all-ns)] (println n)) otherwise

16:11 SnowBuddy: Why the brackets in the second version?

16:12 wwmorgan: the syntax changed to make it more consistent with for, let, loop, etc

16:12 SnowBuddy: so will the first not work anymore?

16:12 wwmorgan: I'm pretty sure the first form is broken as of rev 1090

16:12 Chousuke: yeah, it is

16:12 it throws an exception I think

16:13 SnowBuddy: poo diddles, i guess i need to update my installation

16:13 Chousuke: for now, stay with revision 1088

16:13 apparently HEAD is quite volatile at the moment :P

16:13 SnowBuddy: how do i know which revision i'm on/

16:13 ?

16:14 Chousuke: if your code works, you're pre-1089 :P

16:15 albino: svn? svn info

16:15 SnowBuddy: i just downloaded the zip from sourceforge...

16:19 wwmorgan: SnowBuddy: the sf download lags behind head usually

16:23 Lau_of_DK: If I have a seq-of-seqs that I want to output, I would think (map println seqs) would do the trick, but it takes the liberty to throw out a "nil" between every seq, why ?

16:24 wwmorgan: Lau_of_DK: because println returns nil, is my guess. You'd be better off using doseq anyway as map is lazy

16:26 Lau_of_DK: THanks wwmorgan

16:26 kotarak: Lau_of_DK: rule of thumb: side-effects => do*

16:26 Lau_of_DK: Good one

16:42 SnowBuddy: you know what would be awesome? an example for each of the standard functions/macros in the documentation.

16:43 Zak: That would be awesome. I bet if you contributed some good ones, they would become part of the official documentation.

16:43 SnowBuddy: i would, but i'm reasonably sure they wouldn't be good quite yet ;)

16:45 Zak: I know what you mean, but don't sell yourself too short. I'm still a Clojure novice, but having experience with other Lisps I think I have a very good grasp of the parts that are similar.

16:49 SnowBuddy: hmm, is there any reason why the output appears to be sorted? (doseq x (take 10 (iterate rand 100)) (println (int x)))

16:51 wwmorgan: snowbuddy: you want (repeatedly #(rand 100)), not (iterate rand 100). In the latter case you're feeding smaller and smaller numbers into rand

16:51 Lau_of_DK: rhickey_, when are these 'interim' svn updates expected to be completed?

16:51 ls

16:52 SnowBuddy: how's that? does iterate send the result of the previous rand call to the next iteration?

16:52 Zak: Yes, that's what iterate does.

16:53 Iterate returns a seq of (f x), (f (f x)), (f (f (f x)))...

16:53 SnowBuddy: gotcha

16:54 so what would i use iterate for?

16:55 drewc: iteration?

16:55 :)

16:55 Cark: (iterate inc 0) = all the positive integers

16:55 that's usefull

16:55 SnowBuddy: drewc: not in any form i'm familiar with ;)

16:56 Cark: (zipmap (iterate inc 0) (enumeration-seq (-> table .getColumnModel .getColumns)))

16:56 a map from index to table column

16:57 drewc: SnowBuddy: FWIW i thought i was in #lisp, where ITERATE is indeed for iterating in the usual sense :)

16:57 SnowBuddy: :D

16:57 bbiab

16:57 time to go home

16:59 kib2: gnuvince, do you wrote your new tutorial ?

17:01 albino: What's the word on the clojure book? Has anyone looked at it yet?

17:02 gnuvince_: kib2: not yet, haven't had time to write this weekend.

17:03 kib2: gnuvince : ok, i'll wait

17:25 roblally: I've been reading Pragmatic Clojure - it is very good.

17:25 Still a work in progress, but worth acquiring even at this stage.

17:49 bradbev: I use Slime. If I have a recursive function & I re-evaluate it - ie, to stop recursing - the definition doesn't take effect in the running function. Is this a Slime problem, or an artifact due to recur not looking up the function by symbol

17:51 Chousuke: latter, I think.

17:52 bradbev: doh

17:52 It would be handy to be able to do that, perhaps make it a global property some how?

17:53 otherwise you can't edit & fix recursive functions on the fly like you can with other funcs

17:53 SimonAdameit: Hi

17:58 bradbev: this also applies to agent functions that resend themselves to agents, the clojure symbol is looked up at compile time rather than runtime. That is good for speed & local functions, but annoying for development & global defs. Thoughts rhickey_ ?

18:02 nope, I lied about the agent thing

18:02 only recursive functions

18:04 rhickey_: bradbev: that seems backwards - you can redefine recursive fns and see it rught away - but self-sends from agents should use #'action-name to send the var rather than its current value

18:07 lisppaste8: bradbev pasted "weird" at http://paste.lisp.org/display/70099

18:07 bradbev: this is running via slime, which I think spawns a thread for each eval - is the def thread local then?

18:08 rhickey_: no, def is global

18:09 but recur is not a self-call but a direct loop

18:09 bradbev: so the goto is calculated once at compiletime

18:10 rhickey_: bradbev: it's a loop, not a function call

18:11 bradbev: true.... and if it were in a (loop...) I probably would have been quicker. As a tail-call mimic I didn't clue into that as much

18:12 so for recur there is no way to fix on the fly :(

18:14 thanks for the help

18:14 rhickey_: sure

18:15 bradbev: BTW, I'm really liking Clojure quite a lot - thanks for all the effort!

18:16 rhickey_: great - you're welcome!

18:17 danm__: +1

18:23 Zak: I'm having trouble trying to use swank with Clojure. Before I ask any detailed questions, will it work with 20080916, or do I need a recent snapshot?

18:24 Chousuke: I think you need something more recent. however, not the most recent.

18:24 go with r1088

18:35 Zak: I tried r1088 and I'm still getting the following exception: java.lang.Exception: Unable to resolve symbol: *e in this context

18:46 rhickey_: psst - wanna try AOT compiler? rev 1093 9

18:46 (for the daring only)

18:47 Chouser: rhickey_: using #'action is so that the action is looked up when the agent actually run rather than when it's queued?

18:50 * Zak is excited about the idea of an AOT compiler.

18:50 rhickey_: Chouser: when you say (send agt foo) the fn value is sent, so if you change the var foo, it's not seen by the agent

18:50 Chouser: vs (send agt #'foo) which sends the var itself,, agent will get current value whenever it uses it

18:50 bradbev: I guess AOT means that we'd be able to deploy a JAR full of class files generated by Clojure?

18:51 rhickey_: bradbev: yup

18:51 bradbev: nice!

18:51 rhickey_: Clojure itself runs without the source for core.clj et al

18:51 Chouser: rhickey_: in the case of an agent sending the same action to itself, though, it'll still pick up a change in the var, just perhaps one iteration late, right?

18:52 bradbev: So you're not counting core.clj as part of Clojure now? Very Scheme of you!

18:52 rhickey_: Chouser: only if you use #'

18:52 bradbev: I count it, just highlighting that even the bootstrap works from classfiles generated by AOT compiler

18:53 gnuvince_: Interesting times ahead in Clojure Land :)

18:53 bradbev: oh, I see - I thought you were making a joke :)

18:53 * gnuvince_ should get off his ass and find *something* to do

18:54 Chousuke: I wish git svn clone wasn't so slow ;/

18:54 Chouser: time from shell prompt to repl was about 2 seconds. after pre-compiling, about 0.8 seconds.

18:55 rhickey_: Chouser: and java HelloWorld?

18:56 startup was never long for me, but people with old machines have said it's several seconds - interested in the speedup for them

18:57 mibu: eh, clojure is mentioned in a +4 slashdot comment: http://developers.slashdot.org/article.pl?sid=08/11/10/0453229

18:59 rhickey_: Clojure has been mostly ignored by slashdot so far, interesting how Ioke gets an article at this stage of its development

18:59 gnuvince_: Gah!

18:59 * gnuvince_ hits himself

18:59 gnuvince_: I forgot to push my blog articles from work :-/

19:00 Chousuke: rhickey_: well, I guess no-one has actually tried posting a submission about clojure yet.

19:00 mibu: rhickey, maybe ioke is underdeveloped, but it got PR

19:01 Chousuke: and maybe now is not the best time to slashdot clojure

19:01 rhickey_: Chousuke: right

19:02 mibu: rhickey, do you track website hits, svn hit, google group user count, download count, etc to see when there is a surge of interest?

19:02 gnuvince_: It's funny the difference between communities

19:02 Reddit has had Clojure articles for a year now, and quite a few in the past weeks.

19:02 rhickey_: mibu: yes, there are some measures

19:02 gnuvince_: I'm not sure if it made an appearance on Digg or Slashdot.

19:02 mibu: rhickey, when was the biggest surge?

19:03 Chouser: java hello world (short classpath, don't know if that matters) 0.12 seconds

19:03 mibu: slashdot is a lot more mainstream than reddit. it's more of a java crowd than a lisp crowd.

19:04 rhickey_: mibu: seems so

19:05 danlarkin: reddit's gone down the tubes in the past year

19:05 rhickey_: https://sourceforge.net/project/stats/detail.php?group_id=137961&ugn=clojure&type=prdownload&mode=12months&package_id=0

19:05 Chousuke: hmm... judging from the git svn clone output, it looks like you pretty much abandoned the CLI port of clojure at revision 261 :)

19:06 rhickey_: http://sourceforge.net/project/stats/detail.php?group_id=137961&ugn=clojure&mode=12months&type=svn

19:07 bradbev: Is there a good bridge between CLI & JVM? It should be possible. Sensible... maybe not.

19:07 danlarkin: wow october!

19:07 mibu: rhickey: was there a single event that made it surge like that?

19:08 gnuvince_: Wasn't it the Boston Lisp Talk?

19:08 rhickey_: Boston Lisp and JVM Summit

19:09 mibu: gnuvince, that was an actual event. but it's not an event until someone posts something about it on the web. you know, a blog entry, a mention on slashdot, a high rated reddit entry, etc...

19:09 rhickey_: http://clojure.org/space/stats/overview/2008

19:10 gnuvince_: Nice graphs

19:10 rhickey_: only started using that site in June

19:10 mibu: great graphs. very interesting.

19:11 that spike in the middle of october, which blog post/site mention caused it?

19:11 gnuvince_: mibu: Reddit had some noise about both events.

19:14 rhickey_: Between Boston Lisp and Lisp50 at OOPSLA, I think Lispers have embraced Clojure, plus the one friend tells two others effect is kicking in, more experienced users can tell richer stories, lots of factors.

19:16 the group membership and message volume is taking off as well

19:18 Zak: Is there any documentation for the AOT compiler or should I just read the source code?

19:18 rhickey_: Zak - I put some tips in the checkin message

19:19 basically, your code must conform to the new lib format - my.fancy.lib should be in my/fancy/lib.clj in classpath

19:19 mibu: i'm fascinated with how a small number of single events causes a surge of interest in things.

19:19 rhickey_: you can compile it with (compile 'my.fancy.lib)

19:20 * mibu should have gone working in PR. *shudder*

19:20 rhickey_: mibu: it used to be a lot clearer, now there are so many mentions in different places - like last week O think there was a hit due to mentions at #rubyconf

19:21 Zak: I think a lot of times there's latent interest, but some missing feature keeps people from using a project.

19:21 rhickey_: zak: then there will be classfiles in ./classes

19:22 Zak: yeah, and different communities with different awareness levels

19:23 mibu: it's interesting if there will be a 1.0 adoption surge.

19:23 rhickey_: For AOT to be generally useful, the lib fns need to use the classfiles, as per RT.loadLib, and clojure-contrib will have to move to the new dir structure

19:24 I'm ready for people to start trying that

19:26 Zak: For example, I have a future project planned for which I'm probably going to use Clojure. It will be a proprietary desktop app, for which I would like to use AOT compilation and proguard or something like it.

19:26 rhickey_: what's a good open source Java decompiler?

19:31 walters: rhickey_: i spent a good hour or two searching for one with little luck for something that looked modern and sane, if you find one let me know =) however I did find this very useful: http://asm.objectweb.org/eclipse/index.html

19:33 rhickey_: well, people concerned with decompilation can now try it on the AOT code

19:33 walters: rhickey_: though this one looked the most promising, i didn't try it though (aside from the applet): http://jode.sourceforge.net/

19:34 rhickey_: walters: looks pretty old

19:34 walters: yeah, like i said that was the most promising out of a rather sad lot...

19:36 rhickey_: the other trick i found useful was ASM's verifier, not sure if you're using that or not

19:36 since openjdk's verifier emits nearly useless error messages

19:37 rhickey_: ASM's verifier doesn't produce Java source for the program, does it?

19:37 ASMifier produces the Java code needed to get ASM to emit the bytecode

19:38 walters: no; this is in the more general scope of "debugging tools for people generating java bytecode"

19:38 rhickey_: walters: right, I use that myself :)

19:38 albino: http://java.decompiler.free.fr/

19:38 walters: i'm not talking about ASMifier but CheckClassAdapter

19:41 rhickey_: walters: ditto

19:42 bradbev: anybody know anything about java non-blocking sockets? I'm accepting on my server socket, then using a new selector for each client connection, but the problem is that select won't block on the sockets, even though they have no bytes pending. Argh!

19:52 rhickey_: albino: that one doesn't show anything useful for the Clojure-generated code

19:55 thanks for the pointer, looks nice

19:56 albino: well that sucks

19:57 The only other one that my friends are telling me is good is JAD

19:59 Chouser: so require and friends are updated yet?

19:59 rhickey_: Chouser: not yet

20:05 lisppaste8: Chouser pasted "updating the action of a self-sending agent" at http://paste.lisp.org/display/70104

20:06 rhickey_: Chouser: I've added a loadLib method to RT, which loads from a classfile if available and newer than the source

20:06 Chouser: ah, ok.

20:06 and that must be what Repl's using at startup

20:07 as for self-sending agents, I must be misunderstanding you.

20:08 that paste demonstrates what i was expecting, not what I thought you were saying.

20:13 gnuvince_: Is there a way to import all the classes in a package? something like (import '(org.foo.bar *))?

20:13 rhickey_: Chouser: right, I was remembering when I first did the ants, it was the case that a reference to act inside act was resolved to "this", and not via a deref of var #'act. So #'act is only needed when a fn will be held onto, like in a data structure

20:14 gnuvince: no

20:14 gnuvince_: ok

20:14 rhickey_: gnuvince: would just make a mess in the ns

20:14 since they are reified

20:15 gnuvince_: rhickey_: that's fine, I'm just playing with a class in the REPL and it would've been quicker than type 7-8 class names.

20:15 But it's no big deal

20:15 rhickey_: there's also been some talk about leveraging the imports for more inference: http://groups.google.com/group/clojure/msg/5c9a008c794b193d

20:16 * imports could negate that optimization

20:16 gnuvince_: ok

20:21 Chouser: rhickey_: thanks, that makes sense.

20:22 rhickey_: Chouser: sorry for the misinfo

21:58 lisppaste8: danlarkin pasted "generic dispatch" at http://paste.lisp.org/display/70110

21:59 danlarkin: there we go, that's what I want to be able to do

22:44 slava: erg: what a surprise to see you here

22:47 hi rhickey

22:53 rhickey: slava: hi

22:54 danlarkin: ah rhickey, just the man I need... here's what I'm aiming for... http://paste.lisp.org/display/70110 - can it be done with multimethods or do I have to create my own method of dispatching and keep a state-holding variable around on thread-local or something

22:56 slava: rhickey: are we going to see clojure in the language shootout at some point?

22:57 rhickey: slava: that's not something I'd spend my time on, but I imagine someone will at some point

23:12 danlarkin: I'm not sure I get it

23:21 danlarkin: rhickey: it'd be nice for the user to add a dispatcher that returns nil or a keyword, and then be able to define a multimethod on that keyword

Logging service provided by n01se.net