#clojure log - Feb 24 2010

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

0:00 brandonw: holy crap, i finished optimizing the snake-solver algorithm i have been working on as my first project

0:01 removing duplicate transformations caused the run-time of the solver to go from over 4 minutes to 2.5 seconds

0:01 i knew it would help, but i didn't think it would help *that* much

0:51 slyphon: so, to create custom exceptions, you have to use gen-class?

0:52 oh

0:52 * slyphon sees "deferror"

0:53 slyphon: chouser: is error-kit supposed to be more common-lispy ?

0:58 jcromartie: lein uberjar is my new best friend

0:58 seriously

1:10 hamza: is there something in incanter that plots like mathematica's wordplot?

1:12 slyphon: argh, java is so fucking *lame* sometimes

1:50 TheBusby: did something like Tim Bray's parallel line reader make it into contrib or any standard library?

2:06 noticing that $ wc -l bigfile.txt takes 2.3 seconds while (time (count (read-lines "bigfile.txt"))) is taking ~27 seconds...

2:07 wc takes ~23 seconds the first time it's run, but then only about ~2.5 seconds every subsequent run. Clojure is taking 26+ seconds every time and I'm not clear why...

2:32 hiredman: does promise/deliver behave well with the stm?

2:35 doesn't look like it

2:35 :(

2:38 slyphon: if i have two vectors and i want (f [:a :b] [:c :d]) -> [:a :b :c :d] what's the thing that does that?

2:38 * slyphon found 'flatten' in seq-utils

2:41 hiredman: ,(into [:a :b] [:c :d])

2:41 clojurebot: [:a :b :c :d]

2:41 slyphon: oh, right

2:41 * slyphon needs to get his vocabulary up to speed

2:42 hiredman: (repeatedly promise) ;chuckles

2:43 slyphon: hahaha

2:43 (future-cancelled?)

2:43 hiredman: an immutable infinite sequence of promises turns out to be fairl useful

2:44 slyphon: sounds vaguely like marraige

2:45 or a very sepcific fortune-cookie

2:47 hiredman: http://paste.lisp.org/display/95522

2:47 lisppaste8: :(

2:48 avarus: moin

2:49 rads: is anyone else impressed that you can implement clojure-style multimethods in 10 lines of javascript? http://gist.github.com/313225

2:49 slyphon: hiredman: interesting

2:50 hiredman: rads: I doubt that

2:50 clojure's multimethods provide a lot that is not always used in simple treatments of same

2:51 for example you can use arbitrary hierarchies

2:51 dnolen: rads: not nearly as useful because you don't have value equality around arrays and object literals in JavaScript.

2:52 hiredman: and you can use vectors with the hierarchies

2:52 slyphon: and, like, static typing :P

2:52 "1" == 1

2:52 == FAIL

2:52 (sorry, pet peeve)

2:53 rads: dnolen: I'm not sure what you mean

2:53 dnolen: rads: ["foo", "bar"] != ["foo", "bar"] in JavaScript

2:54 {"foo": "bar"} != {"foo":"bar"}

2:54 these are valid matches in Clojure multimethods and _VERY_ useful.

2:54 hiredman: ,(isa? [String Integer] [Object Object])

2:54 clojurebot: true

2:54 rads: dnolen: that seems to work in the example I posted unless I'm missing something (only tested in safari)

2:54 hiredman: see clojure uses isa? for dispatching in multimethods

2:55 so if your dispatch function makes a vector of the types of the arguments

2:56 the multimethods will look for methods that match exactly, but also walk up the hierarchy

2:56 rads: I'm not saying the 10 lines I posted are just as good as clojure multimethods, but they provide the core functionality.

2:57 hiredman: they provide something that is superficially similar

2:57 dnolen: rads: trust me, not even close. I breath JS. not even superficially similar. your code doesn't work for object literals

2:57 var o = {}; o[["foo","bar"] = "cool";

2:58 coerces the array in to a string

2:58 that why it works for arrays

2:58 rads: I see

2:58 dnolen: doesn't work for nested arrays, doesn't work for object literals

2:58 totally broken.

2:59 it can work if you JSON.encode your key first

2:59 also you can take object literals and convert them into arrays sorted by key, recursiing through the object literal.

2:59 this is of course dog slow

3:00 but a useful technique depending, such as dispatching on url routes.

3:00 slyphon: wow, testing in clojure is pretty sweet

3:02 dnolen: rads: that said, JS is great. I love it. It actually spoiled me on most other languages. Then I found Clojure :)

3:02 rads: dnolen: I'm just thinking about applying clojure concepts to JS, mainly trying it without OO

3:04 dnolen: rads: yeah, Clojure has done wonders to my JS. http://github.com/ShiftSpace/functools

3:04 rads: dispatch on fn arity, pre-post conditions, hash and arrays as fns, all useful in JS

3:05 rads: dnolen: looks good. I like underscore.js too

3:07 something I wonder now that I've learned clojure is how much OO is necessary

3:07 dnolen: rads: yes, I actually wrote that like the day before underscore.js came out :) underscore does most of this and without changing prototypes.

3:07 somethings you just can't do in JS without OO. Since you can't write macros, you have to change the system via prototypes

3:08 rads: http://github.com/ShiftSpace/promises, futures/promises, data-flow style programming in JS

3:09 this really needs OO to work (in a language like JS anyway)

3:13 rads: it seems that after working with clojure, advanced OO features like ruby's metaclasses just make things unnecessarily complicated

3:51 a_strange_guy: hi there

3:52 is there a reason why EvalReader doesn't use eval?

3:54 because something like #=(+ (+ 1 2) 3) blows up

3:54 hiredman: right

3:55 evalreader is for calling constructors basically

3:55 arguments are not evaluated

3:55 a_strange_guy: hmm, that sucks

3:56 hiredman: why are you trying to do a lot of evaluating in the reader?

3:56 a_strange_guy: I want to define a print-dup which can print closures correctly

3:58 hiredman: a_strange_guy: fns are compiled to classes

3:58 a_strange_guy: yes

3:58 hiredman: ,(class @#'+)

3:58 clojurebot: clojure.core$_PLUS___4518

3:58 hiredman: ,(.newInstance (class @#'+))

3:58 clojurebot: #<core$_PLUS___4518 clojure.core$_PLUS___4518@1239b45>

3:58 hiredman: ,((.newInstance (class @#'+)) 1 2)

3:58 clojurebot: 3

3:59 hiredman: #=(fn.class.name.)

3:59 a_strange_guy: but this wont work if the fn closes over something

3:59 hiredman: I don't thing you can expect to get that to work without many caveats

4:00 a_strange_guy: this is pretty fragile, but can work

4:03 my poor hack for now is to extract all private non-static fields from a fn

4:03 hiredman: a_strange_guy: http://paste.lisp.org/display/91148 might be interesting

4:06 a_strange_guy: hiredman: nice, never thought of using deftype to created Fns

4:07 hiredman: it has a few issues, hence "fn minus"

4:07 I don't think recur or destructuring work

4:15 AWizzArd: Hi guys

4:15 Hi Lau, how are you?

4:28 avarus: very silent

4:29 AWizzArd: Yes, they are all still sleeping :)

4:30 esj: fortunately they're non-blocking

4:30 AWizzArd: ^^

5:06 raek: if I want to add unit tests to my project, is clojure.test the recommended lib to use?

5:06 AWizzArd: yes

5:06 raek: great!

5:07 LauJensen: Morning guys

5:08 Sorry I missed you AWizzArd, it only beeps on 'LauJensen' - But I'm doing good thanks, you ?

5:10 AWizzArd: fine, thanks :)

6:40 dmiles_afk: achidemic question.. could clojure tranlate to a .java file instead of bytecode.. and stiull be somewhat ok?

6:41 would it lose speed in running? .. (skipping the fact that one needs t compile the java)

6:42 Chousuke: dmiles_afk: sure it could, but there's little reason to do that :/

6:43 dmiles_afk: well sometimes a languge that emits bytecode .. if you decompile it . you realize that a java programmer might have done something better

6:44 after you spot that.. you might imporve the compiler

6:44 or decide instead ot make something a java utility class

6:44 Chousuke: well, decompilation is inaccurate anyway

6:44 dmiles_afk: at least one part of ones program

6:44 Chousuke: probably the clojure compiler produces bytecode patterns that a normal java program would never have

6:45 decompiled clojure is going to look really weird to a java programmer

6:49 dmiles_afk: soemtimes i use just javap

6:51 if someone is converting representtions for convenience of data type conversion.. but they didnt know they where gettign helped in the compiled form

6:52 mainly that might be if anything one might spot

7:03 hamza: incanter does not support pie charts?

7:03 Leafw: jfreechart does, so it ma be a matter of some glue code.

7:05 hamza: yeah but it seemed a bit odd that it does not support it..

7:14 ivan: has anyone seen any test runners that are integrated into an event loop, so that you can resume a test after doing some asynchronous stuff?

7:15 or is the generally strategy to always block in a thread if you want to do this

7:48 powr-toc: I have a problem with clojure-mode and swank-clojure... When Emacs starts I get the error "Cannot open load file" "swank-clojure-autoload"... Any advice?

7:57 hoeck: powr-toc: thats an obsolete file

7:57 powr-toc: then why is it in the latest swank-clojure?

7:57 I mean clojure-mode

7:58 avarus: have you tried turning it off and on again?

7:58 I mean a fresh install

7:58 powr-toc: yeah.... I'm looking at commit 2c3e27753ac40abd22f17d3f9c678d8fa9c8a16a

7:59 see line 702: http://github.com/technomancy/clojure-mode/blob/2c3e27753ac40abd22f17d3f9c678d8fa9c8a16a/clojure-mode.el

8:13 hoeck: powr-toc: it looks like you could safely remove this line (require 'swank-clojure-autoload) from clojure-mode.el

8:15 powr-toc: Ok... I've nuked all my old emacs configs, and I'm trying to install fresh via ELPA... I've M-x package-list-packages and installed swank-clojure... but M-x slime fails to establish a connection... How is it I get swank-clojure to install clojure?

8:16 Do I know do M-x clojure-install?

8:17 Hmmm... that fails to compile contrib, as that now uses maven...

8:17 hoeck: not shure what that does

8:17 you can download latest contrib and clojure from http://build.clojure.org/

8:20 powr-toc: hoeck: I know... I'm just trying to figure out how to get slime/swank-clojure going... I attempted an upgrade and fubar'd everything...

8:24 hoeck: powr-toc: how did you upgrade?

8:25 basically you need latest swank-clojure, slime and clojure-mode from technomancy, then add/update some config foo to your .emacs

8:26 powr-toc: hoeck: I know that :-) ... unfortunately it doesn't seem to be working... and the swank-clojure docs etc... recomend ELPA installs... so I've tried that way, and it's still not working :-(

8:27 hoeck: powr-toc: yeah, had no success with ELPA either, so I did a full manual install

8:27 powr-toc: hmmm... maybe I'll back out and try again with a blank manual install

8:28 looks like another hour shaving yaks :-)

8:32 Hali_303: hi

8:32 ohpauleez: hi Hali_303

8:32 Hali_303: tab completion does not work for me on clojure sources files. any idea how to resolve this? on the border, it says "Clojure Raredit"

8:33 Paredit, sorry

8:34 a_strange_guy: have you installed Slime?

8:35 you need a running 'slime-repl clojure' for good tab-completion

8:35 Hali_303: a_strange_guy: sure, the repl is working (the border says: *slime-repl clojure*), and also, tab completion is working there

8:36 my problem is that tab completion does not work when opening a clojure source file using C-x C-f

8:37 ah, the reason is, that I need to do C-c TAB instead of simply TAB

8:37 a_strange_guy: jepp

8:38 what i have done is binding tab completion to Ctrl-Space

8:38 like in eclipse/netbeans

8:40 does anone know how to instanciate a class that lives in the default packags?

8:40 ^package

8:40 chouser: :-(

8:41 it's not really supported

8:42 a_strange_guy: damn, have to use Reflection (yuck)

8:42 chouser: you can't move the class?

8:42 a_strange_guy: actually, try importing it first.

8:44 (import Foo) (Foo. args) seems to work.

8:44 a_strange_guy: can't do that, I'm trying to instanciate Fns directly (yep evil)

8:44 and import isn't an option in this case

8:46 chouser: (clojure.lang.Reflector/invokeConstructor (Class/forName "Foo") (to-array [args go here]))

8:46 unless you've got an unusual classloader situation as well, in which case you might need a different mechanism for getting the right Class instances.

8:47 a_strange_guy: c.l.Reflector works

9:01 powr-toc: ARRGHHGHGHGHG... it looks like I need ELPA installed to run technomancy's slime regardless of whether I use ELPA to install slime/swank

9:02 AWizzArd: unfortunately yes I think

9:02 It was so nice until some time in October 2009

9:02 You could download the freshest version of slime, just download swank-clojure and put it into a dir, done.

9:02 powr-toc: AWizzArd: yeah, but is that clojure compatible?!?!

9:03 i.e. does it work with technomancy's swank-clojure and clojure-mode?

9:05 AWizzArd: I don't think so. I used to use jochu-swank.

9:06 But unfortunately he seems to have stopped managing it.

9:06 powr-toc: that versions way out of date

9:06 AWizzArd: yes :-(

9:07 And also in slime there were some changes in October, and that seems to made it incompatible with that last version of swank-clojure

9:07 So I basically still use this 5 months old code.

10:17 Raynes: Three days. Three days I've been trying to find a bug in my code, and it's a mistyped keyword. :heartss instead of :hearts

10:17 I'm off to kill myself now. You have a very nice day.

10:18 cemerick: Raynes: that's nothing compared to the time I blew a week looking for what turned out to be an unprintable char in a literal string.

10:19 esj: UTF8 vs ASCII is always fun that way

10:19 cemerick: apache's httpclient certainly is featureful, but *holy hell* is it complicated.

10:20 _fogus_: I've spent untold hours chasing misplaced semi-colons in Java and misaligned spacing in Python

10:21 chouser: I once lost an entire year tracking down a tab where there should have been eight spaces.

10:21 ok, no I didn't.

10:22 stuartsierra: heh

10:23 chouser: sorry, got caught up in the moment

10:23 * _fogus_ just won a battle for Clojure versus "Ruby Guy"

10:23 chouser: _fogus_: ooh, at work?

10:23 _fogus_: yes

10:23 :)

10:23 tmountain: when I first started programming, a friend and I spent a whole day trying to find a missing curly brace in a gigantic monolothic perl script

10:23 newbs

10:24 Maddas: _fogus_: A verbal battle?

10:24 _fogus_: He didn't see the obvious flaw in his argument against the long string of closing parens ))))))

10:24 Maddas: We were not really arguing.

10:24 tmountain: parens are a lot easier to match on than "end"

10:25 _fogus_: tmountain: Bingo.. end end end end end end

10:25 Maddas: :-)

10:26 tmountain: other gripe about ruby... the methods aren't really first-class

10:27 _fogus_: Should they be?

10:27 tmountain: well, it'd be a lot less clunky than using a proc object

10:28 cypher23: tmountain, http://yehudakatz.com/2010/02/21/ruby-is-not-a-callable-oriented-language/

10:28 _fogus_: http://yehudakatz.com/2010/02/21/ruby-is-not-a-callable-oriented-language/

10:28 ahhhhh, beat me to it

10:28 cypher23: heh

10:28 tmountain: don't get me wrong, I like ruby

10:29 I just like Clojure more

10:29 cypher23: tmountain, I also occasionally wonder why Ruby methods aren't first class (like in clojure), but then again, I've never actually missed them

10:29 I rarely ever call a proc directly, almost always through yield

10:30 tmountain: yield essentially provides coroutines, so it negates a lot of the pain

10:30 jcromartie: what's the way to wrap up a Java method, like #(.trim %)

10:30 but there's some other way

10:30 chouser: jcromartie: that's the best way currently

10:31 You can build real coroutines in ruby because it has callcc.

10:31 jcromartie: oh, I just found memfn

10:32 chouser: yeah, memfn is old. likely to be deprecated, I think.

10:33 tmountain: chouser: yeah, I've never learned to fully exploit callcc

10:33 chouser: although, I'd like to

10:33 cemerick: wow, memfn is still around :-/

10:34 jcromartie: hmm

10:34 is memfn bad?

10:34 cemerick: surely it doesn't do anything that #() doesn't handle?

10:34 jcromartie: deprecated?

10:34 chouser: cemerick: right. in fact, it does less.

10:34 stuartsierra: memfn is vaguely deprecated

10:34 cemerick: yeah, that's why I'm surprised it's still around

10:34 stuartsierra: chouser: less?

10:35 chouser: #() is useful in places where memfn is not. Anywhere memfn can be used, #() would also work.

10:35 jcromartie: is this a decent way to get the tokens out of a string? (filter (comp not empty? #(.trim %)) (.split x "[\\,\\s]"))

10:35 stuartsierra: chouser: oh, I see what you mean

10:36 jcromartie: or is comp obfuscating it

10:36 chouser: jcromartie: I'd recommend using the regex literal for regexes

10:36 (.split #"[,\s]" x)

10:36 jcromartie: ,(.split "foo bar" #" ")

10:36 clojurebot: java.lang.ClassCastException: java.util.regex.Pattern cannot be cast to java.lang.String

10:36 jcromartie: ,(.split #" " "foo bar")

10:36 clojurebot: #<String[] [Ljava.lang.String;@1bc70f3>

10:36 jcromartie: ah

10:36 I see

10:37 that's why I wasn't using it

10:37 I didn't realize .split was a method of regexes

10:37 chouser: ,(re-seq #"[^,\s]+" " foo, bar,baz bing ")

10:37 clojurebot: ("foo" "bar" "baz" "bing")

10:37 jcromartie: beautiful

10:38 chouser: and re-seq is lazy, so ... that's fun. :-)

10:38 jcromartie: thanks!

10:39 code clarity++

10:39 err, (inc code-clarity)

10:39 err, (dosync (alter code-clarity inc))

10:40 cemerick: stuartsierra: how far did you ever get in wrapping httpclient?

10:40 stuartsierra: cemerick: I didn't.

10:40 cemerick: oh, I thought you had started on that.

10:41 stuartsierra: I think technomancy & danlarkin have one on Github

10:41 cemerick: ah

10:41 danlarkin: confirmed

10:41 clojure-http-client

10:43 stuartsierra: i'm too preoccupied with test frameworks

10:43 to do anything useful

10:44 ;)

11:00 cemerick: danlarkin: yeah, I was actually talking about apache's httpclient :-)

11:01 danlarkin: ohh right we just used standard java stuff

11:01 it's been a while

11:03 stuartsierra: It's not that bad to just use the Apache client directly.

11:04 cemerick: it gets pretty gnarly if you're using basic auth + multipart POSTs

11:04 stuartsierra: oh. Well, anything would. :)

11:04 cemerick: heh, almost :-)

11:05 I'm almost to the point of having a pretty clean solution using http.agent + my wrapper of it + httpclient's MultipartRequestEntity to construct the :body

11:06 stuartsierra: wow

11:06 That's... frightening.

11:06 cemerick: ha

11:47 a_strange_guy: 20 lines of clojure => closures can be serialized: http://gist.github.com/313601

11:48 evil hack though

11:49 would that be useful?

11:50 chouser: hm. closures but not the code of their fn

11:52 a_strange_guy: sure, but print-dup didn't do that before anyway

11:54 hugod: I was thinking it would be nice to have pluggable behaviour in error-kit for what to do when there is no default handler - swank could then give us a list of continues to choose from...

11:55 Hali_303: clojure.contrib.str-utils disappeared from the online docs @ clojure.org

11:55 is there a new clojure.contrib coming? where is it available?

11:55 Chousuke: Hali_303: make sure you have the docs for the correct branch

11:55 I think there's some reorganisation going on

11:55 chouser: Hali_303: it's been renamed clojure.contrib.str and the arg order changed again

11:56 hm, or maybe c.c.string

11:56 Hali_303: ok, no problem, but where is the binary?

11:57 chouser: http://richhickey.github.com/clojure-contrib/string-api.html

11:57 what binary?

11:57 powr-toc: I have a thread running over some clojure code that needs to send an event to swing to toggle a button on/off on the gui... Any ideas on what the nicest way to do this might be?

11:58 StartsWithK: a_strange_guy, does it work with things like streams or sockets? i don't think you can serialize them

11:58 Hali_303: chouser: I've got a jar for clojrue contrib 1.1, that has str-utils and str-utils2. I guess there's a binary that has c.c.string in it

11:58 maybe I need to get everything from sources?

11:59 chouser: Hali_303: I use the sources, but this might work for you: http://build.clojure.org/job/clojure-contrib/lastSuccessfulBuild/artifact/target/clojure-contrib-1.2.0-SNAPSHOT.jar

11:59 Hali_303: chouser: ah nice, thanks

12:00 a_strange_guy: StartsWithK: it doesn't, this makes it possible print and read a closure

12:00 serialization is the wrong word for that

12:01 powr-toc: I was thinking about using an agent to capture the boolean changes, but the real value I need to change Menuitem.enabled lives in a mutable MenuItem object.

12:03 a_strange_guy: powr-toc: i used a watcher for a simillar case

12:04 whenever the state of the agent changes you set the mutable field

12:04 just make sure not to touch the mutable directly

12:05 chouser: powr-toc: like SwingUtilities/invokeLater ?

12:05 powr-toc: chouser: Yeah, was thinking about that one

12:06 that seems the best choice... anything else is overkill

12:08 chouser: if you have a bunch of state, something more sophisticated to keep the gui state in sync with some more carefully controlled state might be in order.

12:18 powr-toc: Is wrapping a def/defn inside a let bind considered good or bad form?

12:18 stuartsierra: "rand7 from rand5" puzzle in Cloure: http://paste.lisp.org/+21Q2

12:18 chouser: powr-toc: I think it's acceptible *if* it only is evaluated once.

12:19 StartsWithK: powr-toc, you can reverse it (def foo (let [helper (fn ..)] (fn ([] (helper)) ([a] (helper a)))))

12:19 chouser: powr-toc: though I tend to prefer to rearrange to avoid it: (defn foo (let [...] (fn [a b] ...)))

12:19 * chouser high-five's StartsWithK

12:19 StartsWithK: :)

12:20 hiredman: of course that doesn't help if you want several defn's to close over the same thing

12:20 powr-toc: chouser: StartsWithK: There are two def/defn's sharing the bind though

12:21 chouser: powr-toc: and using another var instead of a let is unacceptable?

12:21 StartsWithK: powr-toc, create a toplevel private def or defn

12:21 chouser: I'll just go get some work done and let StartsWithK finish up here...

12:22 StartsWithK: hehe

12:22 powr-toc: Not unnacceptable no... I don't know why, but I like to maintain very tight scopes... is that bad form?

12:25 StartsWithK: no, but i don't think you should go to excessive lengths wit that

12:25 with*

12:27 powr-toc: why? Does it not improve legibility, by documenting explicitly what functions change the state? Or do you think the costs of refactoring later when more things need access to the state are to high?

12:32 krumholt: is there a version of assoc that only updates the map if the key does not exist?

12:33 chouser: ,(merge-with (fn [a b] a) {:a 1} {:a 2})

12:33 clojurebot: {:a 1}

12:34 chouser: hm. not too impressive, but I don't know of anything better.

12:34 krumholt: ok thanks

12:34 chouser: hm, or merge the other way 'round

12:35 ,[(merge {:a 2} {:a 1}) (merge {:b 2} {:a 1})]

12:35 clojurebot: [{:a 1} {:a 1, :b 2}]

12:50 chouser: if IKeywordLookup were a protocol, I could extend it to an existing interface, right? But since it's an interface, I can't?

12:59 so I guess I'll have to wrap instance of this 3rd party interface, and use it to implement IKeywordProtocol

13:13 oh! I can't implement IKeywordLookup in a deftype because deftype wants to do it itself!

13:14 no choice. huh. okay -- next up, reify...

13:14 hiredman: sounds like a long road to hoe to avoid (.someField

13:15 chouser: heh. it does, doesn't it.

13:15 but I did it the direct way before and it was a contributing factor to much pain. So I think this is worth some effort at least...

13:16 there are a couple other features I'll be able to tie in with this. One is mapping of values in ways I consistently need.

13:16 Another is sane printing at the repl

13:17 Another is supporting all of IPersistentMap so I can use rename-keys and such.

14:07 avarus: hi

14:17 cemerick: require seems to always look for a source file, even if the provided namespace exists.

14:19 technomancy: cemerick: I was wondering about that myself.

14:20 elisp has a "provide" function that will add the ns to the "already required" list

14:20 cemerick: technomancy: OK, glad it's not just me. :-)

14:20 It seems like just looking for that namespace is sufficient.

14:20 technomancy: you can alter clojure.core/loaded-libs in a transaction if you're crazy, but yeah.

14:21 it's certainly an off-the-beaten-path need

14:21 clojurebot: have you heard about the bird? is<reply>The bird, bird, bird, the bird is the word.

14:21 cemerick: The contract of require w.r.t. "skipping already-loaded libs" seems pretty broken as-is.

14:22 loading new ns' over the wire is sorta painful as-is :-/

14:22 technomancy: well steve gilardi is working on revamping that anyway

14:22 but I think the new version is going to check the status of the .clj or .class file on disk to determine whether it needs to be loaded

14:22 cemerick: excellent. I'll go find something else to whine about. ;-)

14:23 technomancy: rather than the ref

14:23 might not solve the problem you're running into

14:23 cemerick: no, it doesn't sound like it

14:23 technomancy: I think he posted about that c. January

14:23 cemerick: e.g. remote process, pushing new code at it

14:23 on dev, or the main group?

14:24 technomancy: probably dev

14:24 cemerick: thanks, I'll take a look

14:24 technomancy: I get confused since I sort them all into the same place.

14:25 cemerick: I've stopped following the main group almost entirely. The traffic is simply too high, and interesting stuff filters up into twitter anyway. :-)

14:25 technomancy: yeah, that's inevitable at a certain point

14:27 piccolino: I'm getting a test failure I don't understand: http://gist.github.com/313745

14:30 esj: technomancy: I'm having difficulty getting the -Xbootclasspath part of the command line that leiningen invokes to work under Windows. Have you run across this ?

14:32 technomancy: esj: transitive requires don't work when clojure is on the boot classpath, but there shouldn't be any of those in leiningen proper

14:32 could be a problem with plugins

14:33 esj: perhaps - swank keeps throwing up its hands with "can't find clojure.main" error

14:33 technomancy: esj: that's something else; not sure what's going on there

14:33 esj: it only throws this on (-main "swank")

14:33 where does it look for its clojure.main ?

14:34 its all peachy if the library I'm using and the leiningen checkout use the same branch of clojure but if i try to got to 1.2.0 for my project then it all goes ape

14:35 how I hate windows. It works 100% on my mac

14:36 technomancy: esj: that sounds like a bug in a 1.1.0 leiningen snapshot that was fixed in the release; are you up to date?

14:36 esj: btw: the .bat file that comes with leiningen does not import the leiningen deps into the classpath, like the .sh script does

14:36 technomancy: should be, let me see

14:38 robwolfe: esj: it should, have you tried "set DEBUG=1"?

14:38 esj: robwolfe: no, I've been debugging with echos (time of my life) and it only includes the lib dir for the current project.

14:39 robwolfe: esj: so what other dendencies you mean?

14:40 esj: the .sh file includes the .lib dir for leiningen, if its not uberjar'd

14:40 robwolfe: you mean lib dir from Leingen checkout?

14:40 esj: yeah

14:41 robwolfe: that's true lein.bat has only lain-stable functionality

14:41 esj: ok

14:43 cemerick: oh multimethods, how I love thee.

14:43 eom :-)

14:44 esj: robwolfe: so if I checkout the latest github, make the jar, install it into the repository I should be good to go ?

14:44 robwolfe: yep

14:45 esj: hopefully that will give me swank

14:45 robwolfe: esj: make sure you use 1.1.0 swank

14:45 esj: you got it

14:47 chouser: so ... I think I'm successfully hooking into the callsite caching stuff.

14:48 I wonder why rhickey said it wouldn't work.

14:51 esj: robwolfe, technomancy: so having done all this. lein deps, repl etc all work 100%. lein swank only works if I'm using clojure-1.1.0 in my project. If I go to 1.2.0 I get the usual mismatch exceptions. do I need to rebuild swank under 1.2.0 ?

14:53 * robwolfe has no experience with 1.2.0 on Windows

14:55 esj: Yeah, usually I wouldn't be so gung-ho. Anyways, thanks for your help guys.

14:57 chouser: http://gist.github.com/313728 -- leveraging call-site caching for getter access

14:57 hiredman: chouser: excellent

14:58 chouser: I'm indordinately excited about this. :-)

15:02 hiredman: it's sort of keywordcallsites => java bean

15:03 chouser: ah, yes!

15:03 right

15:04 jeffmess: does clojure have a library for for tunneling into servers on a port? Can server-socket do this

15:05 hiredman: so the get method on the thunk is ignoring the argument?

15:05 oh

15:05 no

15:06 albino: jeffmess: are you thinking like ssh?

15:06 jeffmess: telnet

15:06 sorry, "tunneling" probably wasnt the right word.

15:07 chouser: one potential issue is that the thunk closes over whatever object was first used at the callsite

15:07 oh! no it doesn't.

15:07 hiredman: hmmm

15:07 albino: jeffmess: if you go the ssh route you can use something like this from clojure: http://www.cleondris.ch/ssh2/

15:07 hiredman: it uses the gensym

15:08 it's nice

15:08 jeffmess: albino: thx, Ill check it out.

15:08 chouser: no it doesn't. The message-map obj closes over the msg you give it, but that's just what you'd expect. if you drop the message-map, it and the msg can be GC'ed, but the callsite thunk should live on.

15:08 albino: jeffmess: for what it's worth I stopped doing telnet like 7 years ago.

15:09 jeffmess: good old legacy code that wont be dying anytime soon :)

15:10 albino: jeffmess: hehe, I've also had that problem before too :)

15:11 jeffmess: what about this? http://www.javassh.org/space/start

15:11 jeffmess: albino: looks a bit more promising.

15:30 hiredman: ,*clojure-version*

15:30 clojurebot: {:interim true, :major 1, :minor 1, :incremental 0, :qualifier "master"}

15:36 hiredman: chouser: http://paste.lisp.org/display/95560

15:38 chouser: I think I need to support ILookup at least, as well as other stuff to be a good citizen

15:39 Seqable, etc.

15:43 hiredman: so ILookup would just punt to the thunk?

15:44 chouser: hm... dunno.

15:45 maybe put the thunks in a cache of my own in the message-map obj, so that I could look them up and run them for ILookup?

15:45 eh, that's kinda lousy

15:45 not sure if there's a good way to do ILookup without runtime reflection

15:49 lancepantz: i'm trying to build a war file with an example compojure project and having some problems

15:49 the war file should contain a lib dir with compojure and clojure in it after it's built, correct?

15:53 piccolino: Does anyone have any idea why this test is failing when it so clearly appears it should succeed? http://gist.github.com/313745

15:55 hiredman: looks like you in your test you are expecting a map with symbols and otehr stuff in it, but passing in a map with strings and etc

15:57 piccolino: Hm. I just tried substituting the symbols for the strings the symbols refer to, but it gave the same output.

15:57 hiredman: then you did it wrong

15:58 it looks like a quoting issue, i.e. the symbols in the test are quoted so not resolved and what you pass in has been resolved

15:58 it's hard to say because all you have not posted much of anything

16:00 piccolino: I just updated the gist with both versions of the test code and output.

16:03 hiredman: ,(doc is)

16:03 clojurebot: "clojure.contrib.test-is/is;[[form] [form msg]]; Generic assertion macro. 'form' is any predicate test. 'msg' is an optional message to attach to the assertion. Example: (is (= 4 (+ 2 2)) \"Two plus two should be 4\") Special forms: (is (thrown? c body)) checks that an instance of c is thrown from body, fails if not; then returns the thing thrown. (is (thrown-with-msg? c re body)) checks that an instance of c is thrown AND

16:11 arohner: oh, here's a fun new error I haven't seen before:

16:11 java.lang.OutOfMemoryError: GC overhead limit exceeded

16:12 hiredman: oooh

16:12 morphling: arohner: it means that most of the running time is spend garbage collecting and not much memory is freed

16:12 chouser: in my experience that's generally interchangable with filling the heap

16:13 hiredman: http://java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html#par_gc.oom

16:13 arohner: yeah, I was getting OOMs, and out of curiosity I tried raising my heap size to see if the problem went away, and got that

16:14 hiredman: you might try one of the options that prints out GC pass information

16:20 chouser: I'd like to be able to (optionally) print a *warn-on-reflection* type msg when a :inline-able function is not inlined.

16:21 *warn-on-noninline* would complain about (map + [1 2] [3 4])

16:23 arohner: that's a warning when you call the non-inline arity of a function that has inlined arities?

16:23 chouser: non-inline arity or refer to its value as a function rather than at the front of a list where its macro part can be expanded

17:01 dakrone: can anyone tell me what file I'm missing for this: http://pastie.org/private/fl1lzrr8n6wa8e8t4iw27a

17:06 {newbie}: dakrone: is you path set apropriatly

17:06 ?

17:07 where is you ClojureTest.clj?

17:07 _ato: the file you're compiling is located in ./com/emc/avamar/dtlt/actions/ClojureTest.clj right?

17:07 {newbie}: yes

17:07 or it should be

17:07 dakrone: yea, here's a new paste showing that: http://pastie.org/841319

17:07 _ato: you might also need to set -Dclojure.compile.path= to the location you want the compiled class files to go to, you'll also need to add that location to the classpath

17:08 SirNick: Hello, I'm very new to clojure and am having a problem using recur. I am getting the error "Can only recur from tail position" from this function: http://paste.pocoo.org/show/182239/ I don't see why the recur is not in a tail position. Anyone have any insight?

17:08 dakrone: {newbie} / _ato: yea, the file exists, if it had problems with that I get a completely separate error that's much more helpful than this one

17:09 _ato: ah right

17:09 I'm misreading it

17:10 dakrone: okay, I created a bin folder and added -Dclojure.compile.path=bin, now I get java.lang.RuntimeException: java.lang.ClassNotFoundException: com.emc.avamar.dtlt.actions.ClojureTest$loading__4925__auto____27 (ClojureTest.clj:1)

17:10 _ato: excellent

17:10 hiredman: SirNick: the recur is not in tail position in the let

17:10 _ato: add bin to the classpath

17:10 hiredman: (let [] (recur) nil) is basically what you have

17:11 dakrone: _ato: awesome, that fixed it. Thanks!

17:11 I didn't realize I needed the path and the path to be in the classpath, now I know :)

17:11 SirNick: hiredman: Ah I see it now... Thank you. I figured it had something to do with incorrect parens

17:12 _ato: yeah, sort of a bit counter-intuitive, since Clojure actually executes code while compiling (eg macros) it needs to be able to use classes it's compiled while it's compiling them

17:21 jcromartie: anybody using http-agent to do API testing?

17:23 dakrone: _ato: is there any way to get clojure not to execute code while compiling, some of my code executes shell commands so...

17:23 jcromartie: I can't imagine it would work with deftest?

17:23 dakrone: I'd have to reply with a quippy you're doing it wrong...

17:24 dakrone: jcromartie: it's a giant complicated enterprise backup thing with no API, I don't have any other choice

17:24 jcromartie: you can't put them in functions?

17:24 make a main, or something?

17:24 use gen-class and -main

17:25 dakrone: jcromartie: I'm not familiar enough with clojure compile function, is only code in certain functions that get compiled actually executed when it's compiled?

17:25 or is it possible to work around it by putting it elsewhere?

17:25 jcromartie: anything in the top-level will be evaluated

17:26 dakrone: what do you mean by top-level?

17:26 jcromartie: so put it in a function

17:26 (ns foo) (defn top-level-fn [] nil)

17:26 _ato: (println "hello world") will print hello world during copmile

17:26 (defn foo [] (println "hello world")) will not

17:26 jcromartie: (ns foo) (def top-level-var nil)

17:27 _ato: (def x (println "hello world")) will

17:27 dakrone: in the example I pasted, would -execute actually be called at compile time?

17:27 _ato: no

17:28 dakrone: okay, then that wouldn't be a problem if I had shell stuff in there

17:28 awesome :)

17:28 _ato: yep, it'll only be a problem if you put code outside any function -- which most people would normally not do anyway

17:29 * dakrone slowly replaces all the xworks/tomcat/java stuff with Clojure...

17:29 sthuebner: sorry for interrupting. Just a quik question: what is this kind of form (#{a b} c) doing?

17:30 chouser: #{:a :b} is a literal set

17:30 a_strange_guy: checking if c is equal to a or b

17:30 dnolen: sthuebner: a lot of the datastructures can act as functions, confusing but then ... useful

17:30 ,([1 2 3] 2)

17:30 clojurebot: 3

17:31 dnolen: ,({:foo 'bar} :foo)

17:31 clojurebot: bar

17:31 _ato: ,({:a :b} :c)

17:31 clojurebot: nil

17:31 _ato: ,({:a :b} :b)

17:31 clojurebot: nil

17:31 _ato: ..

17:31 oh right

17:31 ,(#{:a :b} :b)

17:31 clojurebot: :b

17:31 sthuebner: ah, this is what's behind the phrase "Sets are functions of their members"!

17:32 dnolen: sthuebner: pretty cool, eh? :)

17:32 sthuebner: thnx!

17:32 dnolen: cool indeed!

17:34 a_strange_guy: ,(meta (#{(with-meta 'sym {:a 1}) 'other-sym} 'sym))

17:34 clojurebot: {:a 1}

17:35 sthuebner: puh, feels magic

17:36 chouser: I'm going to take advantage of exactly that property (being able to look up a symbol in a map without knowing its metadata, then using its metadata)

17:36 ...at compile time.

17:36 whee!

17:36 a_strange_guy: i've actually used it once ^^

17:37 ... until i realized that I wanted a hashmap isnstead

17:37 chouser: heh. right.

17:37 but I'll be using a hash-map created by the compiler, where I only have control over the keys. so this'll be perfect.

17:39 a_strange_guy: chouser: It tookme a while to realize that you weren't joking

17:39 sthuebner: thanks guys. that helped a lot

17:40 a_strange_guy: str

17:40 chouser: (defmacro hack [] (vec (map meta (keys &env))))

17:40 (let [#^:foo a 5] (hack)) ==> [{:tag :foo}]

17:41 hiredman: D:

17:41 interesting

17:45 _ato: ha, nice. That's a usage that never occurred to me. &env opens up all kinds of interesting- uhh... abuse

17:46 a_strange_guy: are the vals of the &env map useful for anything?

17:48 powr-toc: chouser: what on earth does that do!? :-)

17:48 what is &env?

17:48 (keys &env)

17:49 _ato: &env returns a map from symbols to a compiler-specific thing for each binding in the lexical scope

17:49 it's kind of like locals() in Python

17:50 (you can only use it inside a macro, it's an implicit macro argument)

17:52 powr-toc: _ato: interesting... why does (defmacro foo [] (let [f 1] (prn (keys &env)))) print nil?

17:52 as does (defmacro foo [] (let [f 1] (prn &env)))

17:53 chouser: &env is a map of the locals where the macro is *expanded*

17:53 powr-toc: ahh

17:53 wow... that's pretty crazy

17:53 what do you use it for?

17:54 _ato: black magic

17:54 or debugging

17:54 eg you could write a macro that prints out the value of all the locals and use it for debugging

17:55 chouser: I plan to use it to pass some config info from an out macro to an inner one

17:55 a_strange_guy: you could also write a macro pair

17:55 akin to loop/recur

17:55 where one has to be inside another

17:56 chouser: so two macros, defthing and foo, used something like (defthing This That (alpha [a] ...) (beta [b] ... (foo b)))

17:56 powr-toc: am I right in thinking it's the macro equivalent of a closure?

17:56 or of accessing a closure?

17:56 chouser: but I want 'foo' at macro-expand time to know that it's in the context of That

17:56 a_strange_guy: chouser: use a dynamic var instead

17:56 less crazy

17:57 chouser: but I want lexical scope, not dynamic

17:57 _ato: debug-repl was one of the first use-cases: http://github.com/GeorgeJahad/debug-repl/blob/master/src/alex_and_georges/debug_repl.clj

17:57 chouser: and I need it at macro-expand time

17:57 powr-toc: when did &env become a language feature?

17:57 is it documented?

17:57 Chousuke: when functions got metadata I think

17:59 powr-toc: so wait... let me get this straight... &env allows a macro to compile different code based upon the context of it's current closure?

18:00 a_strange_guy: you could do this already with macros + side-effects

18:00 but yes, you can get at the surrounding context

18:00 powr-toc: a_strange_guy: how do you mean?

18:00 _ato: it lets you get a list of all the bindings in the lexical scope where the macro is inserted

18:01 that's all. You could already capture variables etc, but you'd have to know what they were called beforehand. With &env you don't have to know, since you can list them

18:02 powr-toc: _ato: can you access the values of the bindings, or just the symbols the values will be bound to?

18:02 a_strange_guy: powr-toc: there are tales of evil stuff that people did with side-effecting macros

18:03 powr-toc: a_strange_guy: side effecting macros sound nasty... but I'm intreagued

18:03 _ato: powr-toc: all you need is the symbols (which is what the keys of &env are), then you can use 'resolve' on them to get at the values

18:04 a_strange_guy: they were used mostly for logging the uses of a macro

18:04 hiredman: does resolve work lexically?

18:05 _ato: err.. sorry not resolve.

18:05 hiredman: ,((fn [x] (resolve 'x)) 1)

18:05 clojurebot: nil

18:05 _ato: my brain isn't working this morning

18:05 you just eval them

18:05 you're in a macro

18:05 so return code to access them

18:05 and it'll be eval'ed

18:05 eg: (defmacro foo [] (symbol "x"))

18:06 (foo) will evaluate to the value of x in the lexical scope

18:06 a_strange_guy: yes

18:07 you cannot get at the 'resolved' vals at compile time

18:07 _ato: see for example the local-bindings macro at the top of this: http://github.com/GeorgeJahad/debug-repl/blob/master/src/alex_and_georges/debug_repl.clj

18:07 powr-toc: ahh of course... it's like the whole reason gensym exists

18:07 a_strange_guy: but you can emit forms that will

18:07 _ato: yeah, because they don't have values until run-time

18:07 chouser: I considered that -- my outer macro could make a note in some global environment, but I don't really see that as less magical

18:08 Chousuke: I tried to figure out the env stuff by creating a macro that calls itself in a let form if a certain local is not available :P

18:08 but I didn't quite get it working

18:11 a_strange_guy: clojurebot: paste

18:11 clojurebot: lisppaste8, url

18:13 hiredman: lisppaste8 is broken

18:13 :(

18:15 a_strange_guy: does anyone know a nice way to syntax-color clojure code for a presentation?

18:16 dakrone: a_strange_guy: use vim's :TOhtml option and embed that?

18:18 technomancy: a_strange_guy: I use htmlize and Emacs.

18:18 gist.github.com works too

18:19 actually, that might be hard to embed in a presentation

18:20 a_strange_guy: htmlize looks nice

18:20 powr-toc: a_strange_guy: yeah, it's pretty awesome...

18:20 a_strange_guy: I'll just need a color-theme that won't scare people

18:20 powr-toc: as is org-mode :-)

18:21 technomancy: actually I usually just give presentations straight out of emacs, so htmlize is unnecessary. =)

18:21 you probably want a high-contrast theme for presentations; blackboard might be good for that

18:21 powr-toc: pmade is pretty good...

18:22 a_strange_guy: gotta disable rainbow-paren mode ^^

18:22 too colorful

18:24 powr-toc: a_strange_guy: how's this? http://www.contextualdevelopment.com/articles/2008/project-planning

18:24 a_strange_guy: the colors translate well to clojure

18:29 * the-kenny really has to dig deeper into org-mode

18:30 powr-toc: the-kenny: org-mode is awesome :-)

18:30 the-kenny: powr-toc: I know, but I don't use it very much :(

18:30 fro0g: +1

18:30 the-kenny: And this project-planning stuff looks incredible

18:31 powr-toc: the-kenny: I don't think any org-moder uses it *enough* :-)

18:31 people keep finding new ways to use it more :-)

18:31 fro0g: you can say the same thing about emacs in general

18:31 the-kenny: Org-Mode is like Emacs - Your life isn't long enough to see all of it

18:34 powr-toc: I write my blog in org-mode: http://sourcesmouth.co.uk/

18:34 (only just kick started it again)

18:34 a_strange_guy: i'm stll amazed by emacs, or rather why it does not turn into a gigantic mess

18:35 powr-toc: a_strange_guy: I love Emacs, but when you customise it... it frequently does turn into a gigantic mess :-)

18:35 technomancy: who said it doesn't? =)

18:35 a_strange_guy: well but it still works *kinda*

18:38 technomancy: you maintain clojure-mode + swank-clojure, don't you?

18:40 would it be possible to syntax-color based on information from a live repl?

18:46 krumholt: i have a vector of functions and i want a value to be applied to the first then the result of that to the second and so on. is there a sequence function for that?

18:46 powr-toc: ->

18:47 well, it's a macro so it might be no good for you

18:47 krumholt: no i need a function

18:48 a_strange_guy: ,((apply comp [next next next]) '(1 2 3 4 5 6 7))

18:48 clojurebot: (4 5 6 7)

18:48 powr-toc: nice

18:50 krumholt: a_strange_guy, thanks

18:52 powr-toc: is there any reason why comp applies the functions right-to-left rather than left-to-right?

18:52 Chousuke: that's the traditional order of composition, isn't it?

18:52 a_strange_guy: i think because ((comp f g) x) == (f (g x))

18:53 powr-toc: a_strange_guy: yeah, was just thinking that

18:53 Chousuke: sometimes, you need to read code from right to left :P

18:54 powr-toc: true

18:54 Chousuke: hmm

18:55 ,((nth (iterate comp next) 5) [1 2 3 4 5 6 7 8])

18:55 clojurebot: (2 3 4 5 6 7 8)

18:55 Chousuke: ah, damn

18:55 foiled :P

18:56 I suppose I'd need reductions instead :/

18:57 ,((nth (iterate (partial comp next) next) 5) [1 2 3 4 5 6 7 8])

18:57 clojurebot: (7 8)

18:59 technomancy: a_strange_guy: "maintain" is probably too strong a word for my relationship with swank-clojure

18:59 * a_strange_guy wishes partial would have been abreviated

18:59 technomancy: but I'm the closest thing it's got to a maintainer, yes. =)

18:59 a_strange_guy: grabbing a list of core fns from a running process is altogether possible, yes

19:00 I think slime does that with CL for macro-indentation calculation

19:00 kwertii: the-kenny: hey, I'm getting the same "No matching method found: println for class swank.util.io.proxy$java.io.StringWriter$0" that you got at http://clojure-log.n01se.net/date/2010-01-01.html ... did you ever figure out what the problem was?

19:01 the-kenny: kwertii: Yes, my init-file where I set *print-limit* etc.

19:01 Looks like this breaks swank-clojure

19:01 Chousuke: I wonder what it would take to make swank-clojure up to date with recent SLIME versions

19:01 kwertii: the-kenny: ah.. er. I haven't set any of that.

19:02 Chousuke: but I can't even tell what changes broke it so ;P

19:02 the-kenny: kwertii: hm :/ I have no clue then

19:02 kwertii: the-kenny: when you stopped setting *print-limit*, it just worked again?

19:02 technomancy: Chousuke: I'm in favour of rewriting swank-clojure from the ground-up

19:02 or rather, convincing someone else to do it.

19:03 the-kenny: kwertii: It was print-limit and one or two other variables controlling the reader

19:03 But yes, after I stopped setting this stuff in my init-file, everything worked

19:04 kwertii: hmmm

19:05 Chousuke: technomancy: heh

19:07 technomancy: I just thought about familiarizing myself with the swank protocol, but I think I need to stop that before someone assumes I'm going to do something about the current situation :P

19:07 kwertii: swank-clojure is only 356 lines with comments.... probably wouldn't be much trouble for someone who already knows swank, right?

19:09 Chousuke: kwertii: hm, my copy of swank-clojure has well over a thousand lines :P

19:09 kwertii: are you only thinking of the elisp part of it?

19:10 kwertii: Chousuke: oh. yes. you mean the clojure end needs rewritten... :)

19:11 Chousuke: I'd rather not touch the elisp as I have no elisp skills

19:11 beyond what I can guess from surrounding code :P

19:11 technomancy: the clojure-specific elisp bits are just launcher functions

19:11 classpath calculations, etc. nothing complicated there.

19:13 Chousuke: but now I have to get some sleep

19:13 technomancy: actually if you use lein swank you don't need swank-clojure.el at all

19:14 Chousuke: I wonder if there's anything in current swank that could be salvaged

19:15 powr-toc: what's wrong with the current swank-clojure, other than the installation process?

19:15 technomancy: powr-toc: combination of three things

19:15 (0) it was written a long time ago, before atoms existed

19:15 (1) My First Clojure Project symptom

19:16 (2) no clear comments about if it's implemented this way in order to work around a non-obvious slime quirk, or just because

19:17 piccolino: I asked about this earlier, but I've spent the past few hours digging through the source code of clojure.test and my own, and I'm still stumped: http://gist.github.com/314071

19:18 I don't understand why as-test and latest-as-test behave differently in the test. Clearly the test output shows they evaluate to the same maps.

19:18 powr-toc: technomancy: well its pretty damn useful :-)

19:20 technomancy: powr-toc: yeah, it's a fairly common problem

19:21 powr-toc: RDoc in Ruby is the same way; very clearly My First Ruby Program, but it was so useful that it became an integral part of the toolchain

19:21 powr-toc: technomancy: what are your plans for leiningen?

19:22 technomancy: powr-toc: the only thing I want to add to core is multi-module builds and possibly the option to autogenerate shell wrappers for projects to ease deployment.

19:23 powr-toc: the rest is all plugins: code coverage/statistics, dependency graphs, things like that.

19:25 powr-toc: technomancy: I filed a feature request you didn't agree with... the ability to specify and manage custom classpaths

19:25 technomancy: oh right... did you have a patch for that?

19:25 powr-toc: (or rather I think you said you'd take a patch, but weren't interested yourself)

19:26 technomancy: I don't object to adding it if it's contributed; right.

19:26 powr-toc: haha no :-)

19:26 technomancy: I just think there's usually a better way to do it.

19:26 powr-toc: I just wondered if you had any ideas on how you might achieve it

19:26 i.e. how a patch might implement it

19:26 technomancy: powr-toc: you'd need to add it to eval-in-project in compile.clj

19:27 I think once you read through that function it would be pretty clear how to add it.

19:28 powr-toc: technomancy: but clojure's add-classpath is deprecated... I was wondering if clojure did anything funky with classloaders...

19:28 slyphon: how do you use the :as (insert-correct-noun-here) in the ns macro?

19:29 technomancy: powr-toc: definitely something funky with classloaders. =)

19:29 basically the whole project runs in a subclassloader that's isolated

19:30 so while you can't change leiningen's classpath, you can create a new nested environment over which you have The Power

19:31 bsteuber: slyphon: (:require foo.bar :as fb)

19:31 I guess - so. please correct me if it's wrong

19:31 powr-toc: technomancy: and that's specific to leiningen or clojure?

19:31 slyphon: ah

19:31 bsteuber: ok, thanks

19:32 technomancy: powr-toc: specific to lein; it uses a call to an ant API

19:33 powr-toc: it's the same way you build Clojure; the ant JVM doesn't know the clojure classpath before the VM boots

19:33 raek: (ns your-ns (:require [foo.bar :as db]))

19:33 slyphon: here are some useful examples: http://clojure.org/libs

19:34 slyphon: raek: oh, thank you

19:34 raek: (this was added to the site fairly recently)

19:39 powr-toc: technomancy: A different leiningen question... can you use it to do classical build process things? e.g. could I get it to move some files into a specific directory after compiling? that kinda stuff?

19:39 it's something that's not very clear from the docs

19:41 technomancy: powr-toc: yeah, that should be better-documented. in the latest release you can do things like (ns leiningen.mytask) (defn mytask [project] [do stuff...]) (ns user) (defproject ...)

19:41 so you can put custom tasks in project.clj if they don't merit their own plugins

19:42 powr-toc: cool

19:43 I'm not sure i've ever seen multiple ns declarations in a single clj file before

19:43 technomancy: it's a bad idea in the general case

19:44 powr-toc: presumably the semantics for that are... top-down... you're in that namespace until you hit a new ns declaration

19:44 i.e. kinda like what you do at the repl

19:54 nathanmarz: technomancy: if I define a custom task like how you described, is that just available as "lein mytask" from the command line?

19:58 technomancy: nathanmarz: should be

20:16 Crowbar7: So, being a noob I ws trying to test out myself clojurebot in an irc server and I'm having a ton of trouble getting a jar I build to run. is there something I'm missing about running this guy?

20:16 hiredman: possibly

20:17 what is the trouble you are having?

20:43 SirNick: How can I get exceptions to show filenames? They always say NO_SOURCE_FILE, even when compiled as far as I can tell

20:49 technomancy: SirNick: using swank-clojure? try C-c C-k to load your code.

20:50 SirNick: I was just trying to run it from the terminal

20:50 Crowbar7: hiredman: The problem is I can't open the jar because of a lack of a main.

20:51 Does clojurebot not have a main?

20:54 SirNick: Am I compiling things wrong? Or am I not supposed to compile?

21:07 chouser: SirNick: if you compile or load files using use, require, load, load-file, etc. you should get line numbers in your stack traces

21:08 only for things typed at the repl should you expect to see NO_SOURCE_FILE

21:08 SirNick: Yea I was expecting it to show there, but using clojure.stacktrace seems to be working. Thank you

22:54 hiredman: Crowbar7: right, clojurebot does not have a main, it runs via a script you write, example is hiredman/clojurebot.clj

23:02 Crowbar7: hiredman: ahh

23:03 I really like clojurebot. the code anyways. I started writing my own bot then found clojurebot. I'm still writing my own, but seeing how you set it up was really nice.

23:14 chouser: what's the rule of thumb for performance cut-off between (condp = ...) and (case ...) ?

23:37 cemerick: chouser: probably when the number of clauses is > 1, prefer case, no?

23:39 I mean, even if case's constant-time dispatch is ever-so-slightly slower overall for small N, it seems that constant-time guarantees are always preferable to over-thinking the issue. :-)

Logging service provided by n01se.net