#clojure log - Nov 21 2009

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

0:30 scottj: Can Java call Clojure code? What's the class and method names of Clojure code?

0:32 hamza: yes, http://en.wikibooks.org/wiki/Clojure_Programming/Tutorials_and_Tips#Invoking_Clojure_from_Java

0:32 scottj: hamza: thanks

0:33 hamza: i've even seen people call clojure from ruby.

0:33 JRuby that is

1:01 technomancy: http://github.com/technomancy/clojure-gem

1:22 arohner: technomancy: looks good, except that you have sane, clojure names

1:23 the ruby community won't appreciate it unless you come up with your own terms like filter => select

1:23 :-p

1:26 _ato: hehe yeah... I spend so much time looking through the rdoc for Array trying to remember what they called filter and reduce

1:27 technomancy: arohner: I kind of abandoned the project once it was clear that it wasn't going to net me a speaking gig at RubyConf. =)

1:28 arohner: technomancy: NIH?

1:29 technomancy: arohner: nah, it was just that stuarthalloway also proposed a Clojure talk, and he's a better speaker than I am. =)

1:30 despite allegations of him being a scotch-soaked jerk, which I can refute.

1:30 scottj: load up Smalltalk, give the method finder the arguments and result that you would get from the method you're looking for, look the resulting method name up in ruby.

1:34 arohner: scottj: which would be fine, except that Matz always talks about stealing some from perl, some from smalltalk, some from lisp

1:34 it seems like the only thing he stole from lisp is "map"

1:35 anyways, I'm going to sleep

1:35 chr: (clojure.core/add-classpath "/Users/chr/src/clojure/src/compojure/compojure.jar")

1:36 followed by (ns hello-world (:use compojure))

1:36 does not quite work:

1:36 JayM: arohner: cons

1:36 and others

1:36 chr: I get "java.lang.ExceptionInInitializerError (NO_SOURCE_FILE:0)"

1:37 How do I tell a running clojure about a jar for a library?

1:37 _ato: ~add-classpath

1:37 clojurebot: add-classpath is bad, avoid it. I mean it!

1:38 nanodust: why?

1:38 _ato: unfortunately you can't reliably, set the classpath before you start it and your life will be much simpler

1:38 because the top-level java classloader can't be changed

1:38 clojure makse it's own URL classloader, which can be

1:38 chr: _ato: OK, I'll try that, then.

1:38 _ato: which is what add-classpath does

1:39 * chr restarts *slime-repl clojure*

1:39 _ato: but stuff that's at the top-level can't see stuff that's not properly somehow and everything gets mighty confused

1:41 nanodust: oh, i'll go read jvm specs for whole picture

1:44 hamza: can anyone tell me why this is failing?

1:44 ,(apply hash-map [["test" 0.9912407071619299]])

1:44 clojurebot: java.lang.IllegalArgumentException: No value supplied for key: ["test" 0.9912407071619299]

1:44 hamza: i have a bunch of these pairs in a vector

1:45 _ato: nanodust: if you can figure out how to fix it you'll make a *lot* of people happy ;-)

1:51 chr: by the way, do you know about M-x swank-clojure-project ?

1:52 it'll set the classpath for you and start swank if you tell it your project directory

1:56 chr: _ato: I looked for it earlier, seemed like a good idea

2:11 bradbeveridge: Does lein work 'out of the box' for OS X 10.5?

2:11 It appears to assume some things about my setup & the mkdir implies it should be run from a consistent place

2:12 technomancy: bradbeveridge: I don't know if anyone's tried it, but I can't think of a reason why it would fail.

2:13 you can place it anywhere on your $PATH

2:13 mrSpec: hello

2:13 bradbeveridge: right, but the mkdir -p classes at the top of the script will make a directory in the place that the script is run from, right?

2:14 technomancy: oh, it should be run from within the project you're working on, yes.

2:14 bradbeveridge: lein also appears to assume that I have Java setup correctly (which I probably don't)

2:14 do I need Maven setup first?

2:14 technomancy: bradbeveridge: most of lein works without maven

2:15 you only need it to install the project you're working on in your local mvn repo

2:15 bradbeveridge: OK, let me try again now that I know about it being project centric

2:16 I'm certainly downloading more stuff...

2:16 cgordon: I'm still trying to understand vars. What happens if two threads execute something like "(def some_var "some_val")" at the same time? I presume they both change the root binding. Is there a race condition?

2:16 technomancy: cgordon: yes, but def should never get called at runtime.

2:16 cgordon: ah, alright

2:17 so it's mostly for newbies like me playing in the repl? :)

2:17 bradbeveridge: technomancy: OK, that appears to be working - no idea what the problem was last night for me

2:17 technomancy: well, during development you call it all the time

2:17 bradbeveridge: awesome

2:17 bradbeveridge: thanks for the good work, easy install of packages is awesome

2:18 cgordon: technomancy: and general best practice is to only use (binding ...) with variables that start and end with asterix? (like *command-line-args*)

2:18 _mst: yeah, seconded. I'm having a nice time getting all of my old code to build with lein :)

2:19 cgordon: can anyone explain this comment, from "http://clojure.org/vars": Bindings created with binding cannot be seen by any other thread. Bindings created with binding can be assigned to, which provides a means for a nested context to communicate with code before it on the call stack.

2:20 bradbeveridge: is there any way to list the packages on clojars?

2:21 _ato: type "0" into the search box

2:21 a browse feature is coming, technomancy's prettying up my code and adding it as we speak :)

2:21 bradbeveridge: sweet!

2:22 * technomancy has to learn compojure first. =)

2:22 bradbeveridge: and (I'm stupid) how does one grab stuff from clojar?

2:22 _mst: _ato: heh, I'd already tried '%', '*' and various others ;)

2:22 technomancy: cgordon: yes, *earmuffs* are visual indicators that you intend to rebind a var with binding

2:22 hiredman: cgordon: which part don't you understand?

2:22 _ato: bradbeveridge: just add it the :dependencies list in your project.clj and run: lein deps

2:23 cgordon: hiredman: I understand that "binding" changes the value of a var for everything *down* the stack. I don't understand how it can change the value for things above it on the stack

2:23 unless I just have my up and down confused

2:23 hiredman: cgordon: the binding form doesn't

2:23 but once you have bound a var using binding, you can use set! to change its value

2:24 cgordon: ah, and that changes it for things above it on the stack?

2:24 _ato: I probably should change the leiningen heading on the jars page to "add to leiningen project.clj" or something

2:24 hiredman: not above the binding form

2:24 bradbeveridge: _ato: Oh, I get it now :) Clojar is more about linking libs together, not 'getting stuff' to look at code or whatever

