#clojure log - Jun 29 2008

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

0:09 spacebat_: so, I'd like to ask what environments people use, plain REPL, netbeans+enlojure, emacs+ilisp, emacs+slime, or something else?

0:11 hi craigoz, whereabouts in .au? I'm in adelaide

4:21 fanda_: hello!

4:22 just trying IRC

5:03 spacebat_: hi fanda_

5:03 fanda_: hello spacebat_

5:04 spacebat_: new to clojure?

5:04 I am

5:04 fanda_: yes, me too

5:04 just starting with it

5:04 i used newLISP before

5:04 but I know little about Java

5:05 spacebat_: knowing very little lisp and no functional programming, its a steep curve

5:05 but I can see the reasons to keep on with it

5:05 I used to work for a java shop, but that was years ago

5:06 my day job is perl

5:06 fanda_: yes, i love functional programming and LISP especially

5:06 spacebat_: newLISP, I haven't heard of that one

5:06 fanda_: i used it for explorative programming

5:06 it is a small dialect of Scheme (LISP)

5:06 spacebat_: open or proprietary?

5:06 I tend to think that common lisp is a bit on the hulking side

5:07 fanda_: yes, common lips is too big

5:07 http://www.newlisp.org/

5:07 spacebat_: but it does seem to be the most widely implemented standard

5:07 fanda_: clojure is more symetrical and more well thought in my eyes

5:07 spacebat_: I've liked that common lisp has been easy to start with

5:07 because it lets me code imperatively

5:08 fanda_: yes, exactly

5:08 spacebat_: but that doesn't fly here

5:08 fanda_: newlisp is similar

5:08 (setq x 5) or (set! x 5) ;-)

5:08 clojure is more pure

5:08 spacebat_: I saw an excellent post on the newsgroup today that spelled it out

5:09 if you make a new value, either give it a new variable, or pass it directly into a function

5:10 fanda_: yes, I also have problems with immutability

5:10 i am thinking about creating some "cook book"

5:10 spacebat_: I've had similar ideas

5:10 fanda_: how to mutate or "looks-like-mutate" ;-)

5:11 spacebat_: gradually accumulating code snippets in a library, a modest general purpose collection at the moment

5:11 fanda_: i have been reading some code from contributions

5:11 now i am trying to create my first useful something :-)

5:12 spacebat_: I haven't even looked into contrib yet

5:13 fanda_: here

5:13 http://groups.google.com/group/clojure/files

5:13 and here

5:13 http://clojure-contrib.svn.sourceforge.net/viewvc/clojure-contrib/trunk/

5:13 spacebat_: I see yes I checked that out of svn but its just sitting on disk so far

5:14 looking at complete programs has been a bit confusing, trying to get the gist from gradually larger chunks of code

5:15 clojure just might be my gateway back to java

5:15 using an IDE to get past the static verbosity of java repulses me these days

5:16 I've been ruined and made anew by dynamic languages

5:17 rhickey was saying that there is a guy in sun who really gets lisp

5:17 and wants to put tail recursion and more functional support in the JVM

5:19 ok newlisp, I have seen that page before, like a year ago

5:19 I've been learning lisp about 3 weeks now

5:20 does it have threads?

5:21 fanda_: what do you mean - if newlisp has threads? no, it doesn't

5:21 spacebat_: ok

5:21 yes that's what I meant sorry

5:21 fanda_: newlisp is written in C

5:21 runs on many platforms

5:21 spacebat_: what brings you from there to here?

5:21 yes portable threading isn't trivial

5:22 fanda_: but it has everything on its own - runtime - garbage collector, etc.

5:22 libraries for one

5:22 you can import only C libraries or write your own lisp libraries - so much time spent there

5:22 kotarak: did anyone encounter issues with agents and clojure.lang.Script?

5:22 fanda_: i have no idea about this one

5:23 spacebat_: me neither sorry

5:23 fanda_: don't be sorry

5:23 spacebat_: heh

5:23 fanda_: :)

5:23 if you have any lisp questions, i might answer

5:23 map, apply, filter...

5:23 lambda (meaning fn) functions

5:24 spacebat_: is there something you don't like about newlisp?

5:24 not asking you to trash it or anything

5:24 kotarak: No. It's more about using agents for concurrency. In the REPL I see the agent output, calling the script "hangs". I'm not sure where or why.

5:24 fanda_: hi kotarak :-)

5:25 kotarak: hello fanda_

5:25 spacebat_: sounds like something a tad advanced

5:25 kotarak: ok. never mind

5:25 spacebat_: maybe the REPL is doing some sync that's needed and not in Script

5:26 fanda_: don't know why he left...

5:26 spacebat_: hunting rather than gathering

5:26 fanda_: hm

5:27 spacebat_: newlisp looks like it has potential

5:27 fanda_: yes, its cool in its own terms

5:27 spacebat_: if its fast, then with the right libs for coordinating processes it could be a real workhorse

5:28 fanda_: here are my creations:

5:28 http://intricatevisions.com/index.cgi?page=newlisp

5:28 just click on the left for code, code-tk, ...

