#clojure log - Mar 24 2009

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

0:01 arohner: clojurebot: paste

0:01 clojurebot: lisppaste8, url

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

0:02 arohner pasted "subset" at http://paste.lisp.org/display/77511

0:02 arohner: is there a better way to accomplish this?

0:02 dnolen_: why not use filter?

0:04 sorry I see what yr doing.

0:07 looks good to me.

0:09 cemerick: arohner: try select-keys

0:09 ,(select-keys {:a 5 :b 6 :c 7} [:a :c])

0:09 clojurebot: {:c 7, :a 5}

0:09 arohner: that's *exactly* why I ask these questions :-)

0:09 thanks

0:10 cemerick: np

0:10 dnolen_: nice

0:13 cemerick: arohner: FWIW, select-keys is basically what you pasted, except where it's defined in core.clj, 'into' isn't defined yet, so loop/recur is used to accumulate the map

0:13 heh, and for isn't available there yet, either

0:14 arohner: yeah, I ran (source select-keys)

0:16 cemerick: arohner: source?

0:16 arohner: ,(source select-keys)

0:16 clojurebot: java.lang.Exception: Unable to resolve symbol: source in this context

0:17 arohner: ,(clojure.contrib/source select-keys)

0:17 clojurebot: java.lang.ClassNotFoundException: clojure.contrib

0:17 arohner: grr, one last try

0:17 ,(clojure.contrib.repl-utils/source select-keys)

0:17 clojurebot: java.lang.ClassNotFoundException: clojure.contrib.repl-utils

0:17 arohner: ,(require 'clojure.contrib.repl-utils)

0:17 clojurebot: java.io.FileNotFoundException: Could not locate clojure/contrib/repl_utils__init.class or clojure/contrib/repl_utils.clj on classpath:

0:18 arohner: anyways, a very cool function

0:18 durka42: ~source select-keys

0:19 cemerick: arohner: yes, definitely. Didn't know about that one!

0:21 blbrown: should we use clojure-contrib for most clojure applications.

0:21 cemerick: whew, looks like the source is ready by the source fn when it's called -- had a moment of concern there that it was hanging off of every fn as metadata

0:21 blbrown: if you need it, then that's all that matters, I suppose.

0:21 blbrown: hmm, no download

0:22 durka42: i think you have to use the sv

0:22 svn

0:22 should we try to tag contrib revs corresponding to each release?

0:23 arohner: durka42: that would probably be a good idea

0:23 durka42: i mean, basically just the rev that was latest when the release happened

0:23 * durka42 thinks about posting something on the group about it

0:23 durka42: i don't know if the idea has already come up

0:27 arohner: might as well post it

0:29 jochu: I have a quick question, in gen-class/gen-interface :methods return-types - is it possible to set an array return type?

0:33 cemerick: jochu: if you're using gen-class, I believe so; if you're using the :gen-class form in ns, no

0:33 blbrown: the clojure mascot. suck on that #haskell http://www.flickr.com/photos/berlinbrown/3380716557/

0:34 cemerick: (class (make-array String 0)), etc.

0:34 blbrown: http://www.flickr.com/photos/berlinbrown/3381537052/in/photostream/

0:36 cemerick: cute

0:36 haskellers are good folk, tho. There's more that unites us than divides us, IMO.

0:36 blbrown: hehe

0:37 jochu: cemerick: Hmm, I thought I tried that - :methods [[ReturnsStringArray [] "L]java.lang.String"]] doesn't work (NoClassDefFoundError), am I doing that wrong?

0:38 cemerick: jochu: pretty sure "L]java.lang.String" won't work -- you need to get a reference to (class (make-array String 0)), and refer to it there.

0:39 it's possible I'm being daft right now, tho

0:39 * cemerick is pretty tired, into the last 20 min. :-P

0:42 hjlee: my clojure group post doesn't appear. any idea?

0:42 cemerick: hjlee: if you sent it by email, it can take some time to propagate

0:43 hjlee: ah... then ... peoples receive 3 same messages...

0:44 but 1st message sent hours ago.

0:44 takes that long?

0:50 cemerick: I've had emails to google groups take a day to show on the group's web UI.

0:51 blbrown: to rhickey I just got a look at the clojure java code, you might run it through a checkstyle coding standards checker like program. Just a suggestion

0:51 cemerick: it seemed like that had been resolved, though.

0:54 hjlee: nah.. a day..

0:56 jochu: cemerick: Hmm, I don't think you can pass variable values like that into gen-interface/class

0:57 cemerick: jochu: we do it right now :-)

0:57 that *doesn't* work in the :gen-class form in ns, but if you're using the gen-class "manual" fn, then it's all good

0:58 durka42: blbrown: i think rhickey intentionally doesn't pay much attention to coding standards :)

0:59 blbrown: durka42 I am writing something on the forum about it

0:59 hjlee: ah... found reason - "Messages from new members are moderated"

0:59 cemerick: blbrown: don't bother -- he rebuffs any and all code style suggestions for the java stuff

1:00 blbrown: well, I should rebuff all clojure conventions

1:01 cemerick: I guess that's your choice, but I think Rich has some special privileges. :-)

1:01 blbrown: no one is special

1:01 cemerick: apparently, it ends up looking good in IntelliJ, which is what he uses for the Java stuff.

1:02 blbrown: there are no comments on any of the classes

1:02 cemerick: blbrown: not sure you'll find many who'd agree with that

1:03 blbrown: ideally it should be 100%

1:05 cemerick: heh, no thanks. People aren't interchangeable.

