#clojure log - May 21 2009

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

0:17 cemerick: what is this org.infolace.format ClassNotFound exception about?

0:19 the stack trace points at the compiler, but I'm sure that's not where the root reference is. The exception is thrown when attempting to print something to stdout...

0:20 oh, it's cl-format stuff....which I somehow inherited a dependency on? :-/

0:21 danlarkin: muhahaha! can't keep them out

0:22 hiredman: :(

0:31 cemerick: grrr, a full grep reveals no com.infolace at all

0:31 com.infolace occurrences, I should say

0:32 replaca: cemerick: oops, infolace is me - just joining - what's up?

0:33 cemerick: I'm not sure. I was upgrading our enclojure REPL library, and now I'm getting classnotfound exceptions sporadically when using it, but I can't for the life of me find any infolace references in the source.

0:33 I'm pretty tired though, so this may straighten itself out in the morning.

0:33 replaca: oh, the macroexpand might be pretty printing

0:34 cl-format and pprint were originally on github & named with my domain com.infolace.cl-format

0:34 but now they've moved (a few months ago) into clojure.contrib.pprint

0:34 cemerick: it's actually reporting classnotfound for com.infolace.format

0:34 replaca: that's just an error?

0:35 there was never any such namespace

0:35 it was com.infolace.cl-format

0:35 cemerick: "FileNotFoundException: Could not locate com/infolace/format__init.class or com/infolace/format.clj" *shrug*

0:36 replaca: interesting, let me take a quick look at git history

0:38 apologies, the namespace was com.infolace.format & the function was cl-format

0:38 so you must have code that points at the old pretty print or cl-format routines

0:39 cemerick: not me, I'm just a bystander ;-)

0:39 replaca: if you can find out what code it is, you should be able to just point it at c.c.pprint and go on your way

0:39 cemerick: yeah, I understand

0:39 maybe you need an ant clean somewhere?

0:40 cemerick: tried that, but I'm sure I'll try that again

0:40 is there a way to make lib loading verbose, so I can trace the dependencies?

0:40 replaca: I've nver looked at enclojure, so that's probably as much light as I can shed on it

0:41 cemerick: replaca: sure, thanks for trying :-)

0:41 replaca: dunno, it would be useful

0:41 danlarkin: cemerick: there is, it isn't springing to mind at the moment though

0:41 I think you can pass :verbose to require maybe?

0:42 cemerick: danlarkin: yeah, I just found it... (require :verbose 'blah)

0:42 danlarkin: tada

0:43 replaca: ahh, that's a good trick to know

0:46 cemerick: it only works for the requires or uses in a particular file though -- it's not like a binding, so you have to run around attaching it to the various files that are being loaded.

0:48 danlarkin: isn't it just a front end option for *loading-verbosely*?

0:50 cemerick: danlarkin: dunno. It didn't carry through to verbosely loading my dependencies, tho

0:51 danlarkin: yeah, even when binding *loading-verbosely* to true I don't get the output without using :verbose

0:51 oh well, it's late, I'm off

0:52 cemerick: replaca: I found the bum reference, BTW.

0:53 enclojure ships with a custom build of cl-format, apparently

0:57 replaca: cemerick: argh! the problem with open source :-)

0:58 cemerick: heh, indeed. It doesn't seem necessary, at least for the REPL library part of it. Pretty heavy dependency for the context, IMO.

0:59 replaca: well, I could see why folks want it (after all that's why I wrote it)

1:00 it would be nice if we could make the version of contrib work for them though

1:00 who does enclojure?

1:01 cemerick: Eric Thorsen and co. I'm sure they're aware of clojure.contrib.*. There's likely very good reasons for it, etc.

1:02 replaca: yeah, but I could possibly adapt changes. if they started from the version on github, they're using old code

1:02 cl-format hasn't changed too much (though it's a lot faster now) but pprint has changed a lot

1:03 but who knows, maybe he's doing crazy different things

1:07 gcv: Is Clojure 1.0.0 not compatible with swank-clojure? I get java.lang.NoSuchMethodError: clojure.lang.Namespace.importClass(Ljava/lang/Class;)Ljava/lang/Class; (pprint.clj:0) in my *inferior-lisp* buffer.

1:08 replaca: gcv: you need to compile/recompile contrib

1:09 gcv: swank wants the gen-class'ed pretty printer for macroexpansion

1:10 * gcv hits self on head

1:10 gcv: replaca: thank you

1:11 replaca: gcv: no prob. enjoy your pretty macroexpansions :-)

4:33 alrex021: I have setup Aquamac on my Mac with clojure-mode. Now I have tried adding Clojure Slime support and I get "not connected" when doing C-c C-z

4:34 Any ideas as to when one would get the "not connected" story? in my customization.el I have a (server-start)

4:58 yangsx: ,(defn my-zipmap [keys vals] (loop [my-map {} my-keys (seq keys) my-vals (seq vals)] (if (and my-keys my-vals) (recur (assoc my-map (first my-keys) (first my-vals)) (rest my-keys) (rest my-vals)) my-map)))

4:58 clojurebot: DENIED

4:59 yangsx: ,(my-zipmap [:a :b :c] [1 2 3])

4:59 clojurebot: java.lang.Exception: Unable to resolve symbol: my-zipmap in this context