5:28 spacebat_: does it generate binaries?

5:28 fanda_: no, it does not

5:28 its only interpreted

5:28 spacebat_: what tipped lisp over the interest threshold recently was seeing Language::Lisp::ECL on the cpan

5:28 fanda_: but you can make wrappers - wrap newlisp.exe with your script

5:28 spacebat_: ok

5:29 ECL uses gcc as a backend and can compile standalone exes

5:30 fanda_: can be interesting

5:30 spacebat_: a small naive fibonacci program compiled to 24k on disk

5:30 its common lisp, so I guess it leaves out all the stuff that isn't being called

5:30 fanda_: ok, that's interesting!

5:30 spacebat_: it also makes it easy to embed, all common lisp functions are callable from C

5:31 the fib program ran about 10 times slower than a C program with the same gcc, for fib(39)

5:32 but it was still about 6 times faster than the fastest interpreter I tried, which was python

5:32 fanda_: quite interesting

5:33 spacebat_: time to give my boy a bath

5:33 nice chatting fanda_

5:34 fanda_: wait

5:34 spacebat_: yupo

5:34 fanda_: save this link

5:34 http://groups.google.com/group/clojure/browse_thread/thread/69b781ffe805a7de/b60673e9d4436ce0

5:34 spacebat_: will do

5:34 fanda_: comparison CL - Clojure ;-)

5:34 might use it

5:34 spacebat_: thanks, bye

5:34 fanda_: nice chatting!

5:34 bye!

5:40 kotarak: sorry, got disconnected. maybe the output of the agent goes somewhere else in the Script compared to the REPL.

6:22 spacebat_: possibly, you said it hangs though

6:22 whereas it returns in the REPL?

8:31 Chouser: kotarak: you might just try adding (flush) after your print or prn

8:33 kotarak: Chouser: no, doesn't help.... Everything worked before, until a packed the output into an agent (since I have to some sync here). Then it stopped working. In the Script. In REPL it still works.

8:34 rhickey: kotarak: your script may be ending before your agent is done?

8:36 kotarak: huh? It can? Ok.... Hmmm... I (await) the agent, but let me add some sleep there.

8:37 rhickey: if you await in the same thread you sent, then it's done. Who flushes - - the agent or main?

8:37 kotarak: the agent

8:39 also tried a (flush) in the main thread, didn't help

8:40 rhickey: can you paste a small case?

8:41 kotarak: I'll try to strip it done. Just noticed, that the hitting ctrl-c gives me the output. Maybe a have to issue an explicit exit?

8:44 Ahh. Got the problem!!! When using agents, the script doesn't terminate, when reaching the end. You have to explicit call a (. java.lang.System (exit 0)).

8:44 rhickey: heh, I used to do that for you, but GUI app devs complained...

8:46 kotarak: rhickey: well, I'm mostly a non-GUI guy, so I expect a script to exit, when it is end is reached. But that also comes from things like C or sh. There you also have a non-returning function for GUIs. So maybe I just have a differnt point of view.

8:47 rhickey: btw. good job with clojure. It brought me back to the lispy side of life. :)

8:47 rhickey: thanks, glad you worked it out

9:11 Chouser: calls to the "rest" part of a lazy-cons are synchronized, but I suppose I still need to wrap them in sync if I want to use set! on a ref, right?

9:13 rhickey: you mean your rest expression manipulates a ref?

9:13 Chouser: right

9:13 rhickey: Clojure will force you to be in a transaction, else throws

9:14 Chouser: well, reads a ref, but yeah. Ok, that's what I thought.

9:14 rhickey: I though you said set

9:15 Chouser: I did! I'm sorry, I mis-typed.

9:15 actually, I mis-thought.

9:16 sorry, still sketching this out in my head. the rest expr will only need to read the ref (and perhaps block on something). so no sync there! cool.

9:16 rhickey: You can do non-transactional reads of refs

9:17 as long as you don't require a relationship between that read and another

9:18 Chouser: I don't think so. I'm going to try to build a vector in a background thread, while providing a lazy-seq as access to it in the main thread.

9:20 rhickey: Don't ignore things like java.util.concurrent.ArrayBlockingQueue

9:25 Chouser: hard not to ignore things I've never heard of

9:25 * Chouser reads up

9:26 rhickey: Clojure doesn't duplicate the workflow tools of java.util.concurrent because they are really good

9:27 queues/barriers/latches/exchangers etc

9:29 meredydd: rhickey: Ahh...so, that's really the answer to my question a few days ago

9:29 rhickey: meredydd: which question?

9:30 meredydd: about thread pools in Clojure...but java.util.concurrent does one, so Clojure doesn't have its own

9:30 kotarak: that's my main problem with clojure: when you have to fallback to some java stuff, I pretty lost.... (I have no clue about java whatsoever)

9:30 meredydd: (so you just have to do the magic proxy fiddle to turn a (fn) into a Runnable)

9:30 rhickey: actually Clojure does abstract thread pools with agents

9:30 fns are Runnable

9:30 and Callable

9:31 meredydd: They are now? Oh, great!