1:06 jochu: cemerick: :( Not trying it in the ns form, (gen-interface []

1:07 cemerick: bah, premature sending - but yeah, doing it in an gen-interface and not having any luck.

1:09 cemerick: jochu: FWIW, gen-interface and gen-class are two completely separate mechanisms -- they share nothing, as far as I can tell at a glance

1:11 we absolutely pass concrete classes in for signatures (constructor signatures, in our case) to gen-class -- we calculate them from return types on methods on the interfaces provided to our macro

1:11 durka42: that seems strange, unless classes and interfaces are more different animals than i had imagined

1:13 cemerick: durka42: interfaces are absurdly simple compared to classes -- the mechanisms probably could be unified, but they were developed independently. gen-class by rhickey, gen-interface by Chouser

1:13 durka42: ah

1:14 Raynes: If you inherit a person class, is that like sex with a person object?

1:14 jochu: cemerick: Ah, thanks. Then I guess I'm asking the wrong question, with gen-interface only - is possible to set an array return type? :P

1:15 cemerick: jochu: I guess you know better than I at this point, as I've never used gen-interface ;-)

1:17 patching gen-interface so that it evaluates the symbols provided certainly wouldn't be difficult -- not sure whether such a patch would cause issues for people who are using it already, though

1:18 blbrown: Raynes, where did you learn sex ed?

1:18 cemerick: I know that defining array types as well as parameterized types is on the todo list, though (probably implemented by specifying the string representation of the desired classes, so "[Ljava.lang.String" or "List<String>" would work as you'd expect).

1:19 Raynes: blbrown: Never took sex ed. ;)

1:22 Gilbert987: hi everyone

1:22 i'm going through "programming clojure" (the book)

1:22 and it's telling me to put "clojure-contrib.jar" in my classpath

1:23 however, i don't see this file in the zip file that i downloaded

1:23 am i missing sth?

1:23 Raynes: Gilbert987: It's in the 'lib' directory. It doesn't matter however if you use the REPL script included with the sample-code.

1:23 If you use the REPL script included it will put everything on the class-path for you.

1:23 cemerick: g'night all

1:24 Raynes: Night cemerick

1:25 Gilbert987: Raynes: by script, do you mean "java -cp clojure.jar clojure.lang.Repl" ?

1:26 Raynes: Gilbert987: In the sample-code, in the bin directory I believe, there are scripts, these scripts when executed will load the REPL with the classpath of everything that is used within the book.

1:39 hiredman: hjlee: you still here?

1:40 ah

1:40 nevermind

2:32 Gilbert987: if i don't know a what a function does

2:32 for e.g : "some"

2:32 what can i do to see its docstring or other types of documentation?

2:32 Cark: ,(doc some)

2:32 clojurebot: "([pred coll]); Returns the first logical true value of (pred x) for any x in coll, else nil. One common idiom is to use a set as pred, for example this will return true if :fred is in the sequence, otherwise nil: (some #{:fred} coll)"

2:33 Cark: do the same at the repl, without the comma

2:41 hiredman: well

2:41 with or without the comma, your choice

2:42 Cark: hum true

2:43 that does not make sense

2:46 hiredman: ?

2:48 Cark: ahyes whitespace ... i was thinking common lisp there

3:21 l_a_m: good morning

3:26 Gilbert987: does anyone know if there's a couchdb library for clojure?

6:42 AWizzArd: thewizzard_: The word "wizard" is correctly written with only one "z" :)

6:43 thewizzard_: AWizzArd: :p

6:44 wanted to change the nick anyway... thanks for the reminder :)

7:17 AWizzArd: Well, my nick is now about 14 years old or so, and back then I didn't know about the one z, so I myself have to live with the wrong spelling.

8:08 hjlee: anyone with successful jswat or other debugger?

8:27 AWizzArd: hjlee_: only sometimes successful. jswat sometimes enters a breakpoint, although it is not fully clear to me yet when this happens and when not.

8:37 hjlee_: AWizzArd: thank you. I'm wondering.

8:41 ericthorsen: hjlee_: We are using Netbeans

8:41 hjlee_: ...debugger

8:42 hjlee_: erichthorsen: ah, does Netbeans debugger work well with clojure?

8:43 I'm downloading eclipse clojure-dev now.

9:25 AWizzArd: clojurebot: max people

9:25 clojurebot: max people is 164

9:35 leafw: does anybody know well the ExecutorServices

9:36 digash`: leafw: i have a pretty good idea about it.

9:36 leafw: how in the world can a submit(Callable) throw a RejectedExcecutionException? The java code for that class shows that only when the service is saturated it should be rejected. But then, how can one queue, not submit, a future task?

9:36 i.e. I thought that submit would queue, and get executed when it can.

9:37 I never expected the service to reject anything on the basis of being "saturated". I thought it would queue.

9:37 digash`: leafw: queues have limits, depending on the implementation

9:38 leafw: digash`: I see. So I have to find out how to enlarge the queue then

9:38 digash`: leafw: i've seen it blow up on out of memory

9:38 leafw: I'd like a fixed thread pool but more or less unlimited Callable queue of jobs.

9:39 so far it blows up with 4 or 5 elements queued

9:39 makes no sense to me.

9:40 digash`: it should not blow up with such a small number can you lisppaste an example

9:40 leafw: Executors.newFixedThreadPool(4); should give me such service ... unbounded, as the docs say.

9:42 digash`: it's part of a large app: http://repo.or.cz/w/trakem2.git?a=blob;f=ini/trakem2/persistence/FSLoader.java;h=1a46048a7f811f4d9408e9a04e123b8d4cfe1a33;hb=29dd2cceee8404af24427cb2c0a1ecb65f2836bd#l2422

9:43 would help a lot more if I could understand the error. As far as I can see, the quue is not full at all, yet the task is rejected.

9:45 * digash` taking a look at a lot of Java code.

9:47 leafw: digash`: it's ok, ... likely the error is somewhere else.

9:47 I am translating this entire app to clojure, as a drastic measure to get all threading right.

9:59 lisppaste8: digash` pasted "executor service" at http://paste.lisp.org/display/77526

10:02 leafw: I know ... and that doesn't crash

10:02 thanks in any case

10:11 digash`: you can increase it to a million in that example and there is no problems.

10:16 leafw: digash`: my best guess is that there is a problem in completing the task and it gets resubmitted infinitely, but for some reason it doesn't report so

10:19 digash`: leafw: interesting never run into that problem

10:26 leafw: digash`: I meant the problem is on my side. The whole thing is linked to a canvas repaint.

10:27 bstephenson: digash`: nice example. Helps me with something I am working on. How would I use this approach if instead of wanting to do something 10 times, I wanted to use this to map a function across a collection, in a thread-ly way?

10:30 leafw: bstephenson: (doc pmap)

10:30 ,(doc pmap)

10:30 clojurebot: "([f coll] [f coll & colls]); Like map, except f is applied in parallel. Semi-lazy in that the parallel computation stays ahead of the consumption, but doesn't realize the entire result unless required. Only useful for computationally intensive functions where the time of f dominates the coordination overhead."

10:31 bstephenson: yes! thx, leafw

10:38 banisterfiend: anyone know where i can find a beta copy of the book 'programming clojure' ?

10:39 leafw: banisterfiend: you can purchase it already