2:24 cgordon: so why does that comment say: which provides a means for a nested context to communicate with code before it on the call stack

2:25 hiredman: cgordon: it provides a means to do that with in the scope of the binding form

2:25 cgordon: ah, alright, so it's not talking about code above the binding form

2:25 got it, thanks

2:25 technomancy: bradbeveridge: clojars is about finding what :dependencies forms to put in your project.clj

2:25 and having a place to serve the jars from over HTTP

2:26 (but the latter is handled for you)

2:26 _ato: bradbeveridge: We're shortly going to add links to the source code, project home pages etc from the jar pages so it should be a bit easier to find the source

2:27 bradbeveridge: For some reason I was thinking that lein/clojars was about "I wrote this cool app, here's how you get it". Now that I get it, my questions are pretty daft

2:27 thanks for the help

2:28 _ato: bradbeveridge: I'm thinking about covering that at some point as well, but for now it's more about libraries and building

2:35 bradbeveridge: one more stupid question I think - now that I have my testing project setup, what's the best way to connect with Slime? Normally I launch from Emacs, but I expect I probably want to launch from the lein repl? (lein slime?)

2:40 technomancy: bradbeveridge: add [swank-clojure "1.0"] as a :dev-dependency in project.clj

2:40 then run lein deps and you should be able to M-x swank-clojure-project

2:41 bradbeveridge: ok, I've done that now - where do I find swank-clojure-project? Latest swank?

2:43 technomancy: bradbeveridge: yeah, you can pull it in through the Emacs package manager

2:43 http://github.com/technomancy/swank-clojure/blob/maven/README.md

2:43 bradbeveridge: OK, I'll go try that - thanks a bunch

2:43 technomancy: np

2:54 bradbeveridge: awesome - technomancy & _ato you guys rock! I love seeing how nicely the Clojure community is growing

2:54 thanks for the work

2:58 chr: Clojure can't seem to find compojure.jar.

2:58 My java process was started like this: /usr/bin/java -classpath /Users/chr/src/clojure/clojure.jar:/Users/chr/src/clojure/src/compojure/compojure.jar clojure.main --repl

3:00 still

3:00 ERC> still (ns hello-world (:use compojure)) gets a NoClassDefFoundError

3:02 _mst: I think compojure has more dependencies than just the compojure.jar file

3:03 the 'deps' and task in the compojure distribution pulled a bunch of .jar files into deps/, if I recall correctly

3:04 chr: http://en.wikibooks.org/wiki/Compojure/Getting_Started says: "This will generate the compojure.jar file. Put this in your Java classpath."

3:05 _mst: Shouldn't the compojure.jar contain the dependencies?

3:06 _mst: I don't think it does--see the "hello world with embedded jetty" example in the next session

3:06 it adds all the .jar files in the deps directory to the classpath