9:31 (Must have been looking at an old discussion...could have sworn I'd seen you saying that there was a good behind-the-scenes reason (fn)s weren't Runnable)

9:32 rhickey: there is some casting required now to disambiguate for the executor methods which are overloaded on both Callable and Runnable

9:33 that hassle was the only reason, but the tradeoff is worth it since half the java library uses one, and half the other

9:33 meredydd: Ah, excellent.

9:34 Thank-you, then.

9:34 And, by the way, did you do any more thinking about the relational algebra stuff in set.clj?

9:34 Because I've been thinking a little about that

9:35 rhickey: no, what are your thoughts?

9:35 meredydd: and how, of course, the nil-for-empty convention is fine, provided one uses seqs rather than sets

9:36 rhickey: you mean seqs of maps as rels?

9:36 meredydd: yeah

9:36 rhickey: but won't they have to keep being made into sets anyway?

9:36 meredydd: Just thinking that, if you were willing to forgo the mathematical warm-and-fuzzies of exact correspondence to the un-augmented relational algebra

9:36 Well, for what purpose?

9:36 rhickey: efficiency

9:37 meredydd: Of which operations? (Sorry, haven't poked around enough in set.clj to see how you do this stuff)

9:37 Joins, I suppose.

9:37 rhickey: right

9:37 meredydd: Ah, bugger. The man has a point.

9:37 Damn it - it's just that I was thinking

9:37 rhickey: also I like the rel is a set of maps rule, i.e. no dupes

9:38 meredydd: yep. As I say, nice mathematical warm-and-fuzzies with the exact correspondence to the RA

9:38 rhickey: with the twist of a non-fixed set of columns

9:39 meredydd: yeah, well...it's that, or a set of vectors, which wouldn't be as nice to work with.

9:39 rhickey: that's the special sauce of Clojure rels - non rectangular/sparse

9:39 meredydd: indeed.

9:40 Anyway - I was just musing that if you were to work with seqs, you could create a nice hack to use a proper SQL back-end for these things

9:40 and, because the seqs are lazy, you could have ops like joins, pi, sigma, etc fold themselves into the SQL statement

9:40 rhickey: seq->set once on load seem not too bad

9:40 seems

9:41 meredydd: which is only actually executed when (first) is actually called on the seq

9:41 which would, neatly, allow you to keep all the relational operations Clojure-idiomatic.

9:42 (at the cost of some "Is it a bird? Is it a plane? Is it a seq, or an SQL wrapper?" hackery in the back-end.)

9:44 kotarak: Hmmm... Is there something in using agents, which turns off flushing? Suddenly I have to add (flush)es all over the place.

9:44 Or is java.lang.System.exit discarding unflushed stuff?

9:45 meredydd: kotarak: I think java.lang.System.exit is just killing the VM before the agents get a chance to run what you've sent them

9:45 rhickey: If you have multiple thread writing to the same stream you're likely to get a mess at some point. Maybe confine your I/O to a single place and have the agents just create the to-be-output values?

9:47 kotarak: I have one agent, which does the output stuff. So this is in sync. It's also (await)ed by the main thread. So there should be no problem here. I think exit just kills the VM, with flushing. Give me a second.

9:48 Yep. It's java.lang.System.exit. Is there some way of a sane shutdown? (Ie. doing things like flushing output.)

9:48 rhickey: await/flush/exit doesn't work?

9:49 kotarak: it does.

9:49 The flush is a bit anoying

9:49 But maybe this is again my different background. Just have to get used to it.

9:50 rhickey: there have been requests that the pr* fns flush

9:52 kotarak: I'm used to "newlines flush" and also exit() flushes. So flush is somehow the default for me. Now java.lang.System.exit does not flush. *poof* I have problem. But that's simply the wrong default on my side.

12:19 Chouser: tomhickey_: on clojure.org's left-hand menu, the clickable area for each link extends the full width of the menu. Top notch!

13:15 rhickey: new essay: http://clojure.org/state

15:40 abrooks_: Chouser: Good observation regarding tomhickey_ 's good UI. Nicely done tomhickey_!

16:20 scgilardi: pjb3: I liked the picture of Rich you posted the other day captioned "State: You're doing it Wrong"

16:26 I have a thought about the flushing issue: it's often a good thing to flush on newline, but sometimes the inefficiency matters. How about a var *flush-on-newline* whose global binding is to "true" which is used to control whether or not some subset of the "pr*" functions flush on newline (or flush with each call).

16:28 I also like the idea I saw for "dbg*" functions that auto-flush as debugging is often a case where flushing matters

16:46 rhickey: scgilardi: *flush-on-newline* whose global binding is to "true" works for me

16:51 scgilardi: cool, thanks.

17:39 rhickey: user=> *flush-on-newline*

17:39 true

18:17 Chouser: hmph. can't properly store nulls in an ArrayBlockingQueue

18:18 rhickey: aargh

18:31 Chouser: but false works fine, so using that as an end sentinel, this does what I want:

18:31 (for [e (repeatedly #(.take q)) :while e] e)

19:40 rhickey: gotta love repeatedly

Logging service provided by n01se.net