10:39 then you'll receive betas until it's done; then the book.

10:39 eevar2: banisterfiend: http://www.pragprog.com/titles/shcloj/programming-clojure

10:39 banisterfiend: beta in e-copy?

10:40 rsynnott: yep

10:40 a pdf, specifically

10:40 with your name at the bottom

10:40 banisterfiend: nice

10:40 you can get it ALOT cheaper on the amazon site though

10:41 or so it seems, it's about $25 on the amazon site, but the link you gave me is charging $40, maybe it's the beta copies that push up the price

10:42 eevar2: 40 is dead tree version + pdf

10:42 21 for just the pdf

10:43 banisterfiend: oh ok

10:43 http://www.amazon.com/Programming-Clojure-Stuart-Halloway/dp/1934356336

10:43 it doesn't say anything about it just being a pdf though, afaict

10:44 dliebke: I don't think you can get the beta version of the book through amazon.com. Only through pragprog.com

10:46 you can only pre-order through amazon, and wait until the final version of the book is published

10:46 banisterfiend: ah ok

10:46 dliebke, but do you think the amazon version which is about $21 is the actual book or just the pdf?

10:46 it doesn't say anything on the site about it just being a pdf

10:46 dliebke: the amazon version will be the actual book, not the pdf

10:47 banisterfiend: well that's amazing it's just $21 then!

10:47 :))

11:37 Chouser: cemerick: why does SciCL suggest reader macros?

11:39 cemerick: Chouser: because scientists and mathematicians (and all sorts of disciplines) don't want to screw with "normal" sexprs

11:40 Chouser: you're thinking of a syntax more tailored for them than what's shown at http://www.siginf.com/13023.html ?

11:40 gnuvince: What a bunch of preciouses

11:41 cemerick: Chouser: yeah -- his slides specified that various datastructures with special semantics were defined using {...}, [....], etc (apparently to be aligned with matlab)

11:41 Chouser: ah

11:43 cemerick: I can definitely see the utility there...not for me, but I don't think we want to make clojure comparatively inhospitable for scientific computing (and other domains that are used to particular notation, maybe).

11:44 Chouser: I'd have to see what the desired syntax is, but there's quite a bit you can do without full-on reader macros

11:45 cemerick: Definitely. And the notion of simply building a proper compiler as part of a sci-comp library is certainly out there (well-voiced in the 'are macros a menace' debate :-) )

11:46 Chouser: Was that last night? did you notice if anyone was taping it?

12:04 sohail: anyone tried clojure with gcj?

12:14 durka42: there isn't a seprate google group for contrib, is there?

12:14 Chouser: nope

12:15 durka42: oh, well i was just going to post an idea i had, but i could ask you first

12:15 the idea was to tag contrib revs when releases happen

12:15 and maybe tar them up somewhere

12:15 so people who download releases and are looking for contrib don't run into compatibility issues with the latest svn

12:15 Chouser: yeah, that sounds like a good idea.

12:17 would it be just a jar, or a zip that contains the jar as well as other stuff?

12:18 durka42: i think it'd be useful to, upon a release, check out the latest contrib, ant jar WRT the released clojure.jar, and tar.gz that whole directory for http://code.google.com/p/clojure-contrib/downloads/list

12:18 so the source and the built jar

12:19 Chouser: would you recommend they add the .jar or the src dir to their classpath?

12:20 durka42: well if you decided to work from a specific release you would just need the jars

12:20 if you were going to hacking contrib you'd want to have the src of course

12:20 digash`: we should ask tapestry guys to include clj-contrib in their nightly builds

12:20 durka42: e.g. (source partition-by) is really useful though -- does src need to be on the CP for that?

12:20 Chouser: there's another nighly build server that already has both

12:20 durka42: yes it does

12:21 digash`: which one?

12:21 durka42: hmm, probably want to do that then

12:21 digash`: is it maven repository?

12:21 durka42: does it still work if you build the jar such that the clj files are in it

12:21 Chouser: durka42: I think so

12:22 durka42: i think it does, because i don't have the src dir on my classpath

12:23 jar built with ant -Dclojure.jar=/path/to/clojure.jar has .class and .clj files in it

12:23 Chouser: so would there still be value in a zip, or would the jar be sufficient?

12:23 durka42: then probably just the jar would be good

12:24 digash`: we should have Maven repo, maven allows src jars, doc jars etc.

12:25 durka42: the user i have in mind goes to http://code.google.com/p/clojure/downloads/list and downloads clojure_20091230.zip, then goes to http://code.google.com/p/clojure-contrib/downloads/list and wonders where contrib_20091230.zip is

12:25 the situation right now if you want contrib you have to go svn latest with both or risk incompatibilities, right?

12:26 digash`: it will be all available for download through http and also integrates with all the IDEs

12:26 durka42: is if*

12:26 Chouser: durka42: yes, or use svn to fetch an old version of contrib to go with your clojure release

12:26 what about a zip and/or jar that includes both contrib and a clojure release?

12:26 durka42: right, but it's nontrivial to search through svn history for a date, isn't it

12:28 digash`: why reinvent dependency management, when maven infrastructure already provides it and IDEs/command line tools support it.

12:28 durka42: true

12:29 Chouser: I can't find the link for the non-tapestry nightly builds

12:29 digash`: i use the tapestry repo through maven and it is great and easy to use.

12:30 i would love to have clojure-contrib in their

12:30 Chouser: I actually thought contrib *was* in there, but I don't see it now.

12:30 jsankey: http://pulse.zutubi.com/

12:30 Chouser: jsankey: thanks! that's it.

12:31 jsankey: has both core and contrib, and i'm working on integrated test reporting in the clojure-contrib-reports project

12:31 durka42: rev 1337?

12:31 that's a good number

12:31 jsankey: currently it builds continuously, i can also set up a nightly build if people want

12:31 Chouser: it already says 810 passed -- is that working?

12:31 jsankey: durka42: haha, didn't notice that

12:32 Chouser: yeah, it mostly works

12:32 i just have details to sort out, plus cleanups to the code

12:32 Chouser: is -reports from test-clojure or test-contrib or both?

12:32 jsankey: the 810 is actually the number of (is ...) expressions

12:33 which is more than the number of deftests

12:33 Chouser: sure

12:33 jsankey: -reports does test-clojure, test-contrib and test-datalog

12:33 Chouser: ah, great.

12:33 jsankey: you can drill into the build results to see them as suites

12:34 durka42: this is a nice interface

12:34 http://pulse.zutubi.com/browse/projects/clojure-contrib-reports/builds/15/tests/default/test-clojure/clojure.contrib.test-clojure.agents

12:34 jsankey: pulse actually has an ivy repository built in, in this bleeding edge version i have installed

12:35 durka42: thanks :)

12:35 you can browse it at: http://pulse.zutubi.com/repository/

12:35 durka42: 401

12:35 Cark: durka : the link for "test suite test-clojure" and the next one are not working

12:36 jsankey: oh, you can sign up for an account on the login page

12:36 durka42: ah, ok

12:36 Cark: did you mean that for jsankey

12:37 jsankey: Cark: ah, thanks, I hacked something by hand and looks like I messed that up :|

12:38 you can also get the latest working and compatible (so far as the testing can attest anyhow) clojure and contrib from:

12:38 http://pulse.zutubi.com/browse/projects/clojure-contrib/builds/success/artifacts/

12:40 * durka42 has to go

12:42 jsankey: if you're extra keen you can sign up, add a contact point (e.g. email address) and subscribe to notification emails

12:42 there are also rss feeds for build results

12:42 digash`: jsankey: does it have maven repo?

