#clojure logs

2008-09-15

00:14abrooksChouser: That's really nifty! Congrats!
02:11homercyclesDoes anybody know if a book is currently being written about clojure? I've read the first 8 chapters of Practical Common Lisp to starting "thinking lisp" but want to start doing something with clojure, but am not sure where to get started really
02:12homercyclesonline reference is nice but probably not covered to the level I'll need in order to understand
02:13homercyclesclojure.org/reader - especially the stuff on dispatch - needs more explaining for people like me :-)
11:55Chouserrhickey_: is there any easy way to determine if a FnMethod is going to be used as a target for a recur?
12:22rhickey_Chouser: doesn't appear so
12:24Chouserok. I'm putting a do{}while in every function just in case. Not the end of the world, but I was hoping to skip that if not needed.
12:24rhickey_yuck
12:25ChouserDoesn't seem worth walking the tree differentiating between enclosed fns and loops vs. everything else.
12:29rhickey_you walk the tree when you emit anyway, just track the nesting level. If you look at the compiler, you'll see it tracks loop targets during emit, not analyze. Look for the use of LOOP_LABEL. You could track the (potential) loop target similarly with a dynamic var
12:30rhickey_each fn and loop pushes on the stack, when you hit a recur, top of stack is target. If you don't recur, stack is not used but at least the generated code isn't polluted
12:32Chouserhm. so far I've ignored subtrees when emitting the current level.
12:32ChouserI've passed context down, but not tried to return anything except the code to be emitted.
12:33rhickey_I see, yeah in bytecode I just drop labels as I go...
12:34rhickey_still, possible to do cleanly with mutable dynamic vars
12:35Chouseroh, yeah I hadn't considered that approach. not exactly immaculate, but if you're will to call it clean I guess I'll give it a shot.
12:36rhickey_it's thread safe, and stack based. The compiler does similar things...
12:37Chouserbiab
13:07ChouserThat's the first time I've explicitly used the stack built into a dynamic var. Not too shabby.
13:07rhickey_not too
13:08rhickey_it's sort of made for this problem
13:08rhickey_communicating across nested scopes
13:14ChouserWell it tightens up the .js pretty well. The only bit of cruft I've still got is a local var declared for functions even when nothing internal ever refers to it.
13:20lisppaste8Chouser pasted "JavaScript emitted by tojs" at http://paste.lisp.org/display/66866
13:22rhickey_cool
13:30ChouserI sometimes get a NPE from getAndIncLocalNum when the outermost form I'm analyzing isn't a def or a fn.
13:31ChouserLike this, for example: (doseq src (script-src) (prn src))
13:31ChouserIs there something better I can do than wrapping it in ((fn [] ...)) like I am now?
13:33rhickey_no, that's the right thing, else you will be writing an interpreter too. (see all the evals in addition to the emits in the Expr classes?)
13:41rhickey_added lazy parallel pmap (in rev 1026)
13:57ChouserI did see those evals, but I didn't pretend to understand them.
14:18Chousermore features less code! (re: pmap)
14:51arohnerrhickey_: did you see my compiler error patch?
14:52Chouserarohner: I know very little about Java exceptions. Does your patch end up converting exceptions of all types to Exception instances?
14:53arohneroh, that's a good point
14:53arohnerit doesn't convert the thrown exception, but it does wrap it in an Exception
14:53arohnerbut that shouldn't change the semantics of trying to catch exceptions
14:54Chouseroh, you can still catch the more specific exception type inside?
14:54arohnerno, but compiler.java isn't picky about the types of exceptions it throws
14:54arohnerso, I *think* I'm not making the situation any worse, but I'm not making it better
14:55arohnerwrt to catching exceptions
14:55arohnerI guess I need to clarify that. because java's checked exceptions, you have to declare what type of exceptions you throw
14:56arohnerright now, compiler.java does very little of that, and just declares it throws Exception
14:57arohnerwe could change things so that for example Compiler.load() throws a clojure.lang.loadFile exception, etc
14:57arohnerbut that doesn't really buy you much
14:58arohnerIt looks like rhickey is writing C in java. I don't blame him, that's probably what I would do.
14:58ChouserI'm not really qualified to have an opinion. Just sniping. :-)
14:58arohnerI'm not entirely sure I am either :-)
15:01rhickey_arohner: C in Java? in what way?
15:02arohnerindentation :-) I know you're using inheritance, OO in some places. I don't know, just a feeling I got
15:03arohnerit didn't look like "standard" java
15:03arohnernot that there's anything wrong with that
15:05rhickey_It's certainly not C-like
15:07Chouserheh
15:07Chouserarohner: that may not have been the fastest path to getting your patch accepted. ;-)
15:07arohnerhah
15:07rhickey_http://n01se.net/paste/HTx
15:08arohnerpretty
15:09arohnerrhickey_: I'm really not trying to insult you. The code is nice. It didn't look like standard java, and when I tried to figure out what it looked like, the first thing that popped into my head was "C". I know that's not entirely correct.
15:10rhickey_but I think it's an interesting question - in what ways does it differ from 'standard Java'? (and I agree it is different) It's not C-like, so you need a better answer
15:10rhickey_answer/snipe :)
15:11arohneryou're not constructing hammer factories, for one
15:11arohnerhttp://discuss.joelonsoftware.com/default.asp?joel.3.219431.12
15:12ozzileeThe indentation's all fucked up, for another :-)
15:12ozzileeI spent about half an hour trying to get Eclipse to match the indentation... no dice.
15:13arohnermaybe it's the fact that 90% of the compiler code is pure code. Most java I've seen is just gluing one library to another
15:15arohnerseveral of the important classes are arranged as OO for organization rather than functionality
15:15rhickey_The compiler code is especially different in that it uses the Clojure persistent data structures, not as pretty in Java, and uses Clojure's dynamic vars too.
15:15rhickey_arohner: like what?
15:15arohneri.e. Compiler.java. lots of static functions, rather than classes with lots of internal state
15:16arohnerwhich of course fits clojure's style
15:18rhickey_ozzilee: switch to IntelliJ
15:19ozzileerhickey_: Ok, I'll try that next time I load it up.
15:21Chouserarohner: nice link. Definitely the feeling I get from Java.
15:31Chouserrhickey_: In this code I'm writing, having an :interpose for "for" would be awfully handy. Thoughts?
15:32rhickey_I think you need to explain that to me
15:34Chouser(interpose 0 (for [i (range 3)] i))
15:34Chouser(for [i (range 3) :interpose 0] i))
15:34rhickey_they seem to be the same length
15:34ChouserHm, it's not terribly compelling when written like that is it.
15:36ChouserWhen the "for" is multi-line, having interpose at the front forces "for" to be much more deeply nested than in the latter case.
15:37ozzileeChouser: You mean there's a lot of blank space to the left of every line in the body of the for?
15:37parth_mrhickey: I have been toying with the idea of creating a user friendly clojure shell for the past few days (with jline integration, history, and stuff). Hopefully something like what ipython does for core python. Wanted your opinion on the same. Initial proto is here: http://code.google.com/p/iclj/source/browse/trunk/iclj.clj
15:37ozzileeChouser: Hmm nm.
15:37lisppaste8Chouser pasted "proposed :interpose" at http://paste.lisp.org/display/66878
15:38parth_mBeing in clj its easy to enhance and modify.
15:38lisppaste8parth_m pasted "interaction" at http://paste.lisp.org/display/66879
15:38Chouserozzilee: yeah, you're right.
15:38Chouseranyway, not a big deal.
15:39ozzileeChouser: Lisp indentation kind of sucks sometimes. I usually just plunk a newline in after the (interpose 0
15:39parth_mrhickey: do you say its best to keep something like iclj as a separate project or do you see value in rolling something like this into clojure? Both approaches seem fine to me.
15:40lisppaste8rhickey annotated #66878 with "press enter" at http://paste.lisp.org/display/66878#1
15:42rhickey_parth_m: we've been moving along on this line: http://groups.google.com/group/clojure/msg/78ebea4b2719bc7e
15:43arohnerrhickey_: do you like my patch? is this a good approach? is there anything I should do differently?
15:45parth_mYes. Thats actually nice. But I was thinking that doing the repl in clojure itself may make it easy to maintain and enhance. + there is builtin jline integration (tab-completion and stuff ... i suppose jline works on windows also though I havent tried it).
15:47rhickey_parth_m: yes, repls are trivial to write. jline is a dep I don't want to get into
15:50rhickey_arohner: It seems more like a band-aid than substantive. Given the abbreviated stack trace (see above), the real target should be at the exception generation points themselves, where I have enough info to talk about the nature of the problem
15:50arohnerwhere is the abbreviated stack trace?
15:51rhickey_http://groups.google.com/group/clojure/msg/78ebea4b2719bc7e
15:51rhickey_but I'm not putting any of this in until after I cut a release
15:52ozzileeparth_m: I think a separate project for that would be cool. I can think of some repl features that would be cool to see, but probably would get implemented very quickly in the main clojure repo.
15:52ozzilee*probably wouldn't
15:54parth_mrhickey: jline seems fairly common now (as its under BSD license). groovysh and jruby are using it. Is the intent to keep the distribution small? The problem with using jline from the command line is that we don't get tab-completion. And rlwrap is unix only.
15:54arohnerrhickey_: it is superficial, but it does help. you have different information at the exception generation point. I wouldn't say it's more
15:55arohnerfor example, load a.clj, a.clj requires b.clj. b.clj generates an exception. print the sourcePath at that point, and it will say a.clj
15:55rhickey_jline is not pure Java on windows. I've seen bug reports on JRuby or Groovy related to jline
15:55ChouserThere are going to be a bunch of repl projects: intergrated into various editors (emacs, netbeans, jedit, etc.), various terminal wrappers (rlwrap, jline), GUI toolkits (Qt, swing), etc.
15:55ChouserIn fact, most of those exist already.
15:56parth_mozzilee: yes. separate project could also work. probably features like color, logging, printing source lines with exception (like ipython) and such. Not sure how much it makes sense to have that in the core REPL.
15:56arohnermaybe the correct solution is to fix the source path so it correctly points to the file you're actually loading. I can go down that route, but that is exactly the kind of thing I wanted to get buy-on for first.
15:57parth_mrhickey: Yes. Thats true.
15:58parth_mChouser: Yes. That seems to be the standard practice. Especially for lisp :)
15:59parth_mAnd it has its advantages.
16:00rhickey_arohner: doesn't load already set the source path?
16:00rhickey_gotta run
16:02cemerickI have a genclass impl in a .clj file, which appears to load fine when the corresponding MyClass class is loaded. However, for some baffling reason, a couple of vars that I def using defn are unbound when I refer to them (java.lang.IllegalStateException: Var MyClass-removeAll is unbound, etc). Anyone have any ideas as to why that would be?
16:02ozzileeparth_m: I'd like to see a repl brought the up previously typed line with the cursor positioned at the error in the case of one. That would be slick.
16:04parth_mozzilee: I am not sure I understand you.
16:05Chousercemerick: the defn and the exception are in/from the same .clj file?
16:05ozzileeparth_m: Sorry, I should have proofread that :-)
16:05parth_m:-)
16:06cemerickChouser: No. I bring up a repl with an appropriate classpath, and do (import '(foo.bar MyClass)). Then, foo.bar/MyClass-removeAll => exception.
16:06ozzileeparth_m: Say I type "(print foo)", and I get an error saying "Can't find symbol foo". Then instead of a blank line, I'd like to see "(print $foo)", with the $ being the cursor.
16:07cemerickChouser: Oddly, only the functions that start with MyClass-r seem to be affected, although I have to think that that's coincidence.
16:07Chouseryou're seeing other side-effects from inside the .clj? That's why you're sure it's loading?
16:08parth_mozzilee: Ah. Yes. That would be nice. Getting the line is certainly possible. Don't know about the cursor with jline yet ... still learning jline.
16:08cemerickChouser: Oh, yeah, the .add, .count, .seq, etc., methods all work, and those are implemented in the same .clj file
16:09parth_mI suppose I will maintain iclj as a separate project and see how it shapes up. I am hoping to take some inspiration from ipython. Thats a really neat interactive shell.
16:11cemerickChouser: nevermind. An old version of the .clj file was being loaded from another netbeans project I have open. D'oh!
16:11Chousercemerick: yeah, ok. Kinda had to be something like that. ;-)
16:11cemerickyeah, I thought I was in the twilight zone there.
16:12ozzileeparth_m: Cool, perhaps I'll make a fork and screw around with adding that feature myself.
16:12parth_mSure.
17:40drewrIs there an example in the wild of when fnseq would be used? I cannot come up with a case for it by perusing the source.
17:42rhickeydrewr: it used to be used in lazy-cons, now it's legacy
17:42drewrAh, OK.