5:01 yangsx: ,((fn [keys vals] (loop [my-map {} my-keys (seq keys) my-vals (seq vals)] (if (and my-keys my-vals) (recur (assoc my-map (first my-keys) (first my-vals)) (rest my-keys) (rest my-vals)) my-map))) [:a :b :c] [1 2 3])

5:01 clojurebot: Execution Timed Out

5:03 yangsx: hi, anybody know why the example at the end of http://clojure.org/functional_programming cited above does not produce a result? I guess it might be a bug. Can anybody confirm that?

5:06 Chousuke: yangsx: looks like a bug; the rest calls should be nexts instead

5:08 likely a remnant from the not-so-lazy times when rest returned nil instead of ()

5:36 yangsx: Chousuke: I see the problem now. The example at the web page should be fixed then. Hopefully jhickey will notice this.

7:05 manytalks: anyone going thru the programming-clojure book?

9:03 Chouser: it'd be neat if 'apply' could indicate that it returns the same type as its first arg does, without manual hinting.

9:37 cgrand: Chouser: reduce too... would the Qi stuff -- that Rich mentioned -- help to do that?

9:38 Chouser: yeah, I wonder. it does seem a bit like you'd need a language (datalog?) to descibe the rules.

10:53 digash: ,((fn [fn] (list fn (list (quote quote) fn))) (quote (fn [fn] (list fn (list (quote quote) fn)))))

10:53 clojurebot: ((fn [fn] (list fn (list (quote quote) fn))) (quote (fn [fn] (list fn (list (quote quote) fn)))))

10:56 porpoise: i'm trying to write a macro that defn's a function, but am getting "can't use qualified name as parameter"

10:56 durka42: nice quine :)

10:56 porpoise: paste it?

10:57 porpoise: for example (defmacro make-mult [name mult] `(def ~name [x] (* x ~mult)))

10:58 er make that

10:58 for example (defmacro make-mult [name mult] `(defn ~name [x] (* x ~mult)))

10:58 digash: that is the shortest I could come up with.

10:59 * durka42 fiddles in a repl

10:59 durka42: right so the ` is resolving everything inside it to a namespace

10:59 so it comes up with user/x and defn doesn't like that

10:59 (do a macroexpand to see what i mean)

10:59 digash: yep

10:59 porpoise: yup

10:59 durka42: to prevent it use ~'x

11:00 digash: looks very similar to http://www.nyx.net/~gthompso/quine.htm

11:00 porpoise: thanks! works

11:01 now i just need to understand what happened

11:01 ` causes everything in the form to resolve to a namespace?

11:02 ~ binds to the macro parameters, and ' prevents resolving to the namespace?

11:02 clojurebot: Titim gan �ir� ort.

11:02 durka42: the first about ` is right

11:02 digash: durka42: i started with another one from Peter Norvig's paper http://portal.acm.org/citation.cfm?id=121989.121990

11:02 Chousuke: hm

11:03 durka42: ~ is unquote, it "breaks out" of ` and forces evaluation of the form after it

11:03 clojurebot: I don't understand.

11:03 durka42: ,(let [a 3] `(a ~a (inc a) ~(inc a)))

11:03 clojurebot: (sandbox/a 3 (clojure.core/inc sandbox/a) 4)

11:04 durka42: ' always quotes things so ~'a evaluates 'a, which is just a, not namespace/a

11:04 Chouser: of course it'd be better to use x# unless you specifically intend to capture x

11:04 Chousuke: right.

11:04 was just about to say that ;)

11:06 (defmacro whatever [name thing] `(defn ~name [x#] (stuff x# ~thing)))

11:08 in general, ~'foo is rarely needed; it's usually simply wrong unless your macro is *intended* to introduce names that are not passed as a parameter to the macro

11:12 in the above example, the user wouldn't care about what the function parameter is called, so using ~'x would be wrong

11:13 rhickey_: please use x#

11:14 that's why it's there, to prevent capture, ~' is for intentional capture, rare

11:19 gnuvince: rhickey_: for a second there, I thought you were recommending we use X Sharp (http://www.xsharp.org/)

11:20 Chouser: ha!

11:20 cemerick: X# is code and code is poetry, ? X# is poetry!

11:20 rhickey_: yikes

11:21 cemerick: Either that, or X# is a big yellow kool-aid man.

11:24 Chouser: I've got a clojure lib that uses agents internally. It will generally be called from .java code. Currently the java app hangs, presumably waiting on the agent pools.

11:24 clojurebot: clojure is a language to use if you want to up your game

11:25 Chouser: I guess the only solution is for the java app to indicate somehow that it's done, so the agent pools can be shut down.

11:26 Should I have it call Agent.shutdown() directly, or provide my own method that does the same thing?

11:27 replaca: rhickey_: just wanted to let you know that everything is set up for the Bay Area Clojure meetup on June 3rd

11:29 porpoise: is it possible for me to write a macro for scheme-y nested function defines, (nestdfn (((f a) b) c) (g a b c)) ?

11:30 i'll try hacking away at it... it should be doable

11:30 right?

11:31 replaca: porpoise: did you look at letfn?

11:32 porpoise: looking at it now

11:32 thanks

11:33 rhickey_: replaca: where will it be?

11:34 Raynes: I'm going to take a wild guess and say the bay area.

11:34 :D

11:34 rhickey_: Chouser: probably best not to expose Clojure internals to consumer apps

11:35 porpoise: actually, maybe the scheme-y nested function defines, like (define ((((f x) y) z) w) (g x y z w)) isn't necessary because partial is a nice way of currying things

11:36 replaca: porpoise: does nesting enable currying? Is that what that's expressing?

11:37 porpoise: yep, what it expresses is that (f x) returns a function that takes y which returns a function that takes w

11:37 and returns (g x y z w)

11:38 i'm reading a physics book that uses scheme to express its ideas, and it uses that style a lot

11:38 replaca: rhickey_: it's going to be at my office (unless we get a better location) -> about three blocks from Moscone

11:40 porpoise: I see. I like the haskell thing that *all* funcs are curryable at any arity. (partial) does kind of the same thing

11:40 rhickey_: replaca: sounds good - can you send me an email with the details (time/address)? Also, if other Clojurians are in town for JavaOne, I presume they'll be welcome as well?

11:40 porpoise: replaca: yep, but if you're doing a lot of currying, you'll type "partial" a lot

11:42 replaca: rhickey_: Yeah, I'll get you all the deets and I'm going for the biggest possible clojure crowd, so I'll post to the list, give you info that you can give to other interested folks at JavaOne and also invite the bayfp folks

11:42 porpoise: but i can always give it another name if I use it that much, and if not, then "partial" is an easy to understand name

11:43 replaca: porpoise: yeah, the *really* nice thing in haskell is thet auto currying based on arity. Unfortunately, that kind of conflicts with multiple and arbitrary arities.

11:44 I know hiredman has done a bunch of stuff to support a more point-free style concisely

11:44 porpoise: replaca: I like haskell a lot too. It's an interesting trade off that they went for.

11:45 I actually took up scala before clojure because i thought it might be more haskell like. But I ended up using it in a Java-ish way. Maybe I was using it wrong. I'm programming a lot more functionally in clojure, and the same program is half the length.

11:45 replaca: porpoise: I *really* don't like the idea (which seems to be in both scheme andd scala) that the writer of the function determines how it can be curried

11:46 porpoise: right

11:46 replaca: porpoise: I've just been learning scala the last week or so, mostly so I can do some compare and contrast exercises

11:46 * Chouser just finished chapter 2 of Real Work Haskell

11:46 porpoise: in scheme and scala you need to check the function definition to make sure you're currying correctly

11:47 replaca: Chouser: is it awesome? I went to a presentation by the author a year or so ago at bayfp and was very impressed. But I don't want to disappear back into Haskell right now

11:47 porpoise: yeah, that's just wrong

11:48 Chouser: it's informative. I now know now enough to make it a little further through the finger trees paper than I could before.

11:48 it's easy to read, and doesn't shy from mentioning potential drawbacks in Haskell design decisions, which is a good way to earn my respect.

11:48 aravind: hi

11:49 Chouser: I'm reading the online web version, which has reader comment on almost every paragraph -- an interesting way to read technical material, for sure.

11:49 aravind: hi

11:50 replaca: Chouser: sounds like it might be a little distracting. RWH is on my reading list for sure, but not right this sec

11:50 haskell and clojure are both like bad drug addictions for me and I can't support being a double junkie right now :-)

11:50 Chouser: the comments are collapsed by default, but if a paragraph is confusing, controversial, etc. you can tap the link and expand the discussion

11:51 * porpoise is a double junkie

11:51 aravind: I am new to clojure, and trying to write a LDAP connection library. I am using the novell jldap library and wanted to setup some sort of a connection object that runs a search, gets the results and disconnects. I was looking at the sql.clj source for ideas and it looks like they use with-open a lot.

11:51 Chouser: I don't expect Haskell to lure me away, but I feel like I need to be able to at least read Haskell code and should understand its type system.

11:52 replaca: Chouser: haskell is really mind-bending when you get into it, but I'm sure you know that already

11:52 Chouser: aravind: all that with-open does is bind a local name and then call .close on it at the end of the block.

11:52 replaca: Chouser: plus it makes you feel purer, like a buddhist monk or something

11:52 porpoise: Yeah, monads are purifying

11:53 taoist, perhaps?

11:53 aravind: it appears that with-open depends on the class having a .close method to terminate the connection, but jldap doesn't have that menthod. Am I looking at the right thing here, should I be extending the jldap classes?

11:53 replaca: porpoise: :-)

11:53 aravind: do you need a shutdown there at the end?

11:53 aravind: Chouser: right, what should I do if the class I am using doesn't have a close method?

11:53 Chouser: aravind: does it need to be closed via a method of some other name?

11:54 aravind: replaca: well.. jldap uses a disconnect. It would be nice if with-open took a method name as an optional argument or something.

11:54 clows: right.

11:54 replaca: aravind: you can just use (try ... (finally )) to accomplish the same thing

11:54 Chouser: aravind: or write a with-disconnect macro

11:54 replaca: aravind: or you can write an equivalent macro in about 2 lines of code

11:54 ~def with-open

11:55 aravind: just look there and you'll see how simple with-open is

11:55 Chouser: ha! 3 lines no more

11:56 aravind: okay. I guess, my question was more along the lines of "am I even looking in the right direction" and I guess I wanted to stick to what was already defined and is known to work, than invent my own thing...

11:56 Chouser: that does sort of suggest a more general (with-finally close [...] ...) macro or something.

11:56 aravind: but I guess writing my own is the way to go here?

11:59 I was also thinking if I should just extend the class with some sort of proxy that adds a close method, that then calls the disconnect method in the original class.

12:00 replaca: aravind: I'd go with writing your own

12:01 aravind: okay. thanks for the pointers.

12:01 replaca: The problem with generalizing this is that you get awfully close to the try/finally form pretty fast

12:02 aravind: sure, glad to help

12:11 rhickey_: question about metadata on namespaces?

12:12 rhickey_: right now it seems to get lost in gen-class'ing, which means no ns doc for compiled classes.

12:12 rhickey: should we have an issue on this?

12:52 triddell: ,(dissoc {:a "a" :b "b" :c "c"} (first '(:a :b)))

12:52 clojurebot: {:b "b", :c "c"}

12:53 triddell: anyone know how I can remove the (first) above and dissoc both keys in the list? I know I could pass them literally in this example but the list comes in through a function parameter.

12:54 technomancy: triddell: apply?

12:55 ,(apply dissoc {:a "a" :b "b" :c "c"} [:a :b])

12:55 clojurebot: {:c "c"}

12:56 triddell: technomancy: thanks!

12:59 twism: danlarkin: ping

12:59 danlarkin: twism: pong

12:59 twism: did you ever get to run the test

12:59 ?

12:59 danlarkin: which test?

13:02 cp2: hello guys

13:04 danlarkin: hello

13:27 noidi: is there a standard way of stripping the namespace prefix off a symbol?

13:27 'foobar/baz --> baz

13:27 Chouser: ,(name 'foo/bar)

13:27 clojurebot: "bar"

13:27 Chouser: ,(symbol (name 'foo/bar))

13:27 clojurebot: bar

13:27 noidi: thanks!

13:28 Chouser: sure

14:13 duncanm: what's the status of streams in Clojure right now?

14:13 rhickey_: duncanm: waiting for my better idea (coming soon)

14:17 sopel: what's the clojure way to do python: [f(x) for f in collection]?

14:18 cp2: ,(doc map)

14:18 clojurebot: "([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls]); Returns a lazy sequence consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each coll, until any one of the colls is exhausted. Any remaining items in other colls are ignored. Function f should accept number-of-colls arguments."

14:18 danlarkin: (map f collection)

14:18 cp2: ,(map #(+ 2 %) [1 2 3 4 5 6])

14:18 clojurebot: (3 4 5 6 7 8)

14:18 Chouser: ,(for [x [2 3 4]] (* x x))

14:18 clojurebot: (4 9 16)

14:18 Chouser: either way

14:19 hlship: Is clojurebot really a bot or just someone obessive w/ a clever name ? :-)

14:19 sopel: Chouser is someone obsessive w/a clever neme, clojurebot is a bot

14:19 :)

14:19 they both know everything though hehe

14:19 Chouser: :-P

14:20 hiredman: clojurebot: how much do you know?

14:20 clojurebot: I know 300 things

14:20 hlship: now that's just freaky

14:21 danlarkin: Chouser: how much do you know?

14:21 hiredman: sounds like everything to me

14:21 Chouser: I know nothing

14:21 danlarkin: borked! restart chouser

14:21 sopel: ,(shutdown)

14:21 clojurebot: java.lang.Exception: Unable to resolve symbol: shutdown in this context

14:21 danlarkin: Chouser: now how much do you know?

14:22 Chouser: I know what you did last summer.

14:22 sopel: hehe

14:22 danlarkin: :-o

14:25 hiredman: I wonder if wolfram has an ajax search api

14:26 twism: they do have an api

14:29 duncanm: hmm

14:34 durka42: You can access the API via a web service from technologies such as AJAX and Flash, or from applications written in any programming or scripting language.

14:34 http://www.wolframalpha.com/developers.html

14:40 sopel: hm, what do i do if i want to have a global thread safe counter?

14:40 which i can increment.

14:41 cp2: (def *counter* (ref 0))

14:41 (dosync (alter *counter* ....))

14:41 hiredman: or an atom

14:41 or an agent

14:41 cp2: yeah

14:41 technomancy: an atom sounds best, since inc is never going to block

14:41 keeping it in a transaction is overkill

14:42 cp2: i suppose

14:42 hiredman: what about agent vs. atom

14:43 sopel: ok i was reading about atoms and it wasn't that obvious

14:43 hiredman: Chouser: where is the handy chart?

14:44 http://clojure.googlegroups.com/web/clojure-conc.png

14:45 technomancy: hiredman: if you were doing more calculation then an agent would make sense, but if all you're going to do is increment it, you don't need it to be async

14:46 Chouser: if you want to be able to get a new value from the counter in your current thread, an agent is a poor fit.

14:46 if the value of the counter ever has to be synchronized with any other mutable state, use a ref

14:46 if not, atom.

14:47 sopel: it's just an in-memory sequence (like a db sequence)

14:47 providing consecutive numbers to threads.

14:50 hiredman: you could have a producer thread that just keeps counting upwards and puts each number in a bounded blockingqueue, then have your other threads read from the queue

14:50 Chouser: ooh.

14:50 seque

14:50 hm

14:51 nevermind, that wouldn't work.

14:51 hiredman: I dunno that seque would work

14:54 Chouser: but still, that's an extra thread and the readers would still have to queue up to pull ids out. might as well use an atom.

14:54 hiredman: :P

14:55 depending on the amount of readers, the size of the queue, and how fast you can fill it

14:55 sopel: yea, and if i want thread pools then i use the java thread pools?

14:57 Chouser: ,(_def id (atom 5))

14:57 ,(_defn get-id [] (swap! id inc))

14:57 clojurebot: #'sandbox/id

14:57 Chouser: ,[(get-id) (get-id)]

14:57 clojurebot: #'sandbox/get-id

14:57 [6 7]

14:58 Chouser: ,(get-id)

14:58 clojurebot: 8

14:58 Chouser: sopel: yep, or use agents, in which case they'll use their own thread pools.

14:58 ,(clear-temps)

14:58 clojurebot: nil

14:58 Chouser: ,(get-id)

14:58 clojurebot: java.lang.Exception: Unable to resolve symbol: get-id in this context

15:23 ataggart: just to aid my understanding, how would the memoize fail if you replaced the map-holding atom with just a map?

15:24 in the example at the bottom of http://clojure.org/atoms

15:24 duncanm: is there a call in the built-in libraries that'll take '((a) (b) (c)) into '(a b c) ?

15:24 flatten?

15:24 hiredman: ataggart: how would you add new things?

15:24 duncanm: i thought (into '() '((a) (b) (c))) would work, but that's not it

15:24 Chouser: ,(apply concat '((a) (b) (c)))

15:24 clojurebot: (a b c)

15:24 hiredman: so memoize works by saying for input A the output is B

15:24 duncanm: oh, concat

15:25 ataggart: in the example, replace (let [mem (atom {})] with (let [mem {}], and (swap! mem assoc args ret) with (assoc mem args ret)

15:25 hiredman: ataggart: maps are immutable

15:25 Chouser: ,(into [] (map first '((a) (b) (c))))

15:25 clojurebot: [a b c]

15:25 hiredman: assoc does not add things to a map

15:26 it creates a new map with those things and the things from the old map

15:26 ataggart: but isn't that what happens inside the atom anyway?

15:26 hiredman: ,(let [a {:a 1}] (assoc a :b 2) a)

15:26 clojurebot: {:a 1}

15:26 duncanm: Chouser: aha

15:26 hiredman: ataggart: in the atom, the old map is replaced with the new map

15:26 duncanm: right

15:26 clojurebot: map is *LAZY*

15:26 duncanm: concat is nice

15:27 Chouser: duncanm: concat is also lazy

15:27 hiredman: ,(let [a (atom {:a 1})] (swap! a assoc :b 2) a)

15:27 clojurebot: #<Atom@1e9b67e: {:b 2, :a 1}>

15:27 hiredman: ,(let [a (atom {:a 1})] (swap! a assoc :b 2) @a)

15:27 clojurebot: {:b 2, :a 1}

15:29 ataggart: with regard to (let [a {:a 1}] (assoc a :b 2) a)

15:30 if a is a varable accessed by the closure, then it does refect the changes

15:30 Chouser: locals are also immutable

15:30 ataggart: at least that's what it loks like when I run the un-atomed version of memoize

15:31 hm ok

15:31 hiredman: ataggart: it cannot reflect the change

15:32 if it apears to then you are doing something different

15:32 ataggart: ah wait, ok, because assoc is returngin a new map, not changing the passed in map

15:32 Chouser: if you have code that you think shows a local or a clojure collection changing, feel free to paste it so we can help

15:32 yes

15:32 hiredman: ~paste

15:32 clojurebot: lisppaste8, url

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

15:34 ataggart: aha, I was basing this off of lack of difference between the execution time of the memoized fib, and my version. But I wasn't actually running the right code.

15:34 I see it now

15:34 not using the atom takes just as long as not "memoizing" at all

15:34 excellent

15:54 lisppaste8: marklar pasted "Executing jar error" at http://paste.lisp.org/display/80618

15:54 Qvintvs: I can't seem to get clojure working with jline. Running the command that the getting started page provides gives me a class not found error for clojure.lang.Repl (running clojure without jline as per the command provided on the getting started page works fine). Anyone have any suggestions?

15:54 marklar: I'm trying to package an app in a jar, but when I run it I am getting this error. Has anyone run across this? Or know of a resource that explains how to distribute clojure app?

16:00 arbscht: Qvintvs: is your jline jar in the classpath?

16:01 liebke: Qvintvs: are you invoking the REPL with something like this: java -cp $LIBDIR/clojure.jar:$LIBDIR/jline-0.9.94.jar jline.ConsoleRunner clojure.lang.Repl

16:02 Qvintvs: liebke: yes

16:03 oh, well the two jars were in two different dirs. does the jline jar need to be in the clojure jar's directory?

16:03 liebke: they shouldn't have to be

16:03 if they are both on your classpath, I have no idea what the problem is :(

16:43 Chouser: shuting down self-sending agents is hard

16:44 you can send-off before shutdown-agents, and then still get an exception.

16:46 you can send-off a non-self-sending action to stop the looping, await on that, then call shutdown-agents, and (if one other action got queued behind you) still get an exception

16:47 technomancy: function composition makes me happy.

16:47 (defmulti create-foo (comp class :content))

16:47 ataggart: ,(doc comp)

16:47 clojurebot: "([& fs]); Takes a set of functions and returns a fn that is the composition of those fns. The returned fn takes a variable number of args, applies the rightmost of fns to the args, the next fn (right-to-left) to the result, etc."

16:48 Chouser: I'm staring to wonder if self-sending agents are really that great an idea after all.

16:48 starting

16:49 mrsolo: what is self sending agent?

16:50 ataggart: an agent whose action function does a (send *agent* ...)

16:50 I think

16:52 Chouser: yeah

16:52 as demonstrated in the venerable "ants" code

16:59 technomancy: ataggart: (comp class :content) is a less-punctuated version of #(class (:content %1))

17:02 replaca: I noticed this morning that clojure.xml/parse and clojure.contrib.prxml/prxml work on completely different clojure data structures. This seems wrong.

17:06 Chouser: there's no way to empty out an agent's queue, is ther?

17:08 durka42: what does releasePendingSends do?

17:09 Chouser: it allows sends that aren't queued yet (because you're in an agent action or transaction) to go ahead and get queued.

17:09 triddell: any compojure users here? if I post JSON to compojure, how can I get a string of the entire request? normally a post has named parameters, etc... but I want the entire JSON string

17:12 durka42: what happened to c.c.repl-utils/source?

17:12 Chouser: you tell me

17:12 durka42: or, i should say, why do all my vars have metadata :line 0

17:12 ,(meta (var +))

17:12 clojurebot: {:ns #<Namespace clojure.core>, :name +, :file "clojure/core.clj", :line 569, :arglists ([] [x] [x y] [x y & more]), :inline-arities #{2}, :inline #<core$fn__3327 clojure.core$fn__3327@199182a>, :doc "Returns the sum of nums. (+) returns 0."}

17:13 durka42: clojurebot's are intact

17:13 Chouser: you're on svn-something?

17:13 durka42: yeah

17:13 the latest, 1371 of core and 839 of contrib

17:14 Chouser: hm, I'm indescriminately switching off between 1.0 and 1364 or so.

17:17 yep, looks like a regression. :line 0 here too

17:19 durka42: but it worked in 1364?

17:19 Chouser: works with 1368

17:22 1370 appears to have broken it

17:27 rhickey: you want an Issue for that, a note on the group, or... ?

17:38 durka42: Chouser: commenting out Compiler.java:4964 (form = macroexpand(form)) fixes it, but i'm not sure what else that screws up

17:42 Chouser: I think that would partially or perhaps completely remove the purpose of that commit.

17:42 durka42: yes

17:49 Chouser: but perhaps it could throw away the old value of form only in the 'then' case, not the 'else'?

18:12 mozinator: hi guys, today I hacked a little with Clojure and JMusic to create a JMusic instrument, see it at: http://www.reddit.com/r/Clojure/comments/8mahz/using_jmusic_with_clojure_part2/

18:20 technomancy: mozinator: looks cool. two suggestions: state your dependencies clearly, and use syntax-highlighting.

18:21 where does JMusic come from?

18:21 mozinator: technomancy, haven't found a Clojure syntax highlighting system for wordpress

18:21 technomancy: mozinator: you could probably export HTML from your editor

18:22 that's what I do anyway

18:22 mozinator: Queensland University of Technology

18:22 technomancy: mozinator: what I mean is that if people want to follow along, they'll want links to where they can download the jars they need to run your code

18:22 mozinator: technomancy, good idea, going to have a look how to do it with emacs

18:22 technomancy: mozinator: search for htmlize.el on the emacswiki

18:22 it's very nice

18:23 mozinator: technomancy, good advice :)

18:24 my ultimate goal is to make something like ipromptu http://www.google.nl/url?sa=t&source=web&ct=res&cd=1&url=http%3A%2F%2Fimpromptu.moso.com.au%2F&ei=yNMVSpfROJPLjAf2xb3fDA&usg=AFQjCNEGANbWR_xbxHqEroHdX9rhGMxPiA&sig2=milUfOs55hMGZ9AIp4Lc1g

18:24 oops

18:24 http://impromptu.moso.com.au/

18:25 technomancy: that looks cool

18:25 too bad it's platform-specific

18:25 mozinator: technomancy, hence, the use of JMusic :)

18:26 technomancy: good deal

18:27 mrsolo: beside compile, what are some ways to reduce clojure startup time?

18:28 technomancy: mrsolo: if you're on a 32-bit machine, make sure you're running the "client" jvm

18:28 mrsolo: ok

18:28 will switching jvm help?

18:28 i am using run of the mill sun one

18:29 technomancy: mrsolo: the sun one has two modes, client and server

18:29 server performs better over time, but starts slowly and IIRC uses more memory

18:30 not totally sure how to check which one you're running though

18:30 mrsolo: oh ya.. just tried it out.. 2x as fast in client mode on startup time

18:31 technomancy: yups

18:31 mrsolo: still.. substaintally slower compares to perl/ruby/python..sure hurting its ability to do scripting :-<

18:32 hiredman: (System/getProperty "java.vm.name")

18:32 technomancy: clojurebot: what is nailgun?

18:32 clojurebot: I don't understand.

18:32 hiredman: ~google nailgun

18:32 clojurebot: First, out of 829000 results is:

18:32 nailgun*

18:32 http://www.nailgun.tv/

18:32 hiredman: :(

18:32 ~google nailgun java

18:32 clojurebot: First, out of 7390 results is:

18:32 Nailgun: Insanely Fast Java

18:32 http://martiansoftware.com/nailgun/index.html

18:33 mrsolo: nice

18:35 mozinator: technomancy, htmlize works beautifully, thanks for the tip

18:35 technomancy, I also put some background info to the post

18:36 technomancy: very nice

18:43 hlship: I got my evaluation thing working

18:43 http://paste.lisp.org/display/80624

18:43 I wonder if it could be simpler

18:43 The trick was to defer the evaluation of the forms until in the correct namespace

18:43 so I needed an extra (eval) to pull it off

18:44 hiredman: ugh

18:46 what are you using this for?

18:46 defining functions in another namespace?

18:51 hlship: yes, defining functions in another namespace

18:52 I working on a templating system

18:52 templates are XML

18:52 inside the XML are Clojure expressions

18:52 the template is turned into a function

18:52 the Clojure expressions are also functions

18:52 hiredman: http://paste.lisp.org/display/80624#1

18:53 hlship: I.e. <span color="${(env :span-color)}">alert</span>

18:53 hiredman: like I told you yesterday, use intern

18:54 hlship: thanks for the example, I can see if that fits my needs

18:55 hiredman: and don't use in-ns

18:55 it is fine for switching namespaces in the repl

18:55 technomancy: I hate to say it, but that looks like it's coming dangerously close to blurring the view/logic barrier.

18:55 hiredman: but really you should do something like (binding [*ns* (create-ns 'some-name-space)] stuff here)

19:00 hlship: The docs are really specific on not using anything but (in-ns) or (ns) to change *ns*, but I can try the binding option if that helps.

19:01 The concept is based on Tapestry; it's a hierarchical pull MVC model.

19:01 hiredman: which docs? where?

19:01 ah

19:01 clojure.org/namespaces

19:02 hlship: The current namespace, *ns* can and should be set only with a call to in-ns or the ns macro, both of which create the namespace if it doesn't exist.

19:03 anyway, any Clojure expressions embedded in a template should be evaluated in the same namespace as the template, with access to namespace private vars (such as functions)

19:03 hiredman: in that case, binding is the way to go

19:06 mrsolo: ok nailgun works..sorta...

19:09 clojure.lang.Script bars on Stream closed exception ... Repl exits too fast before output is finished..heh

19:09 hiredman: mrsolo: use clojure.main

19:10 Script and Repl are depricated

19:17 mrsolo: allright..very nice :-)

19:17 thx

20:14 emacs c-c c-k seems to be broken ...

21:09 emacsen: Okay, I'm banging my head against Java. I have a jar on my classpath but I can't import the classes. I don't quite know how to start figuring out what's wrong. Anyone have a guide like "Java for Clojure people"?

21:09 clojurebot: classpath is (System/getProperty "java.class.path")

21:32 chessguy: ok, so i've got a clojure architectural question. i want to implement a protocol called winboard, which is basically a text protocol for communicating with engines. so the idea would be that the client of my library could simply define an engine that knows how to play, and my code would provide the UI wrapper for it

21:34 but i'm really not sure how, overall, to architect such a thing in clojure

21:34 emacsen: communicating with engines?

21:35 chessguy: i'm wondering if i want to provide a defmulti in my library, and let the client define new independent functions for it

21:35 emacsen: chessguy, your question seems really vague

21:36 chessguy: emacsen, yeah as in, how specifically do you say "here's a position, what move do you want to make?"

21:36 emacsen: Okay, do you realize you never even said this was for a game of chess?

21:37 chessguy: oh boy

21:37 sorry

21:37 haha

21:37 yes, that must have sounded veryy strange

21:38 i was trying to figure out how to summarize a lot at once into a succinct question, and i didn't do a very good job

21:39 emacsen: I'm personally hoping someone can answer my question about, basically seeing what I can import... I guess if there's a way to ask for the tree of defined namespaces (?)

21:41 as for your UI wrapping code, I'm going to assume that your code simply communicates over this protocol...

21:41 so somewhere in the protocol you specify which "engine" you want to use?

21:41 why do you need a defmulti? Why can't you just specify the engine over the wire?

21:42 chessguy: well, there's a program called winboard too, for example. the program takes, as a parameter, the name of a chess engine executable. it starts that engine, and then communicates with it, via the winboard protocol, on stdin and stdout

21:43 i want to write the code that communicates with the program once, and potentially have a number of different actual engines

21:44 emacsen: well without seeing it in more detail I can't say anything, but it sounds like defmulti isn't really necessary here

21:45 chessguy: ok

21:45 emacsen: maybe I'm wrong. Maybe you do want to dispatch, but I don't think so

21:45 because it sounds (to me) like you're just talking over the wire

21:45 but I don't know your problem set

21:45 chessguy: over stdin and stdout, yes

21:46 emacsen: isn't winboard the thing that the GPL fight was over? :)

21:46 chessguy: hm, i haven't heard that one

21:46 basically, i want to be able to write a chess engine by just saying (def engine ....); (def main (runwinboard engine))

21:47 emacsen: IChessU

21:47 that was the one

21:47 chessguy, okay, so here's a naieve answer... why not just try it?

21:48 chessguy: try what? i'm telling you, i don't know how to go about an overall architecture

21:48 emacsen: well that's how we learn :)

21:48 by doing

21:48 and it doesn't have to be right the first time

21:48 chessguy: i'm not worried about getting it wrong. i literally don't know what to do

21:49 emacsen: start from the bottom

21:49 and work your way up

21:49 chessguy: the only thing i can think of would be to have engine be a function that, when run, produces a map from symbols to functions

21:50 emacsen: you're all over the place

21:50 chessguy: i'm new to lisps

21:50 emacsen: well, what languages do you know?

21:50 chessguy: i have functional programming experience in haskell, but i'm a little weirded out by the complete lack of type system in lisp

21:51 p_l: chessguy: what lisp? cause there are ones which use static typing and ones that don't :)

21:51 emacsen: You just seem to be obsessed with the overall design and not thinking about the individual parts

21:51 p_l: *which

21:51 chessguy: p_l, uh...clojure?

21:52 emacsen: Can you write something to talk to winboard over the wire manually?

21:52 or via stdin/stdout or whatever

21:52 p_l: clojure afaik conforms to Java's static typing, didn't it?

21:52 chessguy: emacsen, what do you mean?

21:52 emacsen: I'm saying... do the low level stuff first

21:52 Do the grunt work

21:53 chessguy: i guess i'm too SICP-struck

21:53 with their top-down approach

21:53 ataggart: emacsen: you still having a problem importing?

21:53 emacsen: and then once you can do that, think about the way your lower level pieces will fit together. I think you're suffering from too much top-down thinking

21:53 ataggart, I don't know where my problem lies. I don't understand this Java stuff :)

21:53 ataggart: what are you trying to do?

21:54 hiredman: emacsen: are you sure it's in your classpath?

21:54 emacsen: ataggart, There's a java library I want to use. I have the jar in my classpath

21:54 hiredman: are you sure?

21:54 p_l: chessguy: funny how most of what I have seen in lisp world is bottom-up :D With top-down usually having the form of "I type (myapp) in repl, then I fix the bugs it caused" :)

21:54 emacsen: it prints out the jarfile when I ask clj for my classpath

21:54 hiredman: good

21:54 gnuvince_: Has anyone been having problems with Slime lately?

21:54 chessguy: p_l, the art of wishful thinking :)

21:54 hiredman: how are you trying to import it?

21:55 emacsen: gnuvince, it's completely broken for me. I've gone back to inferior-lisp

21:55 (:import javax.mail)

21:55 ataggart: ok, then (ns my-ns (:import [some.package] [some.other.package ItsClass]))

21:56 emacsen: I have to declare a namespace to import the library?

21:56 hiredman: emacsen: is javax.mail a class?

21:56 emacsen: no

21:56 emacsen: hiredman, no... But I want to see the classes inside it. I don't know how to ask it for that

21:56 hiredman: (import '(javax.mail someclass))

21:56 p_l: chessguy: it works quite well, I heard :D

21:56 hiredman: emacsen: there is not import * in clojure

21:56 p_l: chessguy: at least in CL

21:57 emacsen: hiredman, okay but can I ask java.mailx for its classes?

21:57 ataggart: not really

21:57 hiredman: I believe you cannot

21:57 ~jdoc java.lang.Class

21:57 ataggart: thats what javadoc is for

21:58 hiredman: actually

21:58 emacsen: oh

21:58 I have no experience with Java. This has proven a hinderance with learning clj

21:58 hiredman: well, just learn to read javadocs

22:00 emacsen: hiredman, yeah... I was trying to go off examples: http://javamaildir.sourceforge.net/examples/ but these seem to pollute the namespace in ways I can't tell where the classes are being called from

22:00 eg "Where the heck is Session? In javax.mail or javax.mail.internet?", etc.

22:01 hiredman: emacsen: javadocs will tell you

22:01 most javadocs java an index of classes

22:01 emacsen: okay, I'll have to learn that

22:03 ataggart: http://java.sun.com/products/javamail/javadocs/index.html

22:03 emacsen: yeah I'm reading them. It's just not clear to me as I read it how the parts fit together

22:04 ataggart: usually that's listed in the package docs

22:04 e.g., http://java.sun.com/products/javamail/javadocs/javax/mail/package-summary.html

22:04 scroll down

22:05 emacsen: user=> (import '(javax.mail Properties))

22:05 java.lang.ClassNotFoundException: javax.mail.Properties (NO_SOURCE_FILE:0

22:05 so, I can't tell... is that me failing to call it right or not in classpath?

22:05 ataggart: ClassNotFound

22:05 it;s not in the classpath

22:07 emacsen: ataggart, do you mind if I msg you directly my classpath?

22:07 ataggart: go for it

22:28 mrsolo: thank got for M-x clojure-install... geez

23:52 durka42: Chouser: i think i fixed the problem with 1370 without removing the point of the commit

23:52 clojure.lang.Compiler/macroexpand throws away the metadata somehow

23:53 lisppaste8: durka42 pasted "clojure/lang/Compiler.java" at http://paste.lisp.org/display/80629

23:55 durka42: note that clojure.core/macroexpand does not throw away metadata

Logging service provided by n01se.net