12:43 jsankey: no maven, i'm afraid

12:43 digash`: ivy is cool, but most of the IDEs right now support maven

12:43 I am stuck with it since my project is a mix of Java and Clojure and uses Maven

12:44 jsankey: although we are considering what it would take fo the built in repo to be maven-compatible

12:44 digash`: as i understand it, it should not be difficult.

12:45 jsankey: it's probably just about mimicking the layout and delivering a pom

12:45 as i say, these are bleeding edge pulse features, so still a work in progress :)

12:46 digash`: yep, take a look at the http://repo1.maven.org/maven2/

12:46 * digash` got to get some lunch

12:48 jsankey: of course even if we don't build in a maven repo, we could publish to another one

13:00 Cark: ~def send

13:01 ~def clojure.lang.Agent/dispatch

13:01 ~def clojure.lang.Agent

13:09 a question about agents : outside a transaction, is it safe to assume that an action trigered with send or send-off is directly enqueued ?

13:11 hiredman: you mean they are not held till another time then enqueued?

13:11 Cark: yes

13:11 hiredman: sends with-in an agent action are held until the action completes

13:12 Cark: ok let me explain, i'm playing with nio, i have an agent per connection and an agent for the server

13:12 the server is blocking on a select

13:13 hiredman: I gotta run

13:13 Cark: damn =/

14:28 hiredman: back

14:31 Raynes: hiredman: You're my hero.

14:32 hiredman: ...

14:32 durka42: Raynes: i saw your sneaky almost-palindromic clojure program

14:33 Raynes: durka42: Damn that Brian Carper!

14:33 Found me out. :|

15:21 tsdh: Hi. Is there a way to import a whole java package without naming all the classes?

15:25 Cark: nope

15:25 i remember seeing some code to do it anyways

15:26 tsdh: Ok, thanks.

15:26 Cark: but there's nothing in vanilla clojure

15:27 Chouser: There will probably be some automatic performance enhancement based on the idea that you've imported the classes your code is actually likely to use.

15:28 importing a bunch of classes you don't need may complicate that, not to mention making the code harder to read since many people may not know which package a class belongs to, and thus won't know where to find docs for it.

15:37 tsdh: Well, in my case I need to import a package which contains 50 classes, and I'm going to need them all. ;-)

15:38 hiredman: ouch

15:39 tsdh: Yes, but I admit that this is rather uncommon.

15:52 Chouser: fortunately

16:30 jwinter_1: Has Rich posted his ILC09 slides?

16:32 hiredman: I think I saw posts of slides from presentation 1 and 3

16:32 clojurebot: delicious?

16:32 clojurebot: delicious is http://delicious.com/clojurebot

16:32 Chouser: jwinter_1: they're on the google group files list

16:32 jwinter_1: thanks

16:37 durka42: why did delicious move away from del.isio.us?

16:37 del.icio.us

16:38 SethTisue: i could never remember where the first dot went

16:43 Chouser: I wonder why 'throw' is a special form instead of just a Java method, like in RT

16:43 perhaps it's just for the sake of the generated stack trace?

16:50 digash`: it does not abide by the normal Java method invocation semantic

16:52 there is an instruction in the jvm for athrow

16:53 http://java.sun.com/docs/books/jvms/second_edition/html/Compiling.doc.html#9934

16:56 Chouser: but there could be a fn or macro named 'throw' in clojure that turns around and calls RT.throwVal( e ), which could in turn just do a Java throw

16:56 hm, I guess it participates in type hinting oddly

16:59 digash`: it would pollute the stack with the call

17:03 Chouser: yes, that's the only reason I could think of -- I suppose it's sufficient.

17:06 berth_: Hi, I am trying to read the java version like that: (.getProperty (java.lang.System) "java.version")

17:06 But I get java.lang.ClassCastException: java.lang.Class .

17:07 hiredman: (System/getProperty "java.version")

17:07 berth_: Thanks, is that a general rule for static methods?

17:08 hiredman: yes

17:08 ,(macroexpand '(System/getProperty "java.version"))

17:08 clojurebot: (. System getProperty "java.version")

17:08 hiredman: ,(macroexpand '(.getProperty (java.lang.System) "java.version")

17:08 clojurebot: EOF while reading

17:08 hiredman: ,(macroexpand '(.getProperty (java.lang.System) "java.version"))

17:08 berth_: Interesting, thanks a lot.

17:08 clojurebot: (. (java.lang.System) getProperty "java.version")

17:09 berth_: , (+ 2 2)

17:09 clojurebot: 4

17:09 berth_: ... now that's funny. :-)

17:09 ,(System/getProperty "java.version")

17:09 clojurebot: java.security.AccessControlException: access denied (java.util.PropertyPermission java.version read)

17:09 berth_: wow.

17:20 kib2: Pathetic: http://www.wisdomandwonder.com/link/2110/why-mit-switched-from-scheme-to-python

17:22 cmvkk: that made a lot of sense to me; then again, i have no problem accepting python as a good learning language

17:23 i wonder how clojure fares in terms of 'first languageness'? Even though it's hands down my favorite language now, and I find programming in it pretty easy,

17:23 I get the feeling if someone asked me for tips on learning to program, I'd still reccomend starting wtih Ruby.

17:24 p_l|backup: java & bluej is certainly a bad way to teach

17:24 gnuvince_: I recommend Python

17:24 kib2: cmvkk: Python is a good langage to learn, I've no problem with it too. What's pathetic for me is "In 1980, good programmers spent a lot of time thinking" : what now ?!

17:25 gnuvince_: It allows a new programmer to quickly use it to make script that can benefit him

17:25 cmvkk: kib2 I see what you mean; i didn't get that comment either. but the rest makes sense to me.

17:25 p_l|backup: kib2: now they spend time cursing

17:25 gnuvince_: It's easy to stay motivated that way.

17:25 cmvkk: about things being understandable all the way down before, and now they aren't.

17:25 gnuvince_: SICP is nice and powerful, but I don't think it would grasp most programmers when they begin

17:26 kib2: gnuvince: not so sure...

17:26 * p_l|backup today had seen the proof that java&bluej based program is much, much worse than many others

17:26 cmvkk: i think the thing about functional program a la clojure is, while it makes doing real programming much simpler, it still isn't as intuitive for simple tasks as a regular imperative language would be

17:26 gnuvince_: kib2: somebody who starts to play the guitar doesn't want to know about scales and arpegioes, he wants to learn 10 chords to play songs and sing along.

17:27 I believe that for a lot of people who take up programming, they just want to solve one or a few little problems.

17:27 So give them something good for that

17:27 And if they get hooked, then they can make their own journey into SICP and Haskell and CLRS

17:27 p_l|backup: gnuvince_: that was purpose of things like shell scripting, perl etc.

17:28 Chouser: I'd be very curious to see if it really would be hard for someone to learn clojure as a first language.

17:28 hiredman: that hardly compares to a being programing course

17:28 cmvkk: p_l|backup, I think perl falls into the same category here as python and ruby

17:28 gnuvince_: p_l|backup: I would recommend them if I didn't think Python was a better choice for someone new.

17:28 cmvkk: you can use those languages like that.

17:28 p_l|backup: I was referring to elder times :)

17:29 cmvkk: the question is whether clojure can be a language that's easy for beginners to learn,

17:29 whether clojure can be a language that's easy to write simple tasks in.

17:29 gnuvince_: I don't think it's easy. Simple, yes; easy, maybe not so much.

17:29 kib2: gnuvince: sure, SICP is rather hard (and if you really try to find all the exercices solutions, it's even harder but worth it).

17:29 cmvkk: and if not, why not? it's not like you can't write compicated programs in python and ruby; you can do both things in those languages.

17:29 gnuvince_: It makes "sense" to modify something

17:30 You have a "sum" box, you just add something more to it by modifying it

17:30 cmvkk: gnuvince_ yes i think that's the crux of the problem. imperative programming is just plain intuitive.

17:30 gnuvince_: It may not be the best of habit, but I think it certainly makes sense to somebody who's starting out.

17:31 hiredman: honestly, I cannot imagine my classmates in the last CS course I took having any more trouble with clojure then they did with java

17:31 but they had a lot of trouble with java so...

17:31 cmvkk: hiredman, on the flip side though, I always got the feeling Java was a terrible language to learn on

17:31 way worse than python would be

17:31 * p_l|backup has troubles imagining a more clueless course than his java one, so clojure would be rather quick to learn

17:31 kib2: What really amazed me the first time I've read some parts of it was the little computer algebra system they introduce. Doing such things in Python is much more difficult than Scheme/Lisp.

17:31 Chousuke: cmvkk: python teaches you that code that compiles doesn't always work

17:32 Chouser: I really don't know. once you've spent a day learning basic or python or any other procedural/imperative language, that's a day's worth you'll have to re-learn to use clojure or something functional.

17:32 Chousuke: "it compiles, ship it!"

17:32 "but it's full of stubs!"

17:32 Chouser: but if you start with the idea that things don't change, I'm not sure that's actually any more difficult to grasp.

17:32 cmvkk: Chouser, so in other words, you think it doesn't matter if languages like clojure are easier to learn than other languages, because they're necessary.

17:32 Chouser: you don't even have to think about "locations"

17:33 cmvkk: in the end, you have to have a language like clojure, so you might as well just go with it from the start?

17:33 Chouser: no, I'm not asserting anything. I'd like to know if someone could learn clojure first just as easily as learning python first.

17:33 cmvkk: ah, okay. that's basically what I want to know.

17:34 Chouser: or if immutable collections and immutable locals are inherently harder to grasp. I really don't think the answer is obvious.

17:34 hiredman: the idea that imperitive is easier is silly, when you see how much trouble people have with it

17:34 cmvkk: to me, python feels more intuitive from a beginner's perspective. but then again, I personally started programming with gw-basic, so maybe that shapes my opinions.

17:34 hiredman: without even going into thread safety, etc

17:34 Chousuke: people might have expectations that don't apply to clojure.

17:35 Chouser: cmvkk: right, I started with basic and then got several years of various imperative languages under my belt before even hearing of immutable locals or collections.

17:35 and of course my first thought was: how the heck can you *do* anything??

17:35 gnuvince_: Chouser: the only way you could know is to have a large sample. You would need many programmers who begin programming in functional languages.

17:35 cmvkk: yeah, me too. and when i started learn-- yeah, when i started learning common lisp, that's exactly what I thought.

17:35 gnuvince_: And unless you force them, that's probably never gonna happen.

17:35 Chousuke: Chouser: I guess you could counter that question with something cryptic like "how do you think functions in mathematics work?"

17:36 hiredman: I finished the third and final CS course the local community college offers about a year ago. this was the *third* course and people still had trouble with basic things like looping around arrays, etc, or building stuff outside of an environment like bluej

17:36 gnuvince_: I hang in a french programming irc channel, and no matter how much I encourage newbies to begin with Python for a variety of reasons documented on my blog, they all end up going to C or C++

17:36 All of them

17:36 Chouser: well one of these days one of my kids will show a spark of interest in programming and I'll ram something into their heads. ;-)

17:36 p_l|backup: C is not that bad of a choice... C++ on the other hand...

17:36 gnuvince_: Because "I hear they're the most popular/powerful languages" or "they're *real* programming languages" or "they're fast" or whatever.

17:36 cmvkk: heh

17:37 gnuvince_: p_l|backup: I wouldn't start somebody on C. Probably go with Python to learn about variables, loops, conditions, functions, etc. and then take a step back and look at C.

17:37 Chousuke: Chouser: just make sure it's got lots of parentheses.

17:37 p_l|backup: gnuvince_: they have one thing better than those who end learning Java all the way as it's shown in introductory courses in unis...

17:37 cmvkk: it seems odd because nowadays, i think of Ruby as being 'the popular language'. if you want to do web programming, that is, and apparently that's all anyone ever wants to do anymore

17:37 kib2: gnuvince-: so they only think "speed" is better ?

17:37 p_l|backup: gnuvince_: namely, they get hurt by the machine :)

17:37 gnuvince_: kib2: who doesn't think that?

17:38 kib2: gnuvince_: your readers think that speed matters

17:39 gnuvince_: p_l|backup: could the fact that they, themselves, decide to learn programming instead of just doing what the course requires of them, count for something?

17:39 I know that I won't ever be good at math, because I only care about learning what I need to pass the classes I take.

17:39 p_l|backup: gnuvince_: that too

17:39 * p_l|backup is just in bad humor after his lecture today

17:49 cconstantine: Chouser: The types of things that could be thrown from a function is a part of the method signature in java.

17:52 meredydd: Hey - anyone here tangled with the Java SecurityManager stuff?

17:52 danlarkin: meredydd: hiredman has

17:52 meredydd: Specifically, I'd like to identify stuff from the Clojure classpath

17:53 uhh, "classpath" is the wrong word

17:54 Restate: I'd like to be able to identify, in my security policy, the actual generated code rather than the Clojure compiler

17:54 (so, for example, it's entirely reasonable for the former to run without (RuntimePermission createClassLoader), there's no way the latter could)

17:55 Is there a way to do this for dynamically (eval)ed code, or am I just going to have to AOT everything?

17:55 hiredman: danlarkin: not really

17:56 it sounds like meredydd acutally knows how policy files work

17:57 * meredydd didn't this morning, and rather wishes he still doesn't.

17:57 meredydd: *still didn't

17:57 hiredman: word

17:57 meredydd: Sausages, law, and JVM sandboxes.

17:58 Chouser: cconstantine: oh, of course.

17:59 hiredman: meredydd: any particular jvm sandboxing resources you'd care to share?

18:00 meredydd: Uhh...unfortunately, there appears to be no such "good resource".

18:00 If you have a question, I'll see if I can answer it, and figure out where I found that answer, though.

18:00 hiredman: makes me feel better about not finding one

18:01 I would like to disallow catches in clojurebot's sandbox

18:02 meredydd: I'm trying to sandbox Rhino scripts right now, and mostly used Google, the Rhino javadocs (ignore the "developer docs" wiki, the security stuff is hopelessly out of date and refers to classes that don't exist any more), and when all else failed, reference to the source of an existing implementation (the Apache batik SVG viewer, which has safely embedded javascript).

18:03 Sorry, not that relevant to you...

18:03 wb

18:03 hiredman: man

18:03 irssi sure picked a great time for that

18:03 meredydd: Summary: I don't think my experience from today is all that useful to you

18:04 hiredman: ok

18:04 * hiredman soldiers on

18:04 meredydd: basic JVM stuff like try/catch falls outside the SecurityManager's remit

18:04 All those permissions are manually checked, with calls to SecurityManager.checkPermission() and friends

18:05 hiredman: wait, what?

18:05 meredydd: You're trying to disallow use of (try ... (catch ...)) in the clojurebot sandbox, yes?

18:05 hiredman: outside the sm's remit, but is checkusing sm.checkPermission

18:06 meredydd: yes

18:06 currently I just check the macroexpanded form for 'catch

18:06 but I would be more comfortable if the jvm took care of this for me

18:07 meredydd: Oh, sorry. What I meant was, "the checks that are within the SM's remit, like 'can I write to this file?', are checked manually, by code in (eg) java.io.File, which calls SecurityManager.checkPermission() and friends)

18:08 hiredman: hmmm

18:08 I see

18:08 * digash` voting for Rich to be on the board of ALU.

18:08 Chouser: ALU?

18:08 meredydd: So I'm guessing you'd have to modify the compiler to reject (catch)s.

18:09 sellout: digash: Can you vote for him for me, too?

18:09 meredydd: What's the reason? What nefarious thing can a clojurebot user do with a catch block?

18:09 sellout: Although, Peter Seibel got on the board in 2005 and later resigned out of frustration ...

18:10 digash`: sellout: are you a member?

18:10 sellout: digash`: I'm at the conf (so, yes), but not at the meeting.

18:10 hiredman: meredydd: you can use a try/catch block to send it into a loop of trying and catching which thread.stop cannot break out of

18:11 meredydd: Oh, that.

18:11 digash`: sellout: they give me only one peace of paper to write names on.

18:11 sellout: digash`: just write it twice ;)

18:11 meredydd: hiredman: Rhino apparently disallows catching of Errors, just to let you do things like that

18:11 sellout: I kid ... I do think he'll get on, though.

18:11 meredydd: which is a strong indication that there's no JVM-level way of saying "no, really, kill this thread *now*"

18:12 hiredman: :(

18:12 sellout: Wait ... Rich isn't at the meeting, is he? He was just talking to me a few minutes ago.

18:12 meredydd: (I'm surprised by Thread.stop(), though - I thought it was deprecated because it was too brutal...)

18:13 digash`: sellout: Yes, he is here.

18:13 meredydd: (Oh, right. You can still catch the ThreadDeath. How silly.)

18:13 hiredman: tell me about it

18:13 digash`: sellout: Come over and vote!

18:14 meredydd: hiredman: My only thought is that you could patch the compiler to refuse to compile (catch)es

18:14 hiredman: ugh

18:14 meredydd: (or, even better, refuse to compile (catch)es of anything not a subclass of Exception)

18:15 Should be a one-liner. But yes, I agree, Ugly City.

18:16 hiredman: Sorry I can't be more help.

18:16 hiredman: not your fault

18:17 digash`: Rich is on the board of ALU now!

18:17 hiredman: haha

18:17 suckers

18:21 cconstantine: What is ALU?

18:23 hiredman: assoc. of lisp users?

18:23 SethTisue: yes

18:24 lisp.org

18:24 cconstantine: ah

18:24 I'm a lisp user... I'm guessing that means an important lisp user ;)

18:29 meredydd: Rats. Looks like the Clojure compiler doesn't mention that a class comes from disc...

18:38 cconstantine: I'm writing a palendrome detector, and I've found something weird: given a list, and the reverse of the list, it's faster to just do a (= in-order-list rev-order-list) than it is to do (= (take half-size in-order-list) (take half-size rev-order-list)). Can anyone explain that?

18:38 duck1123: are you going for that write hello world as a palindrome challenge?

18:39 cmvkk: it might be that 'take' just maps over a list with a counter, so traversing (take 5 foo) would be slower than traversing foo itself.

18:39 but would it be twice as slow?

18:40 durka42: cconstantine: take brings in lazy-seq machinery. i don't know if that's slow

18:40 cconstantine: durka42: no, project euler

18:40 cmvkk: oh, is 'take' eager?

18:40 durka42: no

18:40 ,(take 5 (iterate inc 0))

18:40 cconstantine: it claims to be lazy

18:40 clojurebot: (0 1 2 3 4)

18:41 cmvkk: (do (take 5 (map (fn [x] (print "h")) (repeat 0))) nil)

18:41 ,(do (take 5 (map (fn [x] (print "h")) (repeat 0))) nil)

18:41 clojurebot: nil

18:41 hiredman: ~def take

18:41 cmvkk: guess it's lazy

18:42 cconstantine: the longest of these lists is 6 items long

18:42 cmvkk: 'cows'

18:42 cconstantine: ooo, I wonder if wrapping it in a take each time kills some kind of caching going on with the lazy-seq it's working with

18:44 durka42: ,(let [ls '(1 2 3 4 5 6 7 8 9 10) rev (reverse ls)] (time (= ls rev)) (time (= (take 5 ls) (take 5 rev))))

18:44 clojurebot: "Elapsed time: 0.098 msecs" "Elapsed time: 0.059 msecs"

18:45 cconstantine: hmm

18:45 durka42: microbenchmarks like this may or may not be useless

18:45 ,(let [ls (range 10000) rev (reverse ls)] (time (= ls rev)) (time (= (take 5 ls) (take 5 rev))))

18:45 cconstantine: this is true... my time is something like 2-3 seconds

18:45 clojurebot: "Elapsed time: 0.112 msecs" "Elapsed time: 0.067 msecs"

18:45 durka42: whoops

18:46 cconstantine: hehe

18:46 durka42: ,(let [ls (range 10000) rev (reverse ls)] (time (= ls rev)) (time (= (take 500 ls) (take 500 rev))))

18:46 clojurebot: "Elapsed time: 0.105 msecs" "Elapsed time: 0.06 msecs"

18:46 durka42: oh, i have to go

18:46 cconstantine: thanks :)

18:46 durka42: happy palindroming

18:48 hjlee: sorry, why 500? must be 5000?

18:49 cconstantine: ,(let [ls (range 10000) rev (reverse ls)] (time (= ls rev)) (time (= (take 5000 ls) (take 5000 rev))))

18:49 clojurebot: "Elapsed time: 0.111 msecs" "Elapsed time: 0.061 msecs"

18:49 cconstantine: good point

18:52 hjlee: ah... but i think "=" only take 1st element the above case. why first "=" so slow?

18:53 hiredman: erm

18:53 why would "=" take only the first element?

18:53 ah

18:54 reverse

18:55 Raynes: Is there a function to zip up a sequence? Like say you had [['a] ['b']] and wanted to turn it into ['a 'b].

18:56 [['a] ['b]]*

18:56 hiredman: that is not zip

18:56 that is flatten

18:57 there is always apply concat

18:57 Raynes: hiredman: I was thinking of Haskells zip function.

18:57 And thanks.

19:11 blbrown: is there a Java approach for loading scripts through Java. E.g. can I call main.legacy_script(String[] args); with multiple scripts...more than one time and keep the state of the interpreter

19:11 hmm, or I could create my own 'main' class

19:35 jhawk28: has anyone seen: http://www.newartisans.com/2009/03/the-jvm-and-costs-vs-benefits.html

19:42 johnw: jhawk28: I have ;)

19:42 albino: johnw: yeah, johnw is the author of that

19:43 err that was for jhawk28

20:17 * cconstantine fought the lawn, and the lawn won.

21:26 texodus: hello

21:26 durka42: hi texodus

21:26 cmvkk: hello

21:26 texodus: got a few minutes to help me with some concurrency questions?

21:27 * durka42 doesn't unfortunately

21:27 durka42: have to run in a sec

21:27 texodus: tragic

21:27 cmvkk: well i'm here but i don't know how helpful i can be

21:27 texodus: Well, I'll ask and see what comes from it

21:29 I'm trying to parse a large dataset

21:29 and each entry has some crypto and date parsing and whatnot to be done

21:30 durka42: clojurebot: can clojure do crypto and date parsing and whatnot?

21:30 clojurebot: Yes, Clojure can do that!

21:30 p_l: ... not this shit again

21:30 texodus: sure :)

21:30 cmvkk: heh

21:30 texodus: but I want to do it in parallel

21:30 cconstantine: I've got one too.... :) I have a list of number sets ([1 2 3] [2 3 4] [3 4 5] ...) and only one of them will return true for my predicate. How can I multi-thread the search for the set that is true for my predicate? The math in the predicate should be hard enough to warrant the threading overhead.

21:30 texodus: and creating those objects for each task is a taxing

21:30 durka42: agents :)

21:30 cconstantine: texodus: agents or future

21:31 hiredman: ,(doc pvalues)

21:31 clojurebot: "([& exprs]); Returns a lazy sequence of the values of the exprs, which are evaluated in parallel"

21:31 hiredman: ,(doc pmap)

21:31 clojurebot: "([f coll] [f coll & colls]); Like map, except f is applied in parallel. Semi-lazy in that the parallel computation stays ahead of the consumption, but doesn't realize the entire result unless required. Only useful for computationally intensive functions where the time of f dominates the coordination overhead."

21:31 texodus: yes, but I don't want to create a new crypto parsing objects for every datapoint - is there a way to use send-off with a thread-local copy of the java bits, to be reused?

21:31 cconstantine: hiredman: is there something like pfilter?

21:32 cmvkk: hmmm

21:32 dreish: cconstantine: You could write one using pmap.

21:32 hiredman: cconstantine: I would make sure the predicate returns the data or nil

21:32 then filter identity

21:32 er

21:32 then pmap, then filter identity

21:32 cconstantine: That would work..

21:33 thanks :)

21:34 cmvkk: texodus, you have stuff you want to do in parallel, but you want to reuse an object

21:34 texodus: so, is there a way I can use binding to create thread-local copy of an instance, eg DateFormat, that would be used only for that agent for every fn that is sent to it?

21:34 exactly

21:34 I dont want to recreate the java objects for every function

21:34 cconstantine: ,(doc future)

21:34 clojurebot: "([& body]); Takes a body of expressions and yields a future object that will invoke the body in another thread, and will cache the result and return it on all subsequent calls to deref/@. If the computation has not yet finished, calls to deref/@ will block."

21:35 hiredman: texodus: if the java object is stateful that you really have littel choice

21:35 cmvkk: so maybe you create 4 of these objects, then spin off 4 agents that just loop grabbing a chunk, parsing it, then doing it again

21:35 hiredman: stateful and not thread-safe

21:36 dreish: Not necessarily. I don't see why the binding approach wouldn't work, if you can figure out how to string it together.

21:36 cmvkk: i did this with byte-buffers once. split up the file to be rendered into chunks, then spun off N agents or so. every agent grabbed the next available chunk, parsed it, then put the result in a ref, grabbing the next one.

21:36 hiredman: dreish: it would only work if he bound a sepperate object each time

21:36 cmvkk: concurrent, and only N byte-buffers, just reused over and over again.

21:36 dreish: hiredman: For each thread, which I think is the whole point.

21:37 hiredman: *shrug*

21:37 cmvkk: it's certainly possible, but there's no built-in way to do it.

21:37 texodus: I coudl write a macro to create n agents and n instances, then just manage handing them off

21:37 but I was hoping someone else had already climbed this mountain

21:37 dreish: Or a function!

21:38 Even more powerful than a macro!

21:38 texodus: right, functions are worth fewer life achievement points :)

21:38 * dreish starts in on this crusade again. ...

21:38 hjlee: texodus: why reuse something like DateFormat?

21:38 cmvkk: texodus that's basically what you want to do i think. it's really something you have to hand-roll based on what sort of data you're working on and what you're doing to it.

21:39 texodus: dateformat is a trivial example

21:39 hjlee: the objects are stateful?

21:40 texodus: if they were, is the only answer to wrap them in java concurrent to make them thread safe?

21:41 I dont really have a concrete example, clearly instantiating a new dateformat is no huge efficiency drain

21:41 the crypto stuff is worse

21:42 cmvkk: i don't think mutable java objects play well with clojure's concurrency semantics

21:42 dreish: They're not so bad with thread-local bindings.

21:42 texodus: I'd like to be able to say something like (def some-agent (agent-with start-state & thread-local-bindings)

21:42 cmvkk: yeah, that's basically the only option

21:42 dreish: They don't play well with programs that are easy to reason about, in general, but that's not a Clojure-specific feature.

21:43 So you're no worse off than in most languages, in the worst case.

21:43 cmvkk: texodus, what you want is a function that creates a copy of whatever java object you want, then uses it to process N entries, then returns all those entries at once.

21:44 then you pass THAT to an agent.

21:44 texodus: hrmm

21:44 that may work

21:45 dreish: Feh. Too simple. There must be a more complicated way to spend weeks banging your head against a wall.

21:45 cconstantine: wow, so my Core 2 Duo is NOT happy with all this multi-threading :) Its fans are going like crazy and I get answers really fast.

21:47 texodus: so, on a completely unrelated question, is there a way to create a blocking function in clojure other than through overlapping transactions?

21:48 Chouser: overlapping transactions may not block. :-)

21:48 (doc locking)

21:48 clojurebot: Executes exprs in an implicit do, while holding the monitor of x. Will release the monitor of x in all circumstances.; arglists ([x & body])

21:48 texodus: right, so also consistent blocking

21:48 Chouser: (doc future)

21:48 dreish: (locking ob (...))

21:48 texodus: ah so

21:48 clojurebot: Takes a body of expressions and yields a future object that will invoke the body in another thread, and will cache the result and return it on all subsequent calls to deref/@. If the computation has not yet finished, calls to deref/@ will block.; arglists ([& body])

21:48 dreish: (doc locking)

21:48 clojurebot: Executes exprs in an implicit do, while holding the monitor of x. Will release the monitor of x in all circumstances.; arglists ([x & body])

21:48 texodus: that was easy

21:49 thanks

21:49 very helpful channel

21:49 dreish: Twice as helpful as channels were just one guy gives you the same answer!

21:49 cconstantine: hehe

21:50 Chouser: ha

22:15 arohner: I have an ns declaration, where I use a (:require [foo :as bar]). Now I want to change the ns foo to something else, but reloading the file complains that bar already points to foo. is there a way to unalias foo?

22:17 ah, ns-unalias

22:17 (doc ns-unalias)

22:18 clojurebot: Removes the alias for the symbol from the namespace.; arglists ([ns sym])

23:17 matthew`: Hi, I am interested in using Clojure and the Netbeans platform. How do people link up the actions with Clojure code?

23:17 Also what is done about build and delivery.

23:18 Chouser: matthew`: you've looked at "enclojure"?

23:19 matthew`: Chouser: I have looked at enclojure.

23:19 Chouser: well then you've exhausted my knowledge. :-)

23:19 matthew`: Even in enclojure the two seem like separate entities.

23:20 I am talking in terms of the Netbeans platform.

23:20 Chouser: oh, you want to customize netbeans itself using clojure?

23:21 matthew`: Yes, I want to build a netbeans platform application using clojure.

23:21 So I want to join a Java action up to a Clojure function.

23:22 Chouser: well, you could look at the enclojure sources themselves.

23:22 matthew`: What's more is that I want to be able to deliver such and application. The dynamic nature of Clojure has me a bit stumped there.

23:22 Chouser: you have two routes for calling clojure from java

23:22 matthew`: Yes that sounds like a good idea.

23:23 arohner: I'm not familiar with netbeans, but I assume that means you need to inherit from a java class?

23:23 Chouser: either use gen-class and AOT compilation to create .class files that look like what netbeans is expecting

23:23 or write java code that calls clojure fns using the .invoke() method

23:26 matthew`: Thanks for information. I will investigate the two options and the enclojure code itself. Thanks again.

23:26 Chouser: enclojure uses the latter, last I knew

23:35 http://en.wikibooks.org/wiki/Clojure_Programming/Tutorials_and_Tips#Invoking_Clojure_from_Java

23:50 matthew`: Chouser: Thanks.

Logging service provided by n01se.net