3:06 if you're on java 1.6 you can run java with -classpath 'deps/*' and it will automatically add all those .jar files to your classpath

3:07 chr: _mst: You're right -- it's a little confusing.

3:07 _mst: I seem to be on java 1.6.0_15...

3:08 _mst: yep, that should be fine

3:08 so from your compojure directory: java -classpath '*:deps/*' clojure.main --repl

3:09 should do the trick

3:09 fanatico: http://gist.github.com/240050 <- Anyone want to take a quick look over this code. I can't seem to figure out where I made the mistake in `par-word`.

3:09 chr: mst: I'll try to hook that into slime/swank.

3:12 _mst: fanatico: your call to bind returns a function that expects one argument

3:12 which you bind to 'ne-world', and then call with no arguments when you do (ne-world)

3:14 fanatico: _mst: thanks.

3:14 _mst: no problem

3:19 chr: which swank-clojure on github?

3:25 duncanm: la la la

3:26 _mst: chr: although I'm not currently using it, I'd have a look at technomancy's one

3:30 chr: technomancy: http://github.com/technomancy/swank-clojure/tree/maven says: git clone git://github.com/technomancy/clojure-mode.el

3:30 technomancy: did you mean git clone git://github.com/technomancy/clojure-mode ?

4:16 kzar: Supposing I have a struct variable that I created with def and I want to inc one of it's attributes how can I do that? The only way I can see so far is to call def again passing all of the attributes

4:17 hiredman: no

4:17 never call def again

4:18 kzar: hiredman: Is there a way to do it? I know it's not good practice normally, I don't use it for most stuff

4:19 hiredman: never do it

4:19 kzar: hiredman: Ok thanks for your help

4:19 hiredman: :)

4:19 how you don't do it depends on context

4:19 ,(update-in {:a 1} [:a] inc)

4:19 clojurebot: {:a 2}

4:20 hiredman: ,(let [a (ref {:a 1})] (dosync (alter a update-in [:a] inc)) a)

4:20 clojurebot: #<Ref@16a9a4c: {:a 2}>

4:21 hiredman: ,(let [a (atom {:a 1})] (swap a update-in [:a] inc) a)

4:21 clojurebot: java.lang.Exception: Unable to resolve symbol: swap in this context

4:21 hiredman: ,(let [a (atom {:a 1})] (swap! a update-in [:a] inc) a)

4:21 clojurebot: #<Atom@1a648f9: {:a 2}>

4:21 hiredman: ,(let [a (agent {:a 1})] (send-off a update-in [:a] inc) (await a) a)

4:21 clojurebot: #<Agent@f4aaca: {:a 2}>

4:22 hiredman: thinking about redefing stuff is a symptom of an imperative mindset

4:24 kzar: hiredman: Yea I know, I'm just making a crappy game as practice / to learn clojure and at the moment the position for something is set with def

4:24 hiredman: :|

4:25 kzar: hiredman: It's not the best solution, probably not how I'm going to keep it and of no real concequence anyway because there will only be one of the item

4:25 hiredman: that doesn't sound right

4:25 kzar: if you are going to learn, it is best to learn correctly

4:25 kzar: hiredman: Yea I know but I just wanted to see if it would move on the screen when I updated the coords

4:25 hiredman: Well you learn by doing and with that you must concede some of what you do is wrong

4:26 hiredman: eh?

7:57 gerry`: jsr166y will be included in jdk7

7:59 will par branch be merged in new?

8:00 _ato: JDK 7 isn't coming until at least the end of next year apparently

8:01 gerry`: when the next clojure release?

8:02 oh, closures coming to jdk7

8:04 any benefits to clojure?

8:07 _ato: I trhink the main benefit to clojure would be that first class functions will be standardised so the different JVM languages will play better together. as far as I can tell they don't add any extra functionality over Clojure's closures, but I'm no JVM expert

8:14 gerry`: i don't know whether closures have to involve bytecode changes

8:20 #(int i,String s) (i+s.length()) just like clojure #(fn [] ())

8:21 ,#(fn [#^String x] (.length x))

8:21 clojurebot: #<sandbox$eval__4933$fn__4935 sandbox$eval__4933$fn__4935@ec4789>

8:33 _ato: yeah maybe it means clojure can skip the class generation part, it'd be nice to have less of those gensymed class files spewed out

8:37 gerry`: should ask rhickey

8:40 ,#int(int,String)

8:40 clojurebot: No dispatch macro for: i

8:41 gerry`: (int,String)=>int

9:06 ,((eval (symbol "compare")) 3 4)

9:06 clojurebot: DENIED

9:07 gerry`: ,(doc eval)

9:07 clojurebot: DENIED

9:10 the-kenny: ,(map inc [1 2 3])

9:10 clojurebot: (2 3 4)

9:22 gerry`: ,(doc var)

9:22 clojurebot: Titim gan éirí ort.

9:23 gerry`: ,(doc apply)

9:23 clojurebot: "([f args* argseq]); Applies fn f to the argument list formed by prepending args to argseq."

9:26 gerry`: ,(.seq [1 2 3])

9:26 clojurebot: (1 2 3)

9:27 gerry`: ,(seq? [1 2 3])

9:27 clojurebot: false

9:27 gerry`: ,(.seq {:a 1 :b 2})

9:27 clojurebot: ([:a 1] [:b 2])

10:05 djork: what was the syntax to make a variable for inside a macro?

10:06 sorry, total brain fart

10:07 the-kenny: djork: You mean a gensym'd symbol?

10:07 djork: ah yes

10:07 gensym was it

10:08 the-kenny: I think something like foo# was an auto-gensym

10:08 djork: ,~(name foo#)

10:08 clojurebot: java.lang.Exception: Unable to resolve symbol: foo# in this context

10:08 djork: oops

10:08 oops

10:08 ,`(name foo#)

10:08 clojurebot: (clojure.core/name foo__4980__auto__)

10:08 djork: there we go

10:08 only in syntax-quote

10:19 is there a definitive explanation of unquote-splicing?

10:19 the-kenny: djork: It isn't very complicated. What do you want to know?

10:21 ,(macroexpand-1 '(let [seq (range 10)] `(do ~@seq)))

10:21 clojurebot: (let* [seq (range 10)] (clojure.core/seq (clojure.core/concat (clojure.core/list (quote do)) seq)))

10:21 the-kenny: hm no, something's wrong.

10:21 djork: let's see

10:22 the-kenny: ,(let [seq (range 10)] `(do ~@seq))

10:22 clojurebot: (do 0 1 2 3 4 5 6 7 8 9)

10:22 djork: I think it only applies to & arguments to a macro

10:22 the-kenny: ah

10:22 djork: ah ha

10:22 there we go

10:22 so it expands the seq

10:22 the-kenny: Yes

10:22 djork: I'm trying to make a hash-map out of the tail-end of a macro's args

10:22 the-kenny: Useful for [& body] in arguments

10:22 djork: so

10:22 yeah

10:23 ,(let [hash-args [:foo :bar :bat :baz]] `(hash-map ~@hash-args))

10:23 clojurebot: (clojure.core/hash-map :foo :bar :bat :baz)

10:25 ohpauleez: it's essentially the same as python's *args.

10:25 if that helps you any

10:25 the-kenny: It's also like common lisps ,@args :p

10:26 ohpauleez: yes, perhaps a better example

10:26 haha

10:35 djork: hmm

10:35 every time I load this file I get a higher line number with this error

10:58 the-kenny: Is there a nice description of lexical and dynamic scope?

11:06 michaeljaaka: hi!

11:06 anyone used clojure.contrib.accumulators?

11:06 what is it?

11:07 how to use it?

11:07 I found using immutable types quite hard

11:07 for example I have map

11:07 { "one" [ 12 3 4] "two" [ 5 6 7 ] }

11:07 any time I want to update [ 1 2 3 4]

11:08 I have to extract it by (get map "one" []) then conj to it, and finally assoc

11:08 all made in a transaction with alter for ref

11:08 is there any simpler way?

11:23 djork: michaeljaaka: you could simplify your life by using keywords as hash-map keys

11:24 michaeljaaka: how?

11:24 djork: ,(let [x {:foo [1 2 3]}] (println (:foo x)))

11:24 clojurebot: [1 2 3]

11:24 michaeljaaka: but when I want to add a value to collection of [ 1 2 3] ?

11:25 the-kenny: I think there is assoc-in or something like this

11:25 djork: not quite

11:26 assoc-in just does assoc in a nested map

11:26 ,(doc assoc-in)

11:26 clojurebot: "([m [k & ks] v]); Associates a value in a nested associative structure, where ks is a sequence of keys and v is the new value and returns a new nested structure. If any levels do not exist, hash-maps will be created."

11:42 Chousuke: assoc-in works for any nested associative structure

11:42 so it's fine for vectors too

11:42 though I'm not sure if it can add elements... hmm

11:42 ,(assoc [1 2 3] 3 4)

11:42 clojurebot: [1 2 3 4]

11:43 Chousuke: apparently it can

11:43 there's also update-in

11:44 the-kenny: It can, if you supply the length.

11:44 Chousuke: ,(update-in {:foo {:bar [1 2 3]}} [:foo :bar] conj 'hello)

11:44 clojurebot: {:foo {:bar [1 2 3 hello]}}

11:45 the-kenny: Oh, that's a cool function.

11:46 Chousuke: it takes a seq of keys as the second argument, and works like alter etc. otherwise

11:46 and as with assoc-in, vectors are fine too. the keys are just integers

11:58 djork: what's the canonical way to tell if a value is in a vector

11:58 oh wait

11:58 the vector is a function of its elements right

11:58 no

11:58 hm

11:59 ah sets

11:59 right

11:59 mjm: djork: i think the common way is to convert it to a set, then do that

11:59 djork: I should be using a set in the first place

11:59 mjm: vector is a function of its indices

11:59 djork: of stop-words symbols

12:00 mjm: djork: oh. then there you go :)

12:00 djork: yup

12:08 Chousuke: of course, if the vector is sorted you can always do a binary search

12:15 djork: Chousuke: yah, but a set works better in this case... it's a set of stop words

12:15 '#{of in the at} etc

12:31 qed: anyone here see s. halloway this morning at rubyconf?

12:40 solussd: if i have a function that takes a variable number of args and I want to pass it a seq, how can I 'explode' the seq when i pass it in [to it appears to be a bunch of args, rather than just one]

12:41 *so it

12:43 nanodust: apply?

12:43 the-kenny: solussd: (apply fn seq)

12:43 ,(apply + (range 100))

12:43 clojurebot: 4950

12:44 * defn waves

12:44 solussd: yep.. that's what I wanted. I always forget about apply

12:44 defn: i still don't understand what difference exists between apply and reduce

12:45 the-kenny: defn: (apply + [1 2 3]) is like (+ 1 2 3). (reduce + 1 2 3) is (+ 1 (+ 2 3)) or something like this

12:45 defn: ah

12:45 reduce is faster

12:45 based on what i was reading from cgrand

12:46 the-kenny: But it isn't the same as apply. In this example yes, but in others don't

12:46 defn: nod

12:47 the-kenny: Sorry.. bad english

12:48 defn: np :)

12:48 (:)

12:49 michaeljaaka: Chousuke: thanks for poiting update-in it was very helpful

12:50 ,(doc do)

12:50 clojurebot: It's greek to me.

12:50 michaeljaaka: can someone explain what "do" does?

12:50 the-kenny: do is a special op

12:50 michaeljaaka: it is not documented

12:50 the-kenny: michaeljaaka: It runs every function in it and returns the value of the latest

12:50 michaeljaaka: http://clojure.org/special_forms

12:51 Oh sorry, wrong link

12:51 solussd: how can i convert a seq of integers to a java array of doubles? right now i'm using (to-array [1 2 3]), but i dont want to have to iterate through them casting them individually as doubles

12:51 michaeljaaka: ok, I have found the description there

12:51 so I can run (do (+ 1 2) ( + 4 5) )

12:51 and so on

12:52 this is helpful for expresion where one expression is expected

12:52 the-kenny: ,(do (print 42) :foobar)

12:52 clojurebot: :foobar

12:52 42

12:52 michaeljaaka: but I want to put more than one

12:52 the-kenny: Exactly

12:52 But it only makes sense for methods with side effects (except for the last one)

12:52 michaeljaaka: ok, thanks!

12:56 btw. anyone have seen line-seq ?

12:57 I core.clj

12:57 in core.clj

12:57 I have question

12:57 is this function consuminc the stack?

12:57 because it is made with recursion

12:57 the-kenny: michaeljaaka: recursion or recur?

12:57 michaeljaaka: recursion

12:58 the last statment is

12:58 line-seq with arg

12:58 so it is recursion

12:58 so if there is a very long file

12:58 I can get stackoverflow?

12:58 the-kenny: I think so.. But I'm not very experienced there :)

13:01 qed: is (defn make-adder [x] (fn [z] (+ x z))) (def add-2 (make-adder 2)), the same as (def add-2 (partial + 2))?

13:01 opqdonut: yeh

13:01 qed: ty

13:03 solussd: nevermind- into-array is what i was looking for

13:20 chr: I did "git clone git://github.com/technomancy/clojure-mode"

13:20 Should there then be a swank-clojure.clj in ./slime ?

13:21 Chousuke: probably not.

13:21 I think the projects were separated.

13:24 chr: maacl: Pardon me, I pasted the other link.

13:24 maacl: It was "git clone git://github.com/technomancy/slime.git" that created a ./slime directory.

13:25 maacl: chr: sorry?

13:26 chr: http://github.com/technomancy/swank-clojure/tree/maven lists two links to git repos.

13:27 slime.git and clojure-mode.el. I meant slime.git, which created a slime directory.

13:31 maacl: Let me rephrase, please.

13:31 maacl: I did "git clone git://github.com/technomancy/slime.git".

13:31 spuz: solussd: also have a look at double-array: http://clojure.org/api#toc231

13:32 chr: mmaccl: That got me a directory named "slime". Inside it, I expected some mention of clojure.

13:33 spuz: michaeljaaka: line-seq is lazy, so no you can't get a stack overflow

13:33 chr: maacl: But "cd slime; grep clojure *" lists nothing.

13:33 spuz: I believe lazyness in this case will magically remove the recursion

13:37 maacl: chr: think you should send to mmaccl

13:47 solussd: im calling a java function that takes a Vector, how can I "cast" a clojure seq to a java Vector?

13:50 spuz: solussd: Vector takes a Collection as an argument

13:51 so perhaps (Vector. yourseq)

13:51 solussd: right- implements the collections interface.

13:51 thanks

13:51 candera: I'm trying to understand the semantics of ref/dosync. I've written some test code that has unexpected behavior. Basically, I've started a couple of threads, and in one I loop, starting a transaction, incrementing a simple ref to a counter, and then committing. In the other thread, I start a thread and loop, reading the ref. I was a bit surprised to find that the reading thread shows some of the updates. I would have

13:51 thought that the transaction would show me the start-of-transaction value of the ref throughout the lifetime of the tx. What am I missing?

13:52 spuz: ,(java.util.Vector. (range 10))

13:52 clojurebot: #<Vector [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]>

14:36 * chr went to http://technomancy.us/swank-clojure

14:36 * chr was told to install swank-clojure through ELPA and did so

15:19 chr: Hi, could you give me a hand in getting started with a new swank-clojure install?

15:21 M-x slime stops with the *inferior-lisp* buffer reporting "Could not locate swank/swank__init.class or swank/swank.clj on classpath".

15:21 Which files should I put in ~/.clojure?

15:22 So far, there is clojure-1.0.0.jar and compojure.jar in ~/.clojure

15:23 Earlier today I had a working install of an older slime with LW and clojure support.

15:24 I removed most of what I had in order to fit in with the "demolish the house in order to install a fridge"-ideology of the guides to installing swank-clojure.

15:26 the-kenny: chr: Check if you classpath is correct

15:26 You have to make sure that the .clj files from swank-clojure are accessible there too

15:27 chr: I don't have any swank-clojure, I'm afraid.

15:28 There are a few .el-files in /Users/chr/.emacs.d/elpa/swank-clojure-1.0, but that's all.

15:29 djork: aw what the heck did I do? "Don't know how to create ISeq from: java.lang.Character"

15:29 chr: How do I get the .clj files from swank-clojure that you are referring to?

15:29 djork: the line it's complaining about is (defmethod command :default

15:31 the-kenny: chr: add them to swank-clojure-extra-classpaths in your .emacs

15:31 (I had to play around a bit with these paths until I got everything right)

15:32 chr: where do they come from? Which git repo?

15:32 the-kenny: http://github.com/jochu/swank-clojure

15:33 robwolfe: chr: here there is full description of slime configuration for clojure: http://riddell.us/tutorial/slime_swank/slime_swank.html

15:33 the-kenny: swank-clojure is the backend for slime which connects slime to common lisp's slime

15:35 chr: I did "git clone git://github.com/jochu/swank-clojure.git"

15:35 The README babbles along about elpa, the possibly deprecated "M-x clojure-install" etc.

15:36 Invoking clojure-install in emacs tells me to visit technomancy's pages.

15:39 robwolfe: chr: have you looked at this link I provided? there is really simple step by step guide

15:40 djork: any tips on figuring out a cryptic file-loading error?

15:40 hiredman: djork: I doubt that is the whole of the line, and the whole of the exception

15:41 djork: k

15:41 hiredman: I wonder why people keep exceptions like some kind of scarce resource

15:42 "I have a problem" "we will need more than that" "here is one line from the exception" "we need more" "here is another line" …

15:42 djork: hiredman: here's my source up to the offending line and the full exception

15:42 http://paste.lisp.org/display/90864

15:42 java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Character (server.clj:28)

15:43 (past the offending line)

15:43 I'm loading this from the repl

15:45 hiredman: ,(doc defmulti)

15:45 clojurebot: "([name docstring? attr-map? dispatch-fn & options]); Creates a new multimethod with the associated dispatch function. The docstring and attribute-map are optional. Options are key-value pairs and may be one of: :default the default dispatch value, defaults to :default :hierarchy the isa? hierarchy to use for dispatching defaults to the global hierarchy"

15:47 hiredman: djork: have you looked at what the command function is being passed as an argument?

15:47 djork: it's not being called yet

15:48 hiredman: oh right

15:48 ,(doc defmethod)

15:48 clojurebot: "([multifn dispatch-val & fn-tail]); Creates and installs a new method of multimethod associated with dispatch-value. "

15:48 hiredman: ^- no docstring

15:49 djork: ah...

15:50 thanks that was simple.... for some reason I thought defmethod had a docstring

15:50 comments it is, then

15:56 spuz: rhickey: Am I right in thinking that Clojure will unroll a function call that is only made once within another function?

15:56 (not sure if Rich's around, but worth a try)

15:58 hiredman: spuz: I doubt it

15:58 chr: I have swank-clojure .clj files in ~/src/swank-clojure/src/

15:58 hiredman: clojure relies on hotspot to do most optimization

15:58 kotarak: hotspot maybe does it?

15:58 hiredman: but hotspot may or may not do it, depending on this, that, or the other

15:59 spuz: This is what I'm seeing when looking at a call stack from VisualVM

15:59 chr: Is there a compile command that makes a jar from these .clj files?

15:59 spuz: I'm not sure if it is Clojure or hotspot, it seems more likely to me that it would be Clojure but who knows..

16:00 I could have the wrong end of the stick of course, I don't know much about JVM optimisation

16:00 hiredman: chr: I would ask again when technomancy is in

16:00 ~seen technomancy

16:00 clojurebot: technomancy was last seen in #clojure, 797 minutes ago saying: np

16:01 kotarak: chr: you have to that (more or less) manually. Most peoply use ant, maven, clj-gradle or now leiningen.

16:01 hiredman: ,(float (/ 797 60 24))

16:01 clojurebot: 0.5534722

16:01 hiredman: kotarak: the jar making is a yak shaving expidition, he wants to get swank-clojure working

16:02 and he is not sure how to do it, so he is asking about everything under the sun

16:02 twbray: hiredman: technomancy is at rubyconf

16:02 chr: hiredman: to bad you're already hired ;)

16:02 hiredman: chr: and I vim

16:02 twbray: I imagine that's not perminent, so he'll be back sometime

16:02 twbray: Yeah, it ends in a couple hours

16:03 chr: hiredman: I sure have tried most wrong apporaches to getting slime to work with clojure...

16:20 I guess moving src/swank-clojure/src/main/clojure/swank to ~/.clojure/ was wrong, too.

16:21 But it worked.

16:26 technomancy: chr: do you need to compile a recent version for some reason, or do you just need a jar to use?

16:40 vy: Is there any equivalent of read-lines in c.c.duck-streams to read lines from a string? Actually, I want to read whole stream into a seq, but wondering if such a functionality already exists.

16:41 the-kenny: I think there is such a function in core. line-seq?

16:41 ,(doc line-seq)

16:41 clojurebot: "([rdr]); Returns the lines of text from rdr as a lazy sequence of strings. rdr must implement java.io.BufferedReader."

16:41 vy: the-kenny: Oh! Thanks.

16:42 hiredman: technomancy: he doesn't actually want a jar, he wants swank-clojure to work, and is stumbling down various alleys and deadends in the attempt

16:42 (maybe swank-clojure needs to be a jar, so I'd better ask how to make a jar)

16:43 technomancy: chr: do you want a standalone slime repl, or one attached to a project?

16:43 hiredman: it needs to be a jar, but nobody should have to build it by hand unless they are actually hacking swank-clojure itself

16:45 lispnik: chr, did you try loading clojure-mode.el, evaling it and then run the clojure-install function?

16:45 vy: What's wrong with (use 'clojure.contrib.duck-streams :only '(reader))?

16:45 technomancy: lispnik: that's actually deprecated now; swank-clojure.el performs that task.

16:45 * technomancy needs to get the word out

16:46 technomancy: I mean, it still works, but using elpa is easier

16:49 lispnik: that's nifty, good to know

16:51 technomancy: clojurebot: elpa is a package manager for Emacs: http://tromey.com/elpa

16:51 clojurebot: 'Sea, mhuise.

17:02 _ato: anyone know if there's an opposite to clojure.xml/parse anywhere?

17:14 DapperDan: technomancy: is there a page on your blog where one can browse your previous posts?

17:14 i'm looking for it because there are no next/prev links on the posts themselves

17:14 _ato: DapperDan: http://technomancy.us/list

17:14 theere are next/prev links it's just there not obvious

17:15 they're at the bottom of the page

17:15 above the comments

17:15 the double arrow

17:16 DapperDan: ato: sweet! how'd you find that? you must have scoured the page. and the /list link, i would have thought was to the home page rather than a list. thanks anyway..

17:19 _ato: DapperDan: heh.. I couldn't find the next/prev either but the Conkeror browser has a really neat feature where you tap [[ or ]] and it'll scour the page looking for next or prev links and follow them.

17:22 technomancy: DapperDan: just follow the <meta rel="next/prev"> links. =)

17:24 hiredman: _ato: there is a clojure.xml/emit

17:25 it prints out the xml, so you might want to use with-out-str

17:27 _ato: hiredman: ah cool, thanks! I should have checked the source instead of assuming clojure.org/api would have everything ;-)

17:27 hiredman: emit has no docstring

17:27 :/

17:33 djork: is it possible to "reset" a namespace?

17:33 like reset user in the REPL

17:34 hiredman: djork: checkout the functions on http://clojure.org/namespaces

17:35 djork: that would be smart of me

17:36 technomancy: djork: (doseq [[name var] (ns-map my-ns)] (ns-unmap namespace name))

17:37 djork: cool stuff

17:37 I'm using namespaces for this MUD style game

17:37 treating a ns as a "realm"

17:37 seems to be working pretty well

17:39 technomancy: I think that won't touch refer'd vars

17:50 djork: how can I print to a stream other than *out*

17:51 I have re-bound *out* and stored away the original as *server-out*

17:51 _ato: (.println *server-out* "hi!")

17:54 _mst: or if you're using duck streams you can (with-out-writer *server-out* (println "just like old times"))

18:12 qed: in pragprog's clojure book they start very early with defstruct person :first :last... they then use (defrecord..)

18:12 oh nvm, he's alluding to creating a macro defrecord

18:56 kzar: Is there a function like filter I can use to get the index of the results instead of / as well as the values?

19:00 chouser: you can use seq-utils indexed to get pairs of [index value], then filter on just the value part

19:07 kzar: chouser: thanks I got that working

19:25 I'm trying to pass a function to my new filter-indexed function but it keep saying 'Unable to resolve symbol: blah in this context' where blah is the function I'm passing. I tried to emulate the filter function and I can't see how my code is different

19:26 the-kenny: kzar: You should show us the code ;)

19:26 lisppaste8: url

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

19:32 kzar: whoops I forgot to paste it heh

19:33 lisppaste8: kzar pasted "filter-index" at http://paste.lisp.org/display/90876

19:50 kzar: oh I think it's because do is a special form not a function, you get the same problem using it with filter. Also my function's broken anyway.. oh well

19:50 * kzar FAIL

19:52 JAS415: well if you do identity it works

19:52 so that is good

19:53 kzar: JAS415: Oh yea, I used seq instead of do and it's fine actually :) I just remembered seq can be used like that

19:53 * kzar WIN

19:54 lisppaste8: kzar annotated #90876 "solution" at http://paste.lisp.org/display/90876#1

21:22 cgordon_: are there any good examples of using the lazy-xml libraries somewhere?

21:29 qed: is there any way to do multi-line comments

21:29 or would that require a modification to the reader

21:30 like: ;~this is a mutli-line

21:30 comment ~;

21:31 the reason i bring it up is because i think things like (partial + 10), would benefit, readability wise

21:31 if there was some sort of way of saying "there will be a variable here"

21:32 like (partial + 10 %) or something

21:32 _ato: (comment ...) works some of the time

21:32 #_"..." also works some of the time

21:33 neither of them are perfect as they evaluate to nil instead of not being read at all

21:33 oh wait

21:33 #_"..." doesn't

21:33 excellent, use that

21:34 ,[1 2 5 #_"three sir" 3]

21:34 clojurebot: [1 2 5 3]

21:51 chouser: or a comma

21:51 (partial + 10 ,)

21:52 qed: chouser: yeah i thought of the comma

21:52 i just didnt know if there was any other way to make it more obvious

21:53 hiredman: tree commas

21:53 three

21:53 qed: yeah that was my next thought after typing that line :)

21:57 i guess you could also (def ! 0) (partial + x !)

21:58 oops

21:58 (partial + !)

21:58 (partial + 2 !)

21:58 something like that

22:14 weissj: anyone here use emacs/paredit? it doesn't work right w clojure for me. (map inc |[1 2 3]) and run paredit-wrap-round gives (map inc ([1 ) 2 3])

22:15 it doesn't recognize the square braces

22:16 _ato: weissj: :/ it works for me

22:16 I get: (map inc ([1 2 3]))

22:18 I'm using paredit 21 and clojure-mode 1.6

22:23 djork_: I can feel the power :)

22:23 my friend and I are writing MUDs... he's using C# and I'm using clojure

22:24 djork: I changed the way a command worked, and tried it out on a live connection without breaking it or restarting the server

22:24 bboyah

22:24 booyah

22:24 I mean

22:25 not to sound like a douchebag or anything

22:37 qed: omg that's cool: (defmacro unless [expr form] (list 'if expr nil form))

22:37 danlarkin: qed: when-not

22:37 qed: sure sure, but that's still a cool idea

22:37 is all im saying

22:38 this is my first experience with macros

22:38 _ato: qed: ah, you've been missing out :D

22:40 qed: checkout this piece of macro evil I just wrote: http://gist.github.com/240401 (you can ignore the stuff at the top just look at the last lines, the "defview")

22:41 when I eval that file it translates the clojure code into javascript and inserts it into couchdb as a view :D

22:42 hiredman: _ato: excellent

22:44 qed: _ato: not totally sure what's going on there yet :)

22:46 I don't understand the syntax quote yet

22:46 how does that work

22:47 _ato: qed: it probably doesn't make sense unless you've used couchdb. But basically I'm using scriptjure to the that (defview .... [doc] (if (== ... ) ...))) into: "function (doc) {\nif ((doc.type == \"users\")) { \nemit(null, doc)\n };\n }\n"

22:47 so I can write views for couchdb (which are in javascript) straight into my application as clojure code and in the background they're magically turned into javascript and sent to the database

22:48 qed: whoa.

22:48 what calls the macro function?

22:48 _ato: it's at the top-level so it just gets called when the code is loaded

22:49 qed: ah ok

22:49 im just reading about "when to use macros"

22:49 i barely understand the unless example so far, but i can see how they're very powerful, im not particularly sure how defview works though

22:50 the syntax quote and the ([bindings]... in the beginning have me a little off

22:50 _ato: oh right.. I don't need that extra parens around the bindings

22:50 I added it because I was going to have arity overloading but then changed my mind

22:51 syntax quote is pretty easy, basically:

22:51 ,'(foo (+ 1 2))

22:51 clojurebot: (foo (+ 1 2))

22:51 _ato: normal quote, right, leaves everything unevalauted

22:51 qed: in general youd' only use those when you had something like ([])([args*])([& args])

22:51 right?

22:51 _ato: ,`(foo ~(+ 1 2)))

22:51 clojurebot: (sandbox/foo 3)

22:51 qed: whoa, what happened there

22:51 _ato: syntax quote lets you "unquote" in the middle with ~

22:52 and it also resolves all the symbols with the namespace they're in (that's where the sandbox/ bit comes from)

22:52 the reason it does that is so that if you define a macro in one file and use it another things work okay

22:53 but generally you can just think of it as a template

22:53 ,`[1 2 3 4 ~(+ 2 3) 6 7]

22:53 clojurebot: [1 2 3 4 5 6 7]

22:53 qed: so if you do `(blah ~a ~b), the bindings you defined in the defmacro [a b]

22:53 _ato: yeah exactly

22:53 qed: wont be evaluated until they are used as a macro

22:53 ah, kind of like the whole lazy eval thing

22:53 where you only execute the body when you call it

22:54 _ato: (defmacro m1 [x] `(foo x))

22:54 (defmacro m2 [x] `(foo ~x))

22:54 (m1 5) => (foo x)

22:54 (m2 5) => (foo 5)

22:55 qed: ah-ha, i see

22:55 _ato: oh and:

22:55 qed: it's just a way for you evaluate vars *now* inside the template

22:55 _ato: (defmacro m3 [x] `(foo ~@x))

22:55 qed: oooo

22:55 _ato: (m3 [1 2 3]) => (foo 1 2 3)

22:55 the "splicing unquote"

22:56 qed: so ~@ is just for a coll?

22:56 _ato: yes

22:56 qed: okay, wow, i feel like i learned more about clojure in like 4 hours than i have in the last 3 weeks

22:57 _ato: (m2 [1 2 3]) => (foo [1 2 3])

22:57 qed: sure, that makes sense

22:57 wow, that's cool

23:00 thanks again _ato

23:00 _ato: no worries

23:00 macros are where lisps really shine compared to most other languages

23:01 some people find them terrifying but to me the seem a lot simpler than the way metaprogramming works in say python or ruby

23:01 qed: so wait one more way to explain the ~ is that where a quote ', defers evaluation, a ~ enforces evaluation

23:02 yeah i learned some metaprogramming in ruby

23:02 and this seems way less roundabout

23:02 _ato: yeah, note that ~ only works with syntax-quote `

23:02 eg:

23:02 ,'(a ~b c)

23:02 clojurebot: (a (clojure.core/unquote b) c)

23:02 qed: sure

23:03 wait that was a ', not a `

23:03 ,`(a ~b c)

23:03 clojurebot: java.lang.Exception: Unable to resolve symbol: b in this context

23:03 _ato: ,`(a ~(+ 1 2) c)

23:03 clojurebot: (sandbox/a 3 sandbox/c)

23:03 qed: ,'(a ~b c)

23:03 clojurebot: (a (clojure.core/unquote b) c)

23:03 _ato: ,'(a ~(+ 1 2) c)

23:03 clojurebot: (a (clojure.core/unquote (+ 1 2)) c)

23:03 qed: ahhhh ok

23:04 _ato: most of the reader macros get turned into normal macros

23:04 eg

23:04 qed: ,'(str \a ~\b \c)

23:04 clojurebot: (str \a (clojure.core/unquote \b) \c)

23:04 _ato: ,(quote (a b c))

23:04 clojurebot: (a b c)

23:04 _ato: ,''(a b c)

23:04 clojurebot: (quote (a b c))

23:04 _ato: etc

23:04 qed: sure

23:04 it's like a ~~

23:04 in symbolic logic

23:05 ,'''(a b c)

23:05 clojurebot: (quote (quote (a b c)))

23:05 qed: ,''''(a b c)

23:05 clojurebot: (quote (quote (quote (a b c))))

23:05 qed: oh maybe not

23:06 ,(not (not '(a b c)))

23:06 clojurebot: true

23:06 qed: ,(not (not (not '(a b c))))

23:06 clojurebot: false

23:09 _ato: ,'`(evil (~test ~@fish))

23:09 clojurebot: (clojure.core/seq (clojure.core/concat (clojure.core/list (quote sandbox/evil)) (clojure.core/list (clojure.core/seq (clojure.core/concat (clojure.core/list test) fish)))))

23:10 cgordon_: does anyone have example code that uses the lazy-xml libraries?

23:11 qed: _ato: hehe

23:12 so, before i get to the answer in this book: (var my-symbol) is the verbose version of part of what happens during a (let [...])?

23:12 chouser: no

23:13 locals (as created by let) and vars have almost nothing in common

23:13 qed: k

23:13 _ato: qed: vars are used by (def ...)

23:13 qed: ahh

23:13 _ato: and (binding [...] ...)

23:17 cgordon_: If I have a list like ("start", ... some stuff ...., "end", "start", ... more stuff ..., "end", ...) and I want to write a function that takes it as input and produces: ( ("start", ... some stuff ..., "end"), ("start", ... more stuff ..., "end"), ...), what should I do? I'm having a hard time figuring out how to write this function (very much a functional programming novice)

23:18 hiredman: ,(doc split-with)

23:18 clojurebot: "([pred coll]); Returns a vector of [(take-while pred coll) (drop-while pred coll)]"

23:19 hiredman: ,(split-with (partial = :end) [:start 1 2 3 :end :start 4 5 6 7 :end])

23:19 clojurebot: [() (:start 1 2 3 :end :start 4 5 6 7 :end)]

23:19 hiredman: ,(split-with (partial not= :end) [:start 1 2 3 :end :start 4 5 6 7 :end])

23:19 clojurebot: [(:start 1 2 3) (:end :start 4 5 6 7 :end)]

23:19 hiredman: anyway

23:19 use fnparse :P

23:20 cgordon_: hiredman: that just splits it into two parts, right?

23:20 hiredman: cgordon_: you do it again with the remainder

23:20 over and over

23:20 cgordon_: ah, i see

23:20 hiredman: I think there is a partition-with in contrib

23:20 qed: there is

23:20 hiredman: ,(doc partition-with))

23:20 clojurebot: Pardon?

23:20 hiredman: ,(doc partition-with)

23:21 clojurebot: I don't understand.

23:21 hiredman: or not

23:21 ,(doc add)

23:21 clojurebot: "clojure.contrib.accumulators/add;[[acc item]]; Add item to the accumulator acc. The exact meaning of adding an an item depends on the type of the accumulator."

23:21 hiredman: hmm

23:21 qed: i could have sworm

23:21 sworn

23:22 ,(doc partition-by)

23:22 clojurebot: "clojure.contrib.seq-utils/partition-by;[[f coll]]; Applies f to each value in coll, splitting it each time f returns a new value. Returns a lazy seq of lazy seqs."

23:22 hiredman: still not optimal

23:23 cgordon_: should help, I just need some code to study

23:23 hiredman: you would need to toggle start inside f

23:23 qed: yeah

23:23 hiredman: you could definitly use reduce

23:24 cark: ah i was thinking state machine, but reduce sounds good

23:24 qed: ,(doc group-by)

23:24 clojurebot: "clojure.contrib.seq-utils/group-by;[[f coll]]; Returns a sorted map of the elements of coll keyed by the result of f on each element. The value at each key will be a vector of the corresponding elements, in the order they appeared in coll."

23:26 cgordon_: how would you use reduce to solve that problem?

23:26 seems like the accumulator would have to be fairly complex

23:29 hiredman: ,(reduce (fn [blob token] (if (= :end token) (update-in blob [:out] conj (conj (:scratch blob) token)) (update-in blob [:scratch] conj token))) {:out [] :scratch } [:start 1 2 3 :end :start 5 6 7 :end])

23:29 clojurebot: 3

23:29 hiredman: what?

23:31 ,(reduce (fn [blob token] (if (= :end token) (update-in (update-in blob [:out] conj (conj (:scratch blob) token)) (constantly [])) (update-in blob [:scratch] conj token))) {:out [] :scratch []} [:start 1 2 3 :end :start 5 6 7 :end])

23:31 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$update-in

23:31 hiredman: anyway

23:31 ,(reduce (fn [blob token] (if (= :end token) (update-in (update-in blob [:out] conj (conj (:scratch blob) token)) [:tmp] (constantly [])) (update-in blob [:scratch] conj token))) {:out [] :scratch []} [:start 1 2 3 :end :start 5 6 7 :end])

23:31 clojurebot: {:tmp [], :out [[:start 1 2 3 :end] [:start 1 2 3 :start 5 6 7 :end]], :scratch [:start 1 2 3 :start 5 6 7]}

23:31 cgordon_: well, it didn't say "42"

23:31 hiredman: the 3 is a bug in ArrayMap

23:31 well, not a bug

23:31 it is weird behaviour

23:32 ,((comp :out reduce) (fn [blob token] (if (= :end token) (update-in (update-in blob [:out] conj (conj (:scratch blob) token)) [:tmp] (constantly [])) (update-in blob [:scratch] conj token))) {:out [] :scratch []} [:start 1 2 3 :end :start 5 6 7 :end])

23:32 clojurebot: [[:start 1 2 3 :end] [:start 1 2 3 :start 5 6 7 :end]]

23:32 hiredman: something like that, but actually working

23:32 cgordon_: right, I think I get the idea

23:32 hiredman: ,((comp :out reduce) (fn [blob token] (if (= :end token) (update-in (update-in blob [:out] conj (conj (:scratch blob) token)) [:scratch] (constantly [])) (update-in blob [:scratch] conj token))) {:out [] :scratch []} [:start 1 2 3 :end :start 5 6 7 :end])

23:32 clojurebot: [[:start 1 2 3 :end] [:start 5 6 7 :end]]

23:33 hiredman:

23:33 qed: that's terribly ugly

23:33 hiredman: pffft

23:33 shows what you know

23:34 qed: it's an honest observation

23:34 hiredman: if you want pretty, use parser library

23:34 like fnparse

23:36 cark: clojurebot: paste?

23:36 clojurebot: lisppaste8, url

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

23:37 cark pasted "start-end" at http://paste.lisp.org/display/90883

23:38 cark: tho that's not quite functional style

23:45 cgordon_: cark: thanks, what isn't functional about that?

23:46 cark: it's functional, should be efficient too, not sure about the style, it get the job done anyways =P

23:46 looks like a lot of code for such a small thing to do

23:47 qed: yeah that's bothering me

23:47 im sitting here searching

23:47 but your solution looks like all there is

Logging service provided by n01se.net