#clojure log - Aug 04 2010

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

0:00 rhudson: There are over 500 symbols defined in core; it's hard to work them all into conversation

0:07 pdk: you can work them into song then

0:09 lancepantz: hah, we learned this dumb song in high school to memorize all the capitals in south america

0:09 maybe we can make something like that

0:13 rhudson: http://www.youtube.com/watch?v=lhilwBnniBk

0:14 (Tom Lehrer's Elements song)

0:25 technomancy: clojurebot: package.el is part of Emacs now: http://repo.or.cz/w/emacs.git/blob_plain/HEAD:/lisp/emacs-lisp/package.el

0:25 clojurebot: 'Sea, mhuise.

0:25 technomancy: hiredman: how do you set a term to be an alias for another?

0:26 notsonerdysunny: user> (let [a [1 2 3 4 5]]

0:26 (amap a idx ret (inc (ret idx))))

0:26 I get unable to find method aclone for this .. can anybody help me to resolve this?

0:27 technomancy: notsonerdysunny: it's not clear what you're trying to do.

0:28 notsonerdysunny: I just want to learn to use amap

0:29 technomancy: amap is for working with Java arrays, which are not the same as clojure vectors.

0:29 notsonerdysunny: oh ic

0:29 technomancy: ,(map inc [1 2 3 4 5]) ; regular map works with vectors.

0:29 clojurebot: (2 3 4 5 6)

0:30 notsonerdysunny: yea I know the one you just said

0:30 but I didn't realize amap works only for java-arrays

0:30 is there a common convention followed for functions that work only for java-structures

0:31 technomancy: the common convention is that they are all listed on http://clojure.org/java_interop =)

0:32 notsonerdysunny: :) thanks

0:32 technomancy: you can always tell when something is a Java method because it starts with a . and uses camelCase: (.isDirectory (java.io.File. "/"))

0:32 but there aren't enough clojure functions designed to work with java data structures to merit a convention like that

0:33 notsonerdysunny: oh ic

0:33 I really like your leiningen tool .. its awesome ... thanks for such a great tool...

0:33 technomancy: glad it's useful.

0:41 notsonerdysunny: I just find accessing the elements of n-dimensional clunky .. would you have a suggestion for this .. currently i try something like (-> myarray (nth index1) (nth index2))

0:41 would you have a better suggestion

0:42 *n-dimensional vector

0:44 tomoj: -> (get-in [[0 1] [2 3]] [1 0])

0:44 sexpbot: => 2

0:48 notsonerdysunny: thanks tomoj

0:52 pdk: (doc filter)

0:52 clojurebot: "([pred coll]); Returns a lazy sequence of the items in coll for which (pred item) returns true. pred must be free of side-effects."

0:52 pdk: (doc get-in)

0:52 clojurebot: "([m ks] [m ks not-found]); Returns the value in a nested associative structure, where ks is a sequence of ke(ys. Returns nil if the key is not present, or the not-found value if supplied."

0:56 pdk: (doc mapcat)

0:56 clojurebot: "([f & colls]); Returns the result of applying concat to the result of applying map to f and colls. Thus function f should return a collection."

0:57 pdk: (doc repeat)

0:57 clojurebot: "([x] [n x]); Returns a lazy (infinite!, or length n if supplied) sequence of xs."

1:02 pdk: (list :test)

1:02 ,(list :test)

1:02 clojurebot: (:test)

1:22 dsop: hmm (read-lines "foo") works but (take 10 (read-lines "foo")) doesnt..

1:23 arg my bad

1:41 tomoj: careful with read-lines

1:41 (take 10 (read-lines "foo")) will leave the stream open if the file has more than 10 lines

1:57 pdk: (doc cons)

1:57 clojurebot: "([x seq]); Returns a new seq where x is the first element and seq is the rest."

1:58 pdk: ,((1))

1:58 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

1:58 pdk: ,'((1))

1:58 clojurebot: ((1))

1:59 pdk: ,'((1 2))

1:59 clojurebot: ((1 2))

2:01 pdk: ,(list '(1 2))

2:01 clojurebot: ((1 2))

2:11 daaku: anyone know of a library to make dealing with temporary directories easier? (like cleaning up after itself)

2:31 seems awesome and terrible at the same time: (.getAbsolutePath (doto (java.io.File/createTempFile "tmp" (str (System/nanoTime))) (.delete)))

2:40 tomoj: why use nanoTime?

2:41 daaku: tomoj: because that's what the stackoverflow post used in the java example :)

2:41 is it expensive?

2:41 tomoj: I'd expect it to be very cheap

2:41 just seems strange

2:42 daaku: tomoj: i agree, nuked it

2:43 bobo_: only reason i have ever read about using nanoTime, is that currentTimemilis doesnt always have a 1ms resolution, so can give inacurate numbers when benchmarking

2:43 tomoj: I mean, it seems strange to stick a time in there at all

2:44 since createTempFile already ensures uniqueness

2:44 daaku: yeah, it's just prefix/suffix

2:44 bobo_: yes indeed, that makes it realy weird.

2:44 daaku: but oddly it requires a minimum number of characters (in the prefix anyways)

2:46 anyone have recommendations for reading/video for clojure "patterns"? i've gotten a bunch of basics down, but still struggling with the mindset

2:53 Bahman: Hi all!

2:55 bobo_: daaku: not sure its entierly what you wanted, but the sicp lectures are great, and the book. its not clojure, but lisp

2:56 daaku: bobo_: are you talking about these: http://groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures/ ?

2:56 bobo_: well, yes. there is a newer version somewhere i belive though

2:57 although i realy like that version aswell. its abit of humor to watch computer science from the 80:s

2:58 daaku: heh

3:00 bobo_: i think i saw solutions to all the assignments from the book written in clojure on github aswell

3:01 daaku: i found these: http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-001-structure-and-interpretation-of-computer-programs-spring-2005/video-lectures/ -- but i'm not sure if they're newer since the other one's are only via torrent

3:02 cool, i'll look for that on github

3:02 i think i came across those at some point

3:02 thanks bobo_, you gave me more than enough material :)

3:06 bobo_: :-)

3:27 raek: daaku: as for pattern, I've been looking for some material on that too. one thing that seems to come up repeatedly, is to divide the program into a functional layer, which only operates on immutable data and produces new immutable data, and a "state" layer, where you model how the entities of your program interacts and change over time using clojure's concurrency primitives (var/atom/ref/agent)

3:33 daaku: I also recommend the Programming Clojure book by Stuart Halloway, where he not only give a great overview of the language, but also writes about ways of designing programs

3:53 zmila: (type :>)

3:53 ,(type :>)

3:53 clojurebot: clojure.lang.Keyword

4:05 esj: (map greet #clojure)

4:10 LauJensen: (-> "jse" reverse greet)

4:10 Welcome to Geekville! :)

4:13 esj: lol

4:13 jave: hello

4:13 esj: so youve turned me into the johannesburg stock exchange.

4:13 not sure how i feel about that

4:13 jave: does lein support downloading source jars from clojar?

4:14 esj: no idea, don't use it

4:14 tomoj: what is a "source jar"?

4:15 jave: well, a bundling of the source for a project

4:15 in maven

4:15 tomoj: oh

4:15 jave: since lein is aparently maven based I thought it might be possible

4:15 tomoj: the clojure jars on clojars all have the clj source files anyway

4:15 jave: ah

4:16 thats better

4:16 esj: :)

4:16 jave: I would like to have something like the jumpt-to-tag functions in emacs work for lein projects

4:16 lpetit: (str "hello, " (apply str (interpose ", " clojurians)) "!")

4:17 tomoj: jave: it already does

4:17 LauJensen: tomoj: not the aot compiled ones

4:17 esj: oh dear, what have i done....

4:17 tomoj: LauJensen: huh?

4:17 LauJensen: they dont pack the source

4:17 tomoj: how did they make those?

4:18 LauJensen: I dont know with lein, but for the previous version of cql, I built it with Clojuresque, which at that time defaults to AOT

4:18 jave: so, for aot compiled jars, its the same as for plain java jars then? you would need a src jar?

4:18 tomoj: e.g. won't `lein jar` include both the AOT and the clj sources?

4:19 LauJensen: tomoj: yes it will, compiles first then zips

4:19 s/zips/'zips'/

4:19 sexpbot: tomoj: yes it will, compiles first then 'zips'

4:20 tomoj: ok, well, M-. will work for _almost_ every jar on clojars, anyway

4:21 jave: thats very nice, ill try it out

4:21 LauJensen: tomoj: yea it should

4:22 jave: is there any interest in integrating more with the emacs 24 functionality?

4:22 tomoj: like what?

4:22 jave: like publishing on elpa.gnu.org, hooking into semantic

4:24 tomoj: publishing clojure things on elpa?

4:24 jave: I'm not so familiar with slime yet, so I'm just asking dumb questions

4:25 tomoj: if there is anything new coming for clojuremacsers from emacs 24, I think it would come through slime

4:25 bozhidar: well, there is ongoing work

4:25 no make clojure support part of SLIME central

4:25 which would be nice

4:26 jave: well, to have slime published on elpa.gnu.org, copyright would have to be asigned to fsf I believe

4:26 bozhidar: but Emacs 24 won't feature by itself anything of particular value to clojure developers

4:26 jave: no but it could

4:26 bozhidar: maybe clojure-mode will be promoted to emacs proper, but other than that I doubt anything related will be included

4:28 jave: no, it just has to be licensed under a GPL compatible license

4:29 jave: the elpa.gnu.org repos will probably have slightly different rules than the current elpa

4:29 afaik

4:29 it will be possible to hook in 3rd part repos though

4:30 bozhidar: maybe, but I don't think that would a particularly good idea

4:30 and I really hope they rework seriously elpa

4:30 before they include it

4:30 because in the moment it's mostly useless

4:30 jave: its already included

4:31 good idea or not, its a policy decision

4:31 bozhidar: having it in the bzr repo and releasing it are two different things :-)

4:31 a package manager that cannot track package updates...

4:31 jave: well, granted

4:32 bozhidar: to me the most important planned feature is concurrency support

4:32 jave: it will be interesting

4:32 I have an imagemagick branch I hope wil lbe merged

4:33 and the embeddeb widget thing, but that is a long way of merging

4:33 bozhidar: yes, any gtk improvements are welcome as well

4:33 the dvcs enhancements seems promising as well

4:34 I'm currently using magit, but if Emacs offered something nice built-in I'd probably would have used it

4:35 jave: maybe you could offer an email for the dev list which magit features should be replicated in vc

4:35 I have a tendency to jump out to the shell

4:35 Derander: I use the shell because I already know how git works there

4:36 jave: same here

4:36 Derander: does magit actually add any features?

4:36 raek: aren't most clojure jars source-only? (since AOT'ed code is -- in worst case -- only compatible with the clojure version it was built with)

4:36 bozhidar: Derander: it cannot add features, but it makes some things more pleasant to use

4:37 I personally like a lot the staging/unstaging in magit

4:37 diff's are also nicer

4:37 when I'm in Emacs I really hate to exit it to do stuff...

4:38 jave: maybe the concurency support wil render eshell more usable, itd integrate better with emacs

4:38 bozhidar: granted, I'm not magit expert it seems to me it implements a fair amount of git features

4:38 Slant: Link to the best way to get a clojure environment up on my box?

4:38 (surprised this isn't in the topic)

4:40 bozhidar: Slant: IDE/Emacs/Vi(m)?

4:40 Slant: Vim.

4:40 bozhidar: the "best" way is quite subjective you know :-)

4:40 sec

4:40 Slant: Determined to make that uphill fight.

4:41 I do know that emacs is the most common way to write lisp.

4:41 bozhidar: Slant: http://kotka.de/projects/clojure/vimclojure.html

4:41 Slant: But, screw it, worth an attempt. :-)

4:41 bozhidar, thanks.

4:41 bozhidar: Slant: you're welcome

4:42 Slant: Should I be pulling down the straight clojure jar, or playing with leningen?

4:45 bozhidar: Slant: lein is highly recommended

4:45 if you'll be building projects, that is

4:46 Slant: I will be building projects. :-D

4:46 bozhidar: maven has a clojure plugin

4:47 which offer similar stuff

4:47 and maven 3 has even native clojure support

4:47 via the polyglot subproject

4:47 Slant: I have zero experience with the Java ecosystem. This is all exploratory. :-)

4:47 I'm familiar with the fact that Maven is a Java build tool.

4:48 That's about it. ;-)

4:48 jave: yesterday I noticed something odd in the conjure tutorial. it was something like: (hiccup/h (:text "lala")). that didnt work but didnt produce an error. (hiccup/h "lala") worked, but (hiccup/h :text "lala") didnt. what am I missing?

4:53 hoeck: jave: if hiccup/h is a plain function, then calling (hiccup/h (:text "lala")) will evaluate to (hiccup/h nil), and in clojure, (str nil) is the empty string

4:54 ,(:foo "bar")

4:54 clojurebot: nil

4:54 jave: hoeck: so its a typo then?

4:55 but why doe (:foo "bar") evaluate to anytjing?

4:55 raek: ,(get "bar" :foo)

4:55 clojurebot: nil

4:55 raek: ,(get "bar" 0)

4:55 clojurebot: \b

4:56 raek: :foo is not a key of "bar"

4:56 "bar" has keys 0, 1 and 2

4:56 get returns nil if the key is not present

4:56 hoeck: jave: probably yes

4:56 jave: uhm I sort of dimly see it now. its not like in elisp or so

4:57 raek: (:key m) does (get m :key)

4:57 jave: I see.


5:01 lpetit: ,(:foo {})

5:01 clojurebot: nil

5:01 lpetit: ,(:foo "")

5:01 clojurebot: nil

5:02 lpetit: ,(doc get)

5:02 clojurebot: "([map key] [map key not-found]); Returns the value mapped to key, not-found or nil if key not present."

5:05 raek: ,(:foo {} :not-found) ; hrm, can one do this?

5:05 clojurebot: :not-found

5:06 raek: apparently!

5:18 AWizzArd: Can someone please try this: (.exec (Runtime/getRuntime) "program") where "program" is any application. And then you kill the JVM that started this Process. Is now "program" still running or was it killed too? On Windows I tried it with notepad which is not killed.

5:18 I would like to start the process in such a way that it is dependend on my JVM.

5:18 bozhidar: I doubt that this is possible

5:19 after all the process is running

5:19 outside the JVM...

5:19 you could add a shutdown hook

5:19 to the jvm that kill the process

5:20 I'm not sure if the hook will get executed if you interrupt the jvm, though

5:20 AWizzArd: It depends on how I kill the jvm.

5:20 sigterm seems to be caught by the shutdown hook, while a hard kill isn't.

5:22 bozhidar: yes, this is natural

5:22 most likely the jvm implements some signal handlers

5:23 but you cannot handle a SIG_KILL for instance

5:23 :-)

5:37 notsonerdysunny: (doc ns)

5:37 clojurebot: "([name docstring? attr-map? references*]); Sets *ns* to the namespace named by name (unevaluated), creating it if needed. references can be zero or more of: (:refer-clojure ...) (:require ...) (:use ...) (:import ...) (:load ...) (:gen-class) with the syntax of refer-clojure/require/use/import/load/gen-class respectively, except the arguments are unevaluated and need not be quoted. (:gen-class ...), when supplied, default

5:42 defn: ,(:foo {:foo "bar"} :not-found)

5:42 clojurebot: "bar"

5:42 defn: ,(:foo {:bar "bar"} :not-found)

5:42 clojurebot: :not-found

5:42 defn: raek: oooh, cool. thanks

5:45 lpetit: ,(:foo nil :nf)

5:45 clojurebot: :nf

5:46 lpetit: ,(get nil :nf)

5:46 clojurebot: nil

5:46 lpetit: ,(get nil :foo :nf)

5:46 clojurebot: :nf

5:46 defn: heh

5:55 notsonerdysunny: google code search still does not have clojure!!!!

5:56 defn: notsonerdysunny: http://getclojure.org:8080/examples/concat

5:56 notsonerdysunny: i dont know how helpful that will be, but it sort of works for finding examples of code

5:57 replace concat with the function you're looking for

5:58 and click the code to see the result

5:58 noidi: also check out clojuredocs.org

5:59 oops, looks like he left..

6:04 LauJensen: defn: still a good tip, hadn't seen getclojure:8080 before

6:05 defn: LauJensen: I really need to get back on developing it

6:05 I sort of hit a brick wall and now I feel sort of overwhelmed by my own code

6:05 I am having trouble breaking it out into separate functionality

6:05 LauJensen: ouch - Dont hear of a lot of Clojure devs going through that

6:06 defn: i dont like how it is basically a long core.clj

6:07 splitting it out i think has mainly been part of a lack of knowledge about using use and require

6:07 LauJensen: oh - I haven't seen the code, how long is core?

6:07 defn: a few hundred lines

6:08 250

6:08 LauJensen: k, thats not bad. Perhaps you need to add a few abstractions, keep them in core and move the rest out into some backend logic namespace(s)

6:08 defn: i guess it's not that big, but there are things lumped in -- i wish i could just make core.clj the bones and then have functionality split out

6:08 yeah LauJensen i was just thinking that as i wrote that last line

6:09 my abstractions just aren't strong enough i suppose

6:10 esj: You must become like the Cheshire Cat - you need to work on your dissolving powers ;P

6:10 defn: :)

6:11 "Can you stand on your head?"

6:11 xkb: In java I use interfaces quite often to introduce abstractions; how would you do it in Clojure?

6:11 LauJensen: defn: think in terms of DSL then, which fns best describes the work being done.

6:11 defn: LauJensen: good advice

6:11 * defn writes that down

6:11 LauJensen: xkb: In this case Im only thinking of some descriptive fns

6:13 esj: xkb: Protocols and Datatypes are the closest thing I'd suggest.

6:13 xkb: ah interesting

6:14 you quite quickly run into this, when developing something "larger"

6:14 esj: yes, I've recently learnt that its a good place to start

6:15 notsonerdysunny: defn .. My irc client crashed .. can you repost the link?

6:16 xkb: ohhh defprotocol is really nice indeed

6:17 raek: clojure seems to make a diffrence between things that do stuff and things that are just data

6:18 notsonerdysunny: defn .. I found it on the clojure-logs .. nice set of examples...

6:18 raek: the "interface" of the data often is something like "x is a map with key :y, which is a sequence of y-things"

6:19 but the interface of doer-stuff is more similar to classic OO

6:30 LauJensen: raek: typically called 'dumb code', the getters and setters which we free from

6:30 (i mean, free from having to write)

6:30 xkb: hehe

6:31 ususally interface don't have getters and setters hopefully ;)

6:32 LauJensen: hehe, true, not the interface. I meant the typical doer-stuff in OO

6:32 esj: xkb: or you run screaming !

6:32 xkb: that's missing a 's

6:32 Right now I'm writing an agregator for several bookservices like LibraryThing

6:32 and an interface for querying any book service at all would be useful :)

6:33 so that other people in the future can add new book services like amazon or whatever

6:42 jave: xkb: sounds interesting

6:42 I'm working on a family library system

6:42 xkb: ah interesting!

6:42 I started with librarything as a source for books

6:43 they have a very easy API

6:43 And I map it to a very simple datastructure, store that in BigTable

6:44 jave: cool

6:44 I'm not storing only books, but also a lot of different media

6:44 xkb: In the future I want to implement several mapping/corelation algorithms

6:44 jave: aha, like DVD's n stuff?

6:45 jave: I will be interested to have a look at your system when you have something

6:45 I'm storing dvd rips, comics, books, photos, games etc

6:46 music of course also

6:46 xkb: jave: my/our system will be open source, it'll be on google code eventually

6:47 jave: cool mine also if I will ever something that is not completely lame

6:47 xkb: hehe

6:47 I know the problem, at the start so much keeps changing

6:47 and it's quite hackisch

6:47 jave: atm is mostly a plain fs interface

6:48 my aim is to use xattr for tag storage, indexed by maybe virtuoso, and implement some clojure stuff to query it

6:49 basically I just want a wiki were pages are virtual in the sense that they are created from media entries

7:53 bortreb: what's the best way to do optional keyword arguments for a function?

7:53 Chousuke: in 1.2, use the new destructuring syntax

7:55 bortreb: so do I end up calling it like (foo 5 :option 6) or (foo 5 {:option 6}) ??

7:56 (foo 5 {:option 6}) looks kinda ugly to me

7:56 danielfm: bortreb: there's an example here: http://github.com/clojure/clojure/blob/1.2.x/changes.txt

7:57 Chousuke: bortreb: the former

7:58 if you need to do it in 1.1, you can do it manually using let in the function.

8:01 bortreb: thanks for the example!

8:06 hmmmm

8:09 but what if I want to accept an arbitray number of strings followed by optional keyword modifiers? is that possible? something like (shell-command "ls" "-a" "-h" :dir (file-str "/")) is what i'm trying to write.

8:10 danielfm: bortreb: then your function signature would be something like (defn foo [str1 str2 strN & {:keys [a b c]}] ...)

8:11 i guess :)

8:12 bortreb: but it needs to have an arbitray number of strings at the start..... I guess there's no real good way for clojure to know where the strings end and the keywords begin...

8:14 rhudson: Right. You can look at the source of clojure.java.shell/sh, which takes just such an arg list.

8:14 danielfm: bortreb: as a last resort you could have a function (defn foo [& opts] ...) and inside you just (apply hashmap opts) and parse the stuff you get

8:15 bortreb: oh, nevermind.. it wont work with that abitrary strings thing

8:15 rhudson: It calls a parse-args local function, which uses (split-with string? args) to find the split

8:15 bortreb: I want to do

8:15 (defn gggv ([{:keys [dir]} & commands]) ([& commands]) )

8:15 but clojure won't let me :(

8:17 LauJensen: bortreb: {:keys} lets you destructure a map (singular), with '& commands' you're saying that you'll be accepting multiple maps

8:18 ,(let [{:keys [dir]} {:dir 1 :dor 2}] dir)

8:18 clojurebot: 1

8:18 LauJensen: for multiple maps, you might want to go with something like

8:18 ,(map :dir '({:dir 1 :dor 2} {:dir 2 :dor 3}))

8:18 clojurebot: (1 2)

8:18 LauJensen: As I suspect you'll want to do some work with the data

8:20 bortreb: ooh the split-with string? is a really good idea

8:20 that's just what I need; thanks.

8:23 Bahman: Hi all!

8:25 LauJensen: Bahman: Hey

8:25 Bahman: Yo LauJensen!

8:34 AWizzArd: bozhidar: The solution to my previous challenge is http://yajsw.sourceforge.net/

8:35 bozhidar: AWizzArd: that's yet another project name that I hate ;-)

8:36 wasn't there something like jservice?

8:37 AWizzArd: There are several of those, but yajsw looks really nice

8:38 bozhidar: yes, I've browsed through the features and they look impressive

8:38 the use of groovy in the implementation is refreshing as wel

8:39 s/wel/well/

8:39 sexpbot: the use of groovy in the implementation is refreshing as well

8:39 bozhidar: good bot :-)

8:47 AWizzArd: yes, very nice feature set - seems you can make your Clojure app within 3 hours into a service, which runs on Win, Linux, OSX with auto-start, restart, etc.

8:49 raek: hrm, is EPL + LGPL possible?

8:49 saml: hey, write json transformation library for me . something like xsl for xml. but for json.

8:49 i'll come back in an hour. this is high priority for business

8:49 raek: should be alright, right?

8:50 Kaali: raek: IIRC EPL and LGPL are not compatible

8:50 saml: i don't know. licenses are hard. write a program that asks you questions and give you license suggestions

8:51 cemerick: saml: I think you've confused #clojure with rentacoder ;-)

8:51 Kaali: But if the code you release are all under EPL, and just use LGPL libraries, that might be fine.

8:52 cemerick: raek: I think it depends on the direction of the dependencies.

8:52 raek: direction?

8:52 cemerick: yeah, if you're releasing an EPL project that depends on LGPL libs vs. an LGPL project that depends on EPL libs

8:52 raek: can I combine LGPL'ed code and EPL'ed into one program?

8:52 ah, the license of the resulting prograM

8:53 cemerick: right

8:53 Kaali: According to http://www.gnu.org/licenses/license-list.html, EPL is not compatible with GPL.

8:53 cemerick: I try to stay away from anything *GPL, just because even LGPL is slightly murky for any commercial redistribution.

8:54 raek: Kaali: yes, but the LGPL s less restrictive

8:54 gregh: yet more murky. :)

8:54 raek: GPL does not want to be linked with other licenses

8:54 Kaali: raek: But just for library use, which is not really well defined.

8:55 Most people I know interpret LGPL as code that can be dynamically linked to your software, even if it's proprietary.

8:55 cemerick: raek: there's no bsd or EPL or CDDL equivalent lib?

8:55 raek: I just looked at the yajsw page

8:55 just wanted to check whether it would be usable in a EPL'ed program

8:57 Kaali: Using it as an library is in the gray area, but the purpoted use (I guess), but just don't combine the code to be a bit more on the safe side.

8:57 raek: there's http://commons.apache.org/daemon/ also, which has the Apache license

8:57 cemerick: That's what tomcat uses, to good effect. *shrug*

8:58 raek: I hope that using the documented api of a library is "library use"

8:58 I would not add features to yajsw itself

9:00 someone should make a license compability graph

9:00 that includes more than just any<->gpl

9:00 gregh: I don't think you can represent that in three dimensions

9:00 AWizzArd: Yes, only that the apache daemon requires a few hundred man hours of work to match the feature set

9:01 teesh: Hi, I am just starting off with clojure... trying to parse a XML file using lazy-xml and getting a classcast exception when using with the pull parser.

9:01 AWizzArd: http://en.wikipedia.org/wiki/GNU_Lesser_General_Public_License#Differences_from_the_GPL

9:02 teesh: These are my deps from lein:[org.clojure/clojure "1.2.0-master-SNAPSHOT"]

9:02 [org.clojure/clojure-contrib "1.2.0-SNAPSHOT"]

9:02 [xpp3/xpp3 "1.1.4c"]

9:02 [xpp3/xpp3_xpath "1.1.4c"]

9:03 AWizzArd: From the wikipedia entry I see it as: if we use yajsw (lgpl) in our proprietary Clojure programs, then this should be fine.

9:03 raek: yeah, my thought too

9:04 AWizzArd: We are not changing the sources that ship with yajsw and use those.

9:04 We only use what came in the .jar file, without modifying it.

9:04 Kaali: Just remember to use it as a library, not as source files.

9:04 teesh: Is this the correct place to ask for help on clojure-contrib exceptions?

9:04 Kaali: (not a lawyer)

9:05 raek: teesh: yes, I think so

9:06 it would be helpful to know what exception was thrown and what its message was

9:06 i.e. which class could be casted to what class?

9:07 teesh: I am getting a classcastexception from clojure.contrib.lazy_xml$parse_seq_pull.invoke(with_pull.clj:55)

9:07 AWizzArd: Btw, anyone here using a fresh Contrib? If so, can you please test: (do (require 'clojure.contrib.io) (clojure.contrib.io/append-writer "/xyz.txt"))

9:09 teesh: AWizzard: I am getting a Cannot change an open stream to append mode. [Thrown class java.lang.Exception]

9:09 AWizzArd: exactly

9:09 teesh: Awizzard: mine is org.clojure/clojure-contrib "1.2.0-SNAPSHOT"

9:10 AWizzArd: The cause of this in my (a few weeks old) clojure-contrib.jar from http://build.clojure.org/ is that there is a binding problem.

9:11 A function binds *append* to false and can pass every assert, but then returns a BufferedOutputWriter or something similar. This moves out of an inner binding into one in which *append* is set to true and does the assertion test again, which then fails.

9:11 teesh: how old is your clojure-contrib.jar?

9:13 teesh: teesh: yesterday

9:13 Awizzard: yesterday

9:16 AWizzArd: good, then I will create a ticket for that

9:47 teesh: hi Can someone please help with a classcastexception in lazy-xml (from contrib) when using with xmlpull parser?

9:54 raek: teesh: what does the exception say?

9:56 ,(first 1)

9:56 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer

9:57 raek: ,(+ "a")

9:57 clojurebot: java.lang.ClassCastException

9:57 dnolen: teesh: might be helpful if you paste the code and the stacktrace

9:57 raek: anyway, it should say somewhere what classes it tried to cast from and to

10:22 pdk: (doc do)

10:22 clojurebot: Pardon?

10:22 pdk: ,(do 1 2)

10:22 clojurebot: 2

10:29 pdk: ,'(list 1 (+ 1 2))

10:29 clojurebot: (list 1 (+ 1 2))

10:30 pdk: ,'(list 1 ,(+ 1 2))

10:30 clojurebot: (list 1 (+ 1 2))

10:30 pdk: ,`(list 1 ,(+ 1 2))

10:30 clojurebot: (clojure.core/list 1 (clojure.core/+ 1 2))

10:30 pdk: errgh

10:30 raek: ,`(list 1 ~(+ 1 2))

10:30 clojurebot: (clojure.core/list 1 3)

10:30 pdk: !

10:30 avast ye

10:30 raek: comma is whitespace in clojure... :)

10:31 pdk: ,{:ain't :that, :the :truth}

10:31 clojurebot: java.lang.RuntimeException: java.lang.ArrayIndexOutOfBoundsException: 5

10:31 pdk: god damn it clojurebot dont ruin my jokes

10:42 teesh: ok...finally got a full stacktrace:

10:42 Caused by: java.lang.ClassCastException: null

10:42 at java.lang.Class.cast (Class.java:2990)

10:42 clojure.lang.Reflector.boxArg (Reflector.java:364)

10:42 clojure.lang.Reflector.boxArgs (Reflector.java:397)

10:42 clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:55)

10:42 clojure.lang.Reflector.invokeInstanceMethod (Reflector.java:28)

10:42 clojure.contrib.lazy_xml$parse_seq_pull.invoke (with_pull.clj:55)

10:42 clojure.contrib.lazy_xml$parse_seq.invoke (lazy_xml.clj:49)

10:42 clojure.contrib.lazy_xml$parse_trim.invoke (lazy_xml.clj:109)

10:42 user$zip_file.invoke (NO_SOURCE_FILE:8)

10:42 clojure.lang.AFn.applyToHelper (AFn.java:163)

10:43 This is the exception http://clojure.pastebin.com/hS5bevyz for my code http://clojure.pastebin.com/ik3u2CHz

10:44 can some please help?

10:44 *can someone please help?

10:44 raek: the topmost line seems to be missing...

10:45 * raek takes a look into parse-seq-pull

10:45 teesh: raek: I have update the stack trace http://clojure.pastebin.com/2piL692M

10:49 raek: teesh: what happens if you do a (load "lazy_xml/with_pull") ?

10:50 or maybe (load "clojure/contrib/lazy_xml/with_pull")

10:51 teesh: raek: the first errored the second worked

10:51 raek: ko

10:51 *ok

10:52 the exception originates from here: http://github.com/clojure/clojure-contrib/blob/master/src/main/clojure/clojure/contrib/lazy_xml/with_pull.clj#L55

10:52 I don't know anything about xpp

10:52 teesh: raek: yes, I saw that :) but could not figure out beyond that

10:53 raek: but I guess the .setInput method takes an arg of a type that the object that was passed was not

10:54 teesh: raek: I am a newbie to clojure, if I understand L55 correctly it calls setInput on the newPullParser created using XmlPullParserFactory/newInstance?

10:54 raek: something like that

10:55 it calls factory.newPullParser()

10:55 what do you pass as input to the parser?

10:56 it looks like it accepts a java.io.Reader

10:56 teesh: its a file

10:56 raek: a File ?

10:56 teesh: oh.. ok

10:56 got it I think

10:56 raek: you can use clojure.java.io/reader to get a reader easily

11:04 LauJensen: just a note, Enlive makes (non-namespace requiring) xml parsing a breeze

11:06 for instance, here's 2 small functions which rip an entire wordpress blog into clojure data: http://github.com/LauJensen/bestinclass.dk/blob/master/src/bestinclass/wordpress.clj#L36

11:09 raek: I saw you blog post on that... very interesting!

11:10 is enlive a template library for XML/HTML?

11:10 or what is its main purpose?

11:29 pdk: ,(`(~(+ 1 2) 4))

11:29 clojurebot: java.lang.ClassCastException: clojure.lang.Cons cannot be cast to clojure.lang.IFn

11:30 pdk: ,`((~(+ 1 2) 4))

11:30 clojurebot: ((3 4))

11:32 LauJensen: raek: I missed your question due to a netsplit. Enlive is 2 things. CSS selectors which you can apply on (malformed) HTML, and templates/snippets which you can use to transform html (sorta like a better version of Pure). Enlive Templates have generated every single page on bestinclass.dk, enlive selectors has pulled out all the data from the old wordpress based site

11:33 raek: ah, ok

11:33 it uses tagsoup, right? it's an awesome lib

11:33 LauJensen: thats right

11:33 raek: I will certainly use enlive next time I need to scrape some HTML

11:34 LauJensen: yea its the best in the world for that I think

11:34 raek: there are such neat libs for everything in clojure...

11:35 LauJensen: true

11:44 teesh: raek: thanks for your help - I have solved my problem:

11:45 raek: to be able to make an irc bot that prints the titles for urls in less that 10 lines of code is simply amazing...

11:45 teesh: np.

11:46 teesh: this is my working code

11:46 http://clojure.pastebin.com/88eqT7yc

11:47 pdk: ,(partition nil)

11:47 clojurebot: java.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$partition

11:48 pdk: what library are you using for irc interface in clojure

11:52 dsop: how do I count how many iterations in a doseq already happened?

11:53 pdk: (doc doseq)

11:53 clojurebot: "([seq-exprs & body]); Repeatedly executes body (presumably for side-effects) with bindings and filtering as provided by \"for\". Does not retain the head of the sequence. Returns nil."

11:53 pdk: (doseq [i [:x :y :z] counter (range 3)] (prn (str i counter)))

11:53 ,(doseq [i [:x :y :z] counter (range 3)] (prn (str i counter)))

11:53 clojurebot: ":x0" ":x1" ":x2" ":y0" ":y1" ":y2" ":z0" ":z1" ":z2"

11:53 pdk: umm

11:54 guess it nests each seq-expr there

12:02 nipra: ,(for [x [:a :b :c] y [0 1 2]] [x y])

12:02 clojurebot: ([:a 0] [:a 1] [:a 2] [:b 0] [:b 1] [:b 2] [:c 0] [:c 1] [:c 2])

12:02 pdk: guess that nests too

12:02 nipra: pdk, like `for'

12:02 pdk: (doc for)

12:02 clojurebot: "([seq-exprs body-expr]); List comprehension. Takes a vector of one or more binding-form/collection-expr pairs, each followed by zero or more modifiers, and yields a lazy sequence of evaluations of expr. Collections are iterated in a nested fashion, rightmost fastest, and nested coll-exprs can refer to bindings created in prior binding-forms. Supported modifiers are: :let [binding-form expr ...], :while test, :when test. (

12:03 opqdonut: ,(map vector [:a :b :c] [0 1 2])

12:03 clojurebot: ([:a 0] [:b 1] [:c 2])

12:03 pdk: simplest way i can think of is turning your doseq loop into a recursive function to iterate over the list and adding a counter as an extra argument to it that you keep track of

12:03 raek: pdk: irclj

12:04 pdk: not to be confused with ircle

12:04 raek: pdk: http://raek.se/trattern.clj <-- my micro-bot

12:04 half of the code is for the cond-re macro

12:24 defn: ooo, neato

12:25 i wonder if there is support for an admin function yet

12:25 I wrote something that checks your nick before executing xyz

12:25 Bahman: Hi all!

12:27 Raynes: defn: ? :o

12:29 defn: Raynes: i was just wondering if you made some auth system for bot admins

12:30 Raynes: I believe we talked about that a while back. It wouldn't be hard to add a makeshift admin system similar to sexpbot's (sexpbot has a horrible privileges system -- you're either an admin or you aren't), but it feels like that is something that should probably be worked out by the user.

12:30 Privilege systems can be very specialized.

12:30 But a simple admin vs not-admin system would be easy to throw in.

12:41 hippondog: What is a "form"?

12:46 kencausey: hippondog: form n. 1. any object meant to be evaluated. 2. a symbol, a compound form, or a self-evaluating object. 3. (for an operator, as in ``<<operator>> form'') a compound form having that operator as its first element. ``A quote form is a constant form.''

12:46 from http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_f.htm

12:47 clojure is not of course Common Lisp, but I'm certain the meaning is the same

12:47 except perhaps defintion 3

12:48 hippondog: hmm.

12:55 slyrus_: I seem to be having trouble with protocol methods with optional arguments. I have to define (foo [arg1] ...) and (foo [arg1 & more-args]) in order to call the 1-arg form.

12:55 is that expected?

12:58 Drakeson: is there global variable like *in*, *out* that shows the environment variables? (I want to use binding on it)

12:59 rhudson: Drakeson, try (System/getenv)

13:00 Drakeson: rhudson: (binding [(System/getenv) {}] do-stuff) would not work.

13:02 rhudson: There's a clojure.java.shell/with-sh-env, but that's only for shells. Not sure there's a way to override the current process's env

13:03 slyrus_: is it possible that protocol methods don't support & args?

13:05 raek: slyrus_: yes, protocols methods cannot be variadic, afaik

13:05 slyrus_: Oh, bummer.

13:06 raek: ok, maybe not "variadic", but having a & parameter

13:06 you can still have multiple arities, of course

13:14 slyrus_: it would be nice if defprotocol would bounce arglists with & them then

13:19 and while I'm griping... Why doesn't print return the value of the thing it's printing? a macro to do same is trivial enough, but I'm used to print returning the thing it's printing (not the printed form of said thing, of course)

13:24 raek: I don't know about the rationale about that. maybe it's that way to make the side-effect more explicit or something. also, you wouldn't need a macro for that

13:24 (defn trace-value [x] (do (println x) x))

13:27 Kaali: ,(print-str "foo")

13:27 clojurebot: "foo"

13:28 Kaali: Quite common to separate string and stream output.

14:14 TakeV: Is 1.2 about to be released? I noticed that the github repo hasn't been updated in about five days.

14:16 LauJensen: TakeV: They keep saying 'soon'

14:19 TakeV: LauJensen: Ah, cool.

14:20 LauJensen: We'll see

14:26 pdk: takev expect to see it come out in a bundle pack with dnf at a retailer near you

14:37 scottj: I have a lot of functions that return static pages for compojure and I'd like them to execute during development so if I change a subfunction the ones that use it get updated, but during production it seems that they should just execute once. Has anyone done this? Did you use something like memcached or something at the clojure level?

14:41 LauJensen: scottj: Depending on how far in the process you are I can let you in on a pro tip. If you build your website using Moustache for routing and Enlive for templating, you can separate all of your page generation into a namespace of its own. Then when you define your routes do it like so (app (wrap-reload '[some.ns.with.templates]) "welcome" handler ...), that way, if you save an html or clj file affected a view, it will be updated during

14:41 development.

14:42 I cant advice for Compojure in its current state, but theres a #compojure channel (which is a little more tahn half dead) and then a pretty active google group where I will recommend you to post the question

14:49 scottj: well, compojure uses ring too. are your static pages strings or functions? If functions, I don't see how what you mention keeps them from executing on every request

14:50 LauJensen: Enlive uses statemachines internally

14:51 And yes, the wrap-reload is a ring middleware, so you can use that as well

14:53 TakeV: pdk: I'm afraid I don't know what "dnf" is.

14:53 rhickey: got homemade IPersistentMaps? please try latest rev on github. Fixing record equiality meant introducing a MapEquivalence marker class - you must implement in order to be = to maps (APersistentMap does this)

14:54 pdk: http://en.wikipedia.org/wiki/Duke_nukem_forever now you do

14:54 TakeV: pdk: Ah, yes...

14:56 LauJensen: rhickey: Does that means this will be false from here on out? (= {:a 5 :b 10} {:b 10 :a 5})

14:56 TakeV: (let [coll [1 1]] (identical? (nth coll 0) (nth coll 1)))

14:56 ,(let [coll [1 1]] (identical? (nth coll 0) (nth coll 1)))

14:56 clojurebot: true

14:56 rhickey: LauJensen: why would it?

14:57 LauJensen: rhickey: ah sorry I misread your sentence

14:57 TakeV: Wait, those both point to the same thing? Or am I missing something on how identical? works?

15:01 hoeck: ,(let [coll [200 200]] (identical? (nth coll 0) (nth coll 1)))

15:01 clojurebot: false

15:02 hoeck: TakeV: the jvm caches some small integers, in the range of -126 to 127 or so

15:02 qbg: rhickey: Nice!

15:04 TakeV: hoeck: Ah, I see. Thank you.

15:39 akhudek: is it possible to destructure metadata?

15:40 something like (let [[a b :meta m] (with-meta [a b] {:some-data 1})] m)

15:40 where m would be the metadata for the vector [a b]

15:41 LauJensen: AFAIK not in one go

15:41 (let [{:keys [metadata]} (meta (with-meta {:a 5} {:metadata 1}))] metadata)

15:44 akhudek: hm, ok. I have a few functions that break up a data structure while passing on metadata to sub-structures and being able to bind the metadata right in the function arguments would make them more concise.

15:45 guess I'll have to either live with it or refactor the code in some way

15:46 LauJensen: or make a new 'let'

16:03 AWizzArd: rhickey: do Records fall under "homemade IPersistentMaps"?

16:04 rhickey: AWizzArd: no

16:06 AWizzArd: rhickey: btw, would there be performance hits if binding would inherit lets behaviour and allow for sequential binding, so that (binding [x 1, y (inc x)] [x y]) ==> [1 2] ?

16:07 I am not suggesting to change the behaviour of binding, but I am curious why it binds its forms in parallel, unlike let.

16:08 rhickey: AWizzArd: I'm not particularly interested in enhancing binding

16:12 AWizzArd: I don't suggest to change/enhance is... I am just curious what led to your descision to give binding the behaviour that it now has vs. a similar one to let.

16:20 qbg: The way binding works makes its implementation simpler

16:22 AWizzArd: ok

16:23 qbg: Sequential bindings probably wouldn't be much better anyways

16:25 The difference would only be apparent if one value depended a previous one, which for dynamically bound variables sounds like madness to me...

16:26 AWizzArd: It's okay the way it is. I just was surprised when I saw that some bindings did not get the expected values. Today another workmate stumbled upon this.

16:29 LauJensen: AWizzArd: I think he's dodged that question for months now, I doubt you'll get an answer :)

16:52 patrkris: is there anyway, besides nailgun, that clojure programs could be made suitable for use as command line utillities? i'm thinking about the amount of time it takes for java to start, which is unacceptable in many cases I believe

16:54 qbg: What is wrong with nailgun?

16:55 patrkris: qbg: i can't think of a specific problem right now, but couldn't it turn out problematic that you need to have a server running?

16:55 lancepantz: patrkris: it's not possible without a persistent jvm running

16:56 the jruby guys all have the same complaint

16:56 qbg: Use a java machine ;)

16:56 patrkris: lancepantz: yeah, you're right - I've read that too

16:56 lancepantz: if you're looking for a scripting list, you may want to check out newlisp

16:56 patrkris: it seems that programs compiled for mono starts pretty damn quickly - perhaps when clojure-in-clojure is realized, it will be possible to target mono?

16:57 lancepantz: it's half retarded, but it starts up pretty quickly

16:57 patrkris: lancepantz: heh, half-retarded doesn't cut it :9

16:57 :)

16:57 qbg: The CLISP implementation of CL also starts up fast

16:58 rhudson: But if the script is implementing something that takes many seconds to run, the JVM startup isn't a deal killer

17:00 dnolen: patrkris: you might want to look at cake, it uses peristent vms, per project as well as a global one

17:00 patrkris: rhudson: right - and I've used clojure with success to write a few command-line utils, which was a pleasant experience

17:00 dnolen: thanks

17:01 technomancy: dalvik? ={

17:01 =)

17:01 patrkris: dnolen: sorry, do you have a link for cake?

17:01 lancepantz: http://github.com/ninjudd/cake

17:01 patrkris: thanks

17:02 lancepantz: patrkris: try sudo gem install cake

17:02 that is if you have ruby on your system

17:02 danlarkin: please please don't use cake

17:03 dnolen: technomancy: turns out my issue last night was a project.clj that was pre lein deps deps, eesh

17:03 danlarkin: why not?

17:06 drewr: the question is rather why *would* you use cake?

17:07 danlarkin: #1. the code is ugly #2. it is "compatible" with lein, which means, invariably, that there will be sliiight differences in how they handle project.clj which will be a _nightmare_ for everyone. #3. it's distributed as a rubygem? what?! #4. clojure does not need two functionally equivalent build tools

17:07 that was to dnolen, not drewr

17:08 drewr: and why would you want to persist jvm's across projects?

17:08 ninjudd: can't argue with that

17:10 lancepantz: 1) sorry, we're learning 2) we're making an effort to keep it compatible 3) it's easier for people to install 4) it's a dependency based task model, lein isn't

17:11 dnolen: danlarkin: I don't really see a problem with it. The persistent vm stuff solves integration with simpler editors.

17:11 ninjudd: drewr: the jvm isn't persistent across projects

17:11 dnolen: lein offers nothing there

17:11 qbg: Is there something like cake autotest for lein?

17:11 lancepantz: drewr: jvms do not persist across projects, i think you misunderstood something

17:11 qbg: not that i know of

17:12 drewr: I was responding to dnolen's "it uses peristent vms, per project as well as a global one"

17:13 technomancy: qbg: yeah, I think deview does that.

17:13 danlarkin: What does cake do that couldn't have been implemented as a patch (or plugin) to leiningen

17:13 dnolen: drewr: because you don't want to use swank

17:13 ninjudd: danlarkin: startup quickly

17:14 danlarkin: ninjudd: because of a persistent JVM? Why couldn't that be written as a lein plugin? In fact.. hasn't it been?

17:15 wires: are there any libraries on top of clojure that allow you to express and work with types? like in haskell?

17:15 ninjudd: danlarkin: not that i know of

17:15 dnolen: danlarkin: it also uses a fairly fancy socket, uses ruby cause bash scripting is teh suck, has very good symbol completion

17:15 none of which require you to install Emacs or and IDE

17:15 something a good chunk of the population doesn't care to do

17:16 * dnolen is still using lein and swank, but that's him, other people want to use other stuff

17:16 dnolen: get over it

17:16 danlarkin: I don't want to have an internet argument

17:16 that wasn't my intention

17:16 lancepantz: danlarkin: lein seems to be married to hooks to accomplish task dependencies, it's not a task dependency model

17:17 tomoj: danlarkin: there's a persistent jvm for lein? :D

17:17 technomancy: tomoj: lein interactive. it's like 25 LOC

17:17 lancepantz: we're not trying to fracture the community, but we just couldn't do what we wanted with lein

17:18 qbg: wires: There is http://clojure.github.com/clojure-contrib/types-api.html, but that may not be what you want

17:18 lancepantz: technomancy: lein interactive looks like it's restarting the ant project jvm everytime i run a a new task?

17:18 danlarkin: I don't have a problem with 2+ clojure build tools per se, I am just seeing a future where people have to write project.cljs in a crazy way because they want more than one build tool to be able to parse it

17:18 technomancy: lancepantz: right, but it's forking from a persistent JVM, so it's negligible time.

17:19 ninjudd: technomancy: not true

17:19 technomancy: well it depends on your project of course, but the overhead of the new JVM itself is trivial.

17:19 ninjudd: technomancy: dive into how the ant Java task starts the new JVM. it is starting an entirely new process

17:21 technomancy: meh. the point is it's fast.

17:21 wires: qbg: thanks, that's a start. i'm looking for something other that ADT though; e.g. define two functions and then get the type of a composed function, stuff like that- i'm not completely shure when I see a typesystem what it can express or not, i'm no expert

17:22 ninjudd: technomancy: we just timed it this morning, it took 5+ seconds for our project

17:23 qbg: wires: Heavy typing isn't very idiomatic clojure

17:24 danlarkin: regardless of how fast (or slow) the lein interactive mode starts up new tasks -- surely we agree that it /could/ be changed to be faster. It doesn't necessitate writing a new build tool (unless I'm missing the point)

17:24 tomoj: where is this "lein interactive"? having trouble googling

17:24 oh, in edge lein, I see

17:25 technomancy: danlarkin: how else will new developers get to appreciate the tenacity and thoroughness with which Debian has mangled the installation process of rubygems?

17:25 ninjudd: danlarkin: that's not why we wrote cake, it's just something we added after the fact

17:25 wires: qbg: yes. i'm not looking in particular for typing of clojure in general but i need to work with types themselves, or rather typed values.

17:26 danlarkin: ninjudd: I'm sorry if I'm coming off too interrogative, that isn't my intention at all.

17:26 why did you write cake though?

17:26 ninjudd: also, you don't have to use gem to install it, there are two other installation methods.

17:27 technomancy: ah, that's good.

17:27 ninjudd: the main reason we wrote it is because we wanted a dependency-based build tool

17:28 we wrote it before lein hooks came about, but i'm still of the opinion that dependency-based tasks are easier to use and more powerful than hooks

17:28 wires: qbg: in any case, thanks for the hint

17:29 ninjudd: i actually wrote the first version of cake as a proof of concept to show technomancy... to illustrate how i thought dependencies should be handled in lein

17:29 but he chose to go a different direction with hooks

17:31 dnolen: cake also has the most sane Clojure REPL at the moment

17:32 pdk: where's the homepage for cake

17:32 lancepantz: http://github.com/ninjudd/cake

17:33 tomoj: you think it's saner than slime, or do you mean standalone?

17:33 dnolen: tomoj: standalone

17:33 danlarkin: in what sense is it more sane than java -jar clojure.jar clojure.main?

17:34 tomoj: standalone completion does sound awesome, didn't know that existed

17:34 danlarkin: (serious question)

17:34 dnolen: danlarkin: you have to use it

17:34 clojure REPL has problems w/o jline, with jline you still have problems

17:34 lancepantz: danlarkin: readline support, tab completion, no startup times

17:34 danlarkin: oh, well I guess you don't need to specify a class with -jar, but you get the idea

17:34 patrkris: i'm not an expert in any of this, but what are the advantages of tasks over hooks in this case?

17:34 pdk: not 100% sure on what you mean by readline support but the startup delay for clojure on console is annoying

17:35 lancepantz: patrkris: http://martinfowler.com/articles/rake.html is a good primer

17:35 patrkris: thanks

17:36 danlarkin: didn't the author of rake come out and say that his dependency model was a bad idea, and if he had to do it over again he'd not do it again?

17:36 lancepantz: but the idea is that if you have 2 different tasks with the same dependency, A, and a 3rd task dependent on each of them, A would be ran twice

17:36 technomancy: ,(doc memoize)

17:36 clojurebot: "([f]); Returns a memoized version of a referentially transparent function. The memoized version of the function keeps a cache of the mapping from arguments to results and, when calls with the same arguments are repeated often, has higher performance at the expense of higher memory use."

17:37 lancepantz: danlarkin: possibly, but the same model exists in ant and maven

17:37 technomancy: danlarkin: that was the append-on-redefine behaviour specifically.

17:39 danlarkin: it's important to keep in mind, I think, that clojure is not ruby, and the JVM is dissimilar in a lot of ways to the VMs of scripting languages, and we shouldn't try to treat it as such

17:41 lancepantz: danlarkin: i don't follow, do you mean in reference to the repl or task dependencies?

17:42 danlarkin: I mean as a philosophy

17:42 lancepantz: i don't disagree

17:44 danlarkin: trying to get around JVM boot times smells to me like trying to shoehorn clojure into a role it isn't intended to fill. Why are you rebooting the JVM frequently? I hardly ever do, and when I do it's mostly because I did something stupid or need to change my classpath

17:44 dnolen: danlarkin: sure, but cake's persistent REPL you can always connect back always is arguable *more* Lispy , not less, like connect from many different terminals, again without futzing around with swank or slime

17:45 ninjudd: technomancy: do you have a link for that? i can't find anything about it on his blog (http://onestepback.org/)

17:45 technomancy: no, just discussions at seattle.rb

17:46 it's one of the main complaints about rake

17:46 lancepantz: danlarkin: that's probably a result of my not using clojure-test-mode in emacs, so i was had to wait for the jvm to boot to run my tests

17:47 drewr: you could have just run (run-tests)

17:48 lancepantz: so i should use lein but not its test task?

17:48 technomancy: forms starting with "def" generally mean "give this var a new value." places where it doesn't mean that (defmethod) often cause confusion.

17:48 lancepantz: or type that over and over in my swank repl?

17:48 technomancy: lancepantz: "lein test" is generally meant for sanity checks (on a clean JVM) right before you check in.

17:49 drewr: you can use `lein test` to run the whole suite in a repeatable manner, but don't use it for quick feedback

17:49 danlarkin: not to pick nits, but how is that different than typing "cake test" over and over

17:49 drewr: when you're in clojure world, just use functions

17:49 lancepantz: now i just start autotest and it watches for a touched file

17:49 drewr: your repl is already a command line

17:49 lancepantz: when a file is touched my tests are ran

17:49 i keep it open in a window on my second monitor

17:49 it's pretty cool

17:50 drewr: you're trying to bring ruby world to clojure world and worlds are colliding

17:50 lancepantz: apparently

17:51 i'm just trying to optimize my workflow, i don't think your suggestions do that

17:51 danlarkin: I do not intend this to come off as condescending, but I think you aren't understanding that there are better ways to do this in clojure

17:53 lancepantz: no its ok, i take no offense, i just don't understand what that better way is

17:53 danlarkin: yeah I just don't want this to devolve into internet argument time, which wouldn't help anyone. I'm glad we can keep it productive

17:54 drewr: lancepantz: I don't know your workflow, but off-hand I'd say write a function that loads your code, runs the tests, plays a golf-clap.wav, whatev

17:55 you could have it block, waiting for modifications to a file, and then call

17:55 danlarkin: so In Emacs Land™ we just use clojure-test-mode to run, tweak, run, tweak, all inside the same jvm (running through lein swank). If you don't want to use emacs I'm sure there's a similar workflow

17:57 Drakeson: Does clojure.main differentiate between loading foo.clj and running (as a script) foo.clj? How could foo.clj know which case it is, and behave accordingly?

17:57 technomancy: nobody's really taken charge of making nailgun integrate with lein; probably because the vimclojure author uses gradle.

17:58 ninjudd: i didn't realize the motto of the clojure community was: There's Only One Way to Do Things

18:00 dnolen: ninjudd: it's not, keep up the good work

18:02 danlarkin: regardless of the merit of this persistent jvm stuff (which I don't get, I guess, but I'm willing to concede), I am still worried about two build tools with different philosophies trying to use the same project description file (project.clj)

18:02 tomoj: Drakeson: what's the difference between loading foo.clj and running it as a script?

18:02 oh, I see what you're asking maybe

18:03 technomancy: Drakeson: no, still waiting for ticket #315 to get merged.

18:03 dnolen: danlarkin: having used both I haven't found this to be a problem in practice. Because I'm not usually building *other* people's projects. I'm just including them as deps. lein and cake work pretty much the same way there, that's a good thing.

18:03 danlarkin: dnolen: they work pretty much the same *today*

18:04 lancepantz: i can see it getting troublesome with the additions of tasks to project.clj, i do have some concerns there

18:04 danlarkin: they'll undoubtedly diverge, and then it's awful party for everybody

18:04 technomancy: danlarkin: polyglot maven has already gone down that road

18:04 danlarkin: and that was a huge mistake too

18:05 luckily that remains unreleased

18:05 ninjudd: i would encourage everyone to put their deftask calls in build.clj rather than project.clj

18:05 dnolen: danlarkin: projects that want to interoperate will use the compatible subset or provide different build files. or people will submit them.

18:05 lancepantz: tasks between the two projects are pretty unreconcilable though, so that problem is most likely going to exist anyways

18:06 danlarkin: "compatible subset" is a bad road to go down, imo

18:06 lancepantz: if people actually end up using cake, it may make sense to standardize task definitions between the two projects

18:06 Drakeson: technomancy: thanks, that's cool. what is holding it back?

18:06 technomancy: Drakeson: patches take a loooooong time to get applied.

18:06 I have learned this the hard way

18:06 lancepantz: but i'm honestly not sure people are going to use cake instead of lien

18:07 technomancy: even if the original author of the lib being patched says to apply it =(

18:07 Drakeson: technomancy: btw, could something be done about *env* ?

18:07 (binding [*env* {"PWD}

18:07 oops!

18:07 rhudson: Drakeson: basically the JVM doesn't support that.

18:07 Drakeson: as in, (binding [*env* {"PWD" "some/other/place"}] (do-stuff))

18:08 dnolen: lancepantz: TextMate people will I guarantee that

18:09 which means pretty much any Ruby shop that wants to integrate Clojure that doesn't use Emacs

18:09 danlarkin: lancepantz: when you make code public, people are probably going to use it. Being unsure about whether people will use your code is a bad reason to have that code potentially screw you in the future if you do

18:10 Drakeson: currently, I am working around that limitation in a most ugly way. (interning *env* and wrapping all my filesystem path calls in something that looks at (*env* "PWD"))

18:11 lancepantz: it's in sync with lein's project.clj now, if people use cake, i'll keep it in sync

18:11 Drakeson: as in, (spit (fs-path :home "some/place") stuff).

18:11 Can I intern something in clojure.core ?

18:12 technomancy: Drakeson: yes, but the correct question is "May I?"

18:13 Drakeson: oh, I just thought you might have already came up with a solution :D

18:13 danlarkin: lancepantz: I understand that you think you'll be able to keep them in sync, but what if they diverge incompatibly. Then it's a mess

18:14 lancepantz: so what is the solution?

18:14 danlarkin: don't share the same project description file between two build tools

18:14 ninjudd: lancepantz: i'm not so sure keeping them in sync is important, the point of being compatible is so that people who use lein now can try cake with minimal effort

18:15 your readme for your project should explain which build tool should be used for hacking your project

18:16 tomoj: maybe it would be better to provide something that generates a cake.clj (or whatever) from a project.clj

18:16 ?

18:16 ninjudd: if i am hacking on a project that uses lein, i will use lein. if i'm hacking on a project that uses cake, i'll use cake. other than that, it doesn't really matter

18:17 both push jars to clojars, like dnolen said, that is the important thing

18:18 lancepantz: i don't think thats a bad idea tomoj, but, i am a fan of being able to use either with no additional overhead

18:19 tomoj: your additional overhead is in the future when things go awry :)

18:19 lancepantz: lein seems to be pretty mature, and technomancy seems hesitant to do breaking changes, so i dont think it will be difficult to keep them in sync, i could very well end up being horribly wrong though

18:19 ninjudd: tomoj: that doesn't really solve the problem though. now users have to keep both project.clj and cake.clj in sync

18:20 tomoj: now users should just pick one and stick with it

18:20 similarly we can now either have a pom.xml, a project.clj, or try to keep them in sync

18:21 lancepantz: anyways, i have to get some work done, thanks for all the feedback

18:22 ninjudd: what about adding a key to you defproject, something like :lein version or :cake version? i'd be happy to print a warning if you try to run cake on a project.clj that explicitly specifies the lein version it depends on...

18:23 lancepantz: i'm sorry if we're doing something bad by fracturing the community, we built cake for ourselves inline with our philosophies- if we could have patched lein to achieve what we wanted, we would have

18:23 ninjudd: or i could just print a warning if you use an option that isn't supported

18:25 the way i see it, the more cool projects there are in clojure, the better. people should use what they like. competition is good for the community. if cake's purpose is to make lein better, then everyone benefits. but there is room for more than one build tool, and i'll never beg someone not to use lein

18:25 danlarkin: I don't doubt your intentions are pre

18:25 pure, rather

18:27 tomoj: I'd be happier if project.clj was a fallback for cake

18:28 if they're really in sync and as long as this is true, I guess it doesn't matter to me, though

18:33 ninjudd: tomoj: i just want people to be able make projects that work with both cake and lein if they want

18:34 tomoj: hmm

18:35 I get no output on `cake help`

18:36 ninjudd: tomoj: hmm, how did you install?

18:36 tomoj: gem install

18:37 lancepantz: what about cake version?

18:37 tomoj: seems like the project.clj's are already out of sync

18:37 lancepantz: lol

18:37 tomoj: if I add swank-clojure to my :dev-dependencies, then no output from `cake help`

18:37 otherwise, it's fine

18:37 0.3.4, btw

18:38 ninjudd: tomoj, do you mind sending me your project.clj so i can debug?

18:40 tomoj: or file an issue on github

18:41 tomoj: and now I'm swapping

18:41 wheee

18:41 too much cake

18:42 ninjudd: https://gist.github.com/e2477a167f2fb81b5660

18:42 that's the one I was trying to be evil

18:42 is :source-path respected?

18:44 ninjudd: tomoj: that project.clj seems to work for me

18:44 but i'm on 0.3.5-SNAPSHOT

18:45 tomoj: even this one https://gist.github.com/5d2895a87239adc019ef doesn't work for me on 0.3.4 :(

18:45 ninjudd: i'm installing 0.3.4 with gem now to test

18:47 tomoj: I'm installing from master to test :)

18:47 ninjudd: tomoj: yep, you're right. looks like a problem with the gem install

18:47 tomoj: I think somehow 0.3.4 spawned very many jvms

18:48 over 2GB of memory in jvms

18:48 ninjudd: how many different projects did you run it in?

18:48 tomoj: just one

18:50 ninjudd: ps x | grep cake | wc

18:50 tomoj: hmm, even on master I get no output sometimes from `cake help`

18:51 right now that's "5 71 2114", killed all the ones that were making me swap

18:52 ok, now it seems to be working

18:53 ninjudd: one is the grep... what is -Dcake.project for each of the others?

18:53 ps aux | grep cake

18:53 tomoj: but :source-path isn't respected, so the project.clj's are already out of sync

18:53 all the same

18:54 two for bake, two for cake

18:54 each (bake and cake) has an 'sh -c java ...' and a 'java ...'

18:54 ninjudd: ah, so only two JVMs

18:54 that's right

18:55 tomoj: yep

18:55 I killed the ones that were making me swap

18:55 maybe I wasn't waiting long enough for the servers to come up?

18:55 if I can repro again on master I'll let you know

18:55 ninjudd: ok, thanks

18:56 tomoj: clutch for example is incompatible with cake

18:56 ninjudd: the JVM should start up within 5 seconds

18:56 tomoj: but I guess :source-path is pretty uncommon

18:57 ninjudd: yeah, we chose to leave out customized source paths until someone requests them

18:58 tomoj: I took "compatible with leiningen project.clj" to mean "compatible with sample.project.clj"

18:58 technomancy: ninjudd: I delayed on that a long time too. =\

18:59 never did get a good reason as to why they should be supported.

18:59 ninjudd: technomancy: good for you ;)

18:59 tomoj: clutch uses it because they're using maven as well

18:59 technomancy: so customize it in pom.xml =)

18:59 tomoj: heh

19:01 got my `ps x | grep cake | wc -l` up to 15 by just running `cake help` over and over

19:04 ninjudd: hmm, what platform are you on?

19:04 just ran 'cake help' 100 times and i still only have 2 JVMS

19:05 tomoj: ubuntu 10.04

19:05 did you try it from scratch?

19:05 ninjudd: you mean in a new project?

19:05 tomoj: with no jvms already up, I mean

19:05 ninjudd: yes

19:05 tomoj: hmm

19:05 ninjudd: but in the same project

19:06 i'll log in to an ubuntu server and give it a try

19:06 i'm on OSX

19:06 tomoj: I'm guessing the first `cake help` somehow returns before the server is really up, so the second creates another

19:07 ninjudd: are you running them in the same shell?

19:07 tomoj: yeah

19:07 ninjudd: i bet you're right, the timeout may be too slow for your machine

19:08 it currently waits 10 seconds for the JVM to come up

19:08 tomoj: ah

19:09 yeah, netbook :(

19:15 ninjudd: tomoj: yeah, that is it, i lowered to timeout to 2 and reproduced the problem on my machine

19:15 tomoj: thanks for helping me figure it out!

19:16 tomoj: sure, don't want people swapping because of their build tool :)

19:17 lancepantz: tomoj: but that's part of our philosophy!

19:17 if your computer sucks, we're going to disk baby

19:17 bringing it down

19:47 Slant: I'm having an issue with my classpath, but I can't figure out how it's choking. http://quad.pastebin.com/UY6aBp1g

19:47 I'm do a lein run script/run.clj

19:48 http://quad.pastebin.com/mgEy9htE

19:48 That's the traceback.

19:48 It looks like a classpath issue.

19:48 But I don't see why it isn't picking up jetty.

19:49 I've done "lein deps"

20:10 tomoj: Slant: when you run with a filename, it doesn't use your classpath

20:11 try defining a function which starts the server instead of doing it in the toplevel in that file, and then use `lein run your-namespace your-function` instead, like the example at http://github.com/sids/lein-run

20:15 Slant: tomoj, using that method, then, do I have to put all scripts under src/ to be picked up?

20:16 tomoj: yeah, I guess so

20:16 seems like lein-run should be patched so that it loads the file in the project's jvm

21:48 pdk: (doc prof)

21:48 clojurebot: "clojure.contrib.profile/prof;[[name & body]]; If *enable-profiling* is true, wraps body in profiling code. Returns the result of body. Profile timings will be stored in *profile-data* using name, which must be a keyword, as the key. Timings are measured with System/nanoTime."

21:56 Raynes: ,(clojure-version)

21:56 clojurebot: "1.2.0-master-SNAPSHOT"

22:08 leimy: For clojure programming. Eclipse or Emacs?

22:08 * leimy likes SLIME for other lisp stuff, but I'm open to alternatives

22:08 Raynes: Emacs is awesome.

22:08 ninjudd: i'm partial to emacs

22:09 leimy: So I should get the clojure mode stuff and swank-clojure?

22:12 tomoj: if you already are comfortable with emacs, there's really no contest

22:12 leimy: that's what I figured

22:12 but I didn't use ELPA (I think that's what it's called) and I wanted to get swank-clojure working :-)

22:13 the docs seem to assume that's the only way to go.

22:13 tomoj: some instructions here http://github.com/technomancy/swank-clojure

22:13 oh

22:13 yeah, I don't know how to do it the non-ELPA way :(

22:13 leimy: heh

22:13 it's just that I have a lot of elisp I've already installed for myself here locally

22:13 and a nice .emacs.d structure

22:13 I don't want to throw it out for some packaged solution just yet :-)

22:14 tomoj: elpa won't mess that up

22:14 leimy: but I would if someone said ELPA kicks ass! :-)

22:14 Raynes: ELPA is the easiest way for Emacs beginners, and that is the priority.

22:14 tomoj: certainly doesn't kick ass

22:14 leimy: makes sense

22:14 tomoj: if you already have slime installed, I don't think the elpa way will work anyway

22:14 leimy: didn't think so. I do have slime

22:14 and it's hooked to SBCL

22:14 well via my configs it is.

22:15 tomoj: hmm

22:15 well, does it really even matter?

22:15 you don't need swank-clojure.el

22:15 leimy: If I want to do live interaction with the clojure REPL via slime I do don't I?

22:16 tomoj: just clojure-mode, which is easy to install, then try M-x slime-connect ing to a lein swank

22:16 leimy: ah

22:16 hmmm

22:16 tomoj: no, you don't

22:16 leimy: I guess I need a lein swank instance

22:16 tomoj: (at least.. with the ELPA way you don't. but I don't see why it shouldn't work with your own slime)

22:16 leimy: Isn't that a part of swank-clojure though?

22:17 tomoj: you need swank-clojure in your lein project's :dev-dependencies

22:17 you don't need any swank-clojure stuff in emacs though

22:17 leimy: See I'm really new to clojure... I don't even know about the project setup stuff yet.

22:17 so it seems I must learn clojure to learn to use clojure :-)

22:17 tomoj: http://github.com/technomancy/leiningen

22:17 really simple install

22:17 leimy: Cool

22:17 thanks for the help so far by the way!

22:18 tomoj: then you can `lein new fooproject` and edit your project.clj to look like https://gist.github.com/83edb6c1401297c39b53

22:18 `lein deps`, `lein swank`, and then M-x slime-connect

22:19 good luck

22:20 there's also cljr (http://github.com/liebke/cljr) for non-project-oriented work

22:20 (and it can also start swank servers)

22:22 leimy: Ah I've got a bit to learn about lein. This is really neat.

22:24 Slant: Does cljr support the same clojars that lein does?

22:24 Yes.

22:25 tomoj: afaik there is only one clojars

22:25 well, I guess you can run your own

22:56 technomancy: leimy: swank is pretty different in clj-land from CL since you can't alter the load-path at runtime, but the main difference you have to remember is just to use M-x slime-connect instead of M-x slime

22:56 as long as you've got that down you're clear for working on lein-based projects

23:01 so Clojure's reader doesn't honor non-breaking spaces

23:01 trying to decide if I should report that as a bug or just suck it up.

23:03 rhudson: Where/how were you trying to use a non-breaking space?

23:04 technomancy: oh man, I was afraid you were going to ask that.

23:04 * technomancy glances around nervously

23:05 technomancy: so here's the deal

23:05 rhudson: confession is good for the soul

23:05 technomancy: wine strips off quotes from its arguments. so when you say java -cp [...] clojure.main -e "(use 'leiningen.core)(-main)" it sees "(use" and "'leiningen.core)(-main)" as two separate args.

23:06 but bash doesn't treat non-breaking spaces as whitespace. so if I used one of those to separate the args, it would be treated as a single token.

23:06 and Clojure should be able to DTRT

23:06 but it doesn't. because it uses Character/isWhitespace, which is as old as the hills. and also stupid.

23:07 rhudson: nice try

23:07 technomancy: gruesome details: http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Character.html#isWhitespace(char)

23:07 it would have been super-slick if it had worked.

23:08 of course, if ticket #315 were applied it wouldn't be necessary. but that's been open since April. =(

23:08 rhudson: I saw a mention of that earlier today. How would I go look at that?

23:09 technomancy: ,ticket #315

23:09 clojurebot: java.lang.Exception: Unable to resolve symbol: ticket in this context

23:09 technomancy: ~ticket #315

23:09 clojurebot: {:url http://tinyurl.com/37u5rdb, :summary "Add support for running -main namespace from clojure.main without AOT", :status :test, :priority :normal, :created-on "2010-04-25T03:04:43+11:00"}

23:09 rhudson: Anyway, if you're trying to work around wine, couldn't you just as well use some non-whitespace character & replace it once you got into clojure?

23:09 technomancy: anyway, the patch is there ready to be applied; unless you've got commit rights there's not much you can do.

23:10 I could if I AOT'd a -main instead of using clojure.main, but I was trying to avoid that.

23:13 normally I don't complain about patches taking a long time to be applied, but in this case the patch was written by the author of clojure.main... taking someone's lib and putting it in your software and then refusing to apply their fixes is not so great. =\

23:14 rhudson: yow

23:22 technomancy: anyway, you should all explore the Unicode character plane in your free time; it's very rewarding.

23:23 rhudson: I've browsed it a lot; yeah, it's pretty fascinating

23:32 technomancy: ~ticket #419

23:32 clojurebot: {:url http://tinyurl.com/28ngbwe, :summary "LispReader uses Character.isWhitespace rather than Character.isSpaceChar", :status :new, :priority :lowest, :created-on "2010-08-04T22:31:13-05:00"}

23:32 technomancy: for better or worse.

23:55 Slant: The difference between :require and :use is the latter binds the variables in the loaded namespace into the current namespace, right?

23:55 Whereas in require, you have to refer to the referred.namespace/method ?

23:56 Raynes: Pretty much.

23:57 In require, you can use :as to create a qualifier. For example (in (ns ..)) (:require [referred.namespace :as rn]) and then you can use stuff in referred.namespace like so: rn/method

23:57 Slant: Gotcha.

23:57 Raynes: It also works outside of the ns form, of course (require '[referred.namespace :as rn])

Logging service provided by n01se.net