#clojure log - Mar 02 2010

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

0:29 bradbeveridge: is Java's ZipInputStream really slow, or am I using it wrong?

0:29 clojurebot: pastebin?

0:29 clojurebot: excusez-moi

0:31 bradbeveridge: http://clojure.pastebin.com/zR9di5K0

0:39 zaphar_ps: bradbeveridge: I've never tried to benchmark it so I don't know

0:39 bradbeveridge: ok, I was using it wrong

0:39 I thought getNextEntry would throw

0:39 it returns null, so I would have been sitting in an infinite loop for a while ;)

0:39 it has native like perf

0:40 zaphar_ps: heh

1:54 scottj: Anyone else get the error "Wrong number of arguments to task uberjar" when running "lein.bat uberjar" in Windows?

2:40 spariev: scottj: yep, I got this too, lein 1.1.0 seems to fix the problem - http://groups.google.com/group/leiningen/browse_thread/thread/a43ded3d659da915#

2:57 scottj: spariev: thanks

3:11 LauJensen: Morning crew

3:12 TheBusby: evening

3:21 spariev: Morning

3:27 vy: Isn't there an "if" in Clojure?

3:27 bsteuber: ,(doc if)

3:27 clojurebot: Excuse me?

3:28 vy: There is cond, if-not, if-let, but no if?

3:28 bsteuber: there is

3:28 at least it was there yesterday :)

3:28 TheBusby: ,(doc if)

3:28 clojurebot: Huh?

3:29 TheBusby: Please see http://clojure.org/special_forms#if

3:29 bsteuber: ,(if 5 :true :false)

3:29 clojurebot: :true

3:29 danlei: it's a special form

3:39 ordnungswidrig: I think more idiomatic when, however

3:48 esj: wotcha

3:57 LauJensen: ordnungswidrig: huh ?

3:59 ordnungswidrig: LauJensen: hmm, I think I meant: "I think more ideomatic than 'if' is when"

4:03 LauJensen: I dont think they vary in levels of idiomacy, but if is for 2 bodies, when is for 1, different uses

4:15 esj: idiomacy, nice word.

4:19 ordnungswidrig: LauJensen: you're right.

4:28 a_strange_guy: hi there, could anyone help me with swank-clojure?

4:29 i want to use it without the swank-clojure.jar

4:31 bu i cannot configure my classpath so that it will find the (not compiled) source checkout

4:33 AWizzArd: Moin guys

4:33 a_strange_guy: moin moin

4:34 AWizzArd: You want to use the code files directly, but not the compiled .jar file.

4:34 a_strange_guy: correct

4:35 AWizzArd: And does the path of those source files show up in your (System/getProperty "java.class.path") ?

4:36 a_strange_guy: I tried (S/gP "j.c.p")

4:36 but no, the won't show up

4:36 only .jar's

4:40 AWizzArd: Then the CP needs to be set correctly.

4:41 For some reason the "/path/to/swank-clojure/" thing was not added.

4:43 a_strange_guy: swank-clojure-classpath = (append '("/opt/swank-clojure/src") (swank-clojure-default-classpath))

4:44 but when inferior lisp starts

4:44 there are only jars on the CP

4:45 AWizzArd: Then the append did not work as expected.

4:45 a_strange_guy: append works as expected

4:46 swank-clojure-classpath must be a list of strings

4:47 AWizzArd: in my (custom-set-variables ...) I have: '(swank-clojure-extra-classpaths '("/hg/clj/" "/hg/clj/config/" "/hg/lib/clj/swank-clojure/" "/hg/lib/clj/clojure-contrib/clojure-contrib.jar" ...))

4:50 a_strange_guy: same here

4:53 * a_strange_guy is reading swank-clojure.el

4:56 a_strange_guy: it seems to work now

4:57 AWizzArd: grats :)

4:57 a_strange_guy: looks like swank-clojure.el got scared ^^

4:57 AWizzArd: yay

7:08 eevar2: (doc slice)

7:08 clojurebot: Titim gan éirí ort.

7:18 eevar2: (doc partition)

7:18 clojurebot: "([n coll] [n step coll] [n step pad coll]); Returns a lazy sequence of lists of n items each, at offsets step apart. If step is not supplied, defaults to n, i.e. the partitions do not overlap. If a pad collection is supplied, use its elements as necessary to complete last partition upto n items. In case there are not enough padding elements, return a partition with less than n items."

7:31 nipra: Hi, I'm getting the error ``slime-goto-location-buffer: Search failed: " clojure/core.clj$"'' for slime-edit-definition for any clojure.core or contrib symbol. For other symbol (in some other ns) it's working fine.

7:41 powr-toc: nipra: does swank know where to find clojure?

7:43 nipra: powr-toc, yes. I'm using swank-clojure-project to fire up the repl.

7:45 powr-toc: nipra: I don't use that function, I find starting an external clojure program that starts swank, and then using M-x slime-connect works better... I find this gives you better control over the vm startup and classpath

7:45 whether this helps you or not is another matter :-\

7:47 It sounds like your clojure-src-root isn't being set properly though

7:48 nipra: powr-toc, earlier I was using emacs starter kit. It was working fine. It broke after my moved to my old setup.

7:48 bsteuber: nipra: I use swank-clojure-project with leiningen and finding source works fine

7:48 powr-toc: (check out clojure-mode.el file for info...) I set this by calling (clojure-slime-config "~/path/to/clojure") from my .emacs, but I've heard this method is deprecated...

7:50 bsteuber: I use lein too, but for the project I'm working on I have to be very careful with my classpath and classloaders, so starting clojure with a custom start script, and then connecting to it suits me better

7:51 bsteuber: then I guess this setup gives some classpath issue

7:52 so it can find the compiled code but not the clojure source

7:52 does that sound reasonable?

7:53 nipra: bsteuber, yes

7:54 bsteuber: so maybe check the clojure.jar you find in (get (System/getProperties) "java.class.path")

7:55 whether or not it includes the source

7:57 AWizzArd: Is there (in contrib) a tool to generate permutations?

8:02 Okay, clojure.contrib.combinatorics offers a fn “permutations”.

8:05 Leafw: AWizzArd: I have the impression that almost anything I'd want is buried somewhere in c.c

8:06 esj: if i define a function: (fn my-fn [& xs]) and then proceed to call it (apply fn some-giant-collection) I run the risk of blowing the stack right ?

8:06 Leafw: esj: why not map?

8:07 Isee, the args

8:07 sorry

8:07 Chousuke: esj: depends on what you do to the args

8:07 esj: how so ?

8:07 Chousuke: ,((fn [& args] (first args)) (iterate inc 1))

8:07 clojurebot: Eval-in-box threw an exception:java.lang.OutOfMemoryError: Java heap space

8:07 Chousuke: hm, opps

8:07 ,(apply (fn [& args] (first args)) (iterate inc 1))

8:07 clojurebot: 1

8:08 Chousuke: I meant to add that, of course :)

8:08 esj: hmm

8:08 Chousuke: so you can apply a function even on an infinite collection

8:08 esj: so the & binding doesn't break the laziness

8:08 wow

8:12 I guess my question directly is this: I am writing a library for time series. The CRUD functions currently expect collections, but I note that in clojure it is more idiomatic to have a multimethod a' la ([x]) and ([x & xs]) so am thinking about converting my code to that. However as my collections can potentially be pretty big, I'm worried about nasty effects.

8:12 For instance http://github.com/esj/esjtools/blob/master/src/esjtools/timeseries.clj line 82

8:13 am I just making up issues to worry about ?

8:13 AWizzArd: ,(apply + (range 1000000))

8:13 clojurebot: 499999500000

8:14 AWizzArd: esj: how giant is your coll?

8:14 It obviously fits into RAM...

8:14 esj: yeah

8:14 AWizzArd: you have 128 gb ram? ;)

8:14 esj: actually....

8:15 what I was concerned about was expanding the call beyond the call stack

8:15 but clearly that doesn't happen, which is nice.

8:15 AWizzArd: You can (apply fn coll-of-10-mio-objs)

8:16 esj: thanks.

8:16 AWizzArd: I am not sure, maybe ram is the only practical limit *shrugs*

8:18 esj: so the question now is, how exactly is the argument list created ?

8:18 RTFC time I guess

8:18 AWizzArd: What do you mean?

8:18 Is it not your code which creates the argument collection?

8:19 esj: i mean the function calling semantic in Clojure itself. In my mind when you call a function the PC and all the arguments get put on the call stack. Clearly this is not happening here.

8:20 or the apply example you gave above would try to put 1e6 vals on the stack, and it would overflow

8:21 instead Clojure hands you your answer, with a sly grin.

8:22 a_strange_guy: esj: there is no call stack beyond 20 args

8:22 rhickey: esj: but apply only takes as many args as you pass. If you pass a fn and one collection, that's 2 args

8:22 esj: ,(doc apply)

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

8:23 esj: mislead me to believing it was expanded out

8:23 a_strange_guy: apply passes a seq to the Fn

8:23 esj: aha - thanks gents. Now I understand.

8:24 a_strange_guy: and the Fn itself calls next &fist to pop the args of

8:24 rhickey: well, it goes to the meaning of & in arglists. Obviously variadics (+ in this case) are somewhat special

8:25 esj: gotcha

8:25 sorry, that could be misconstrued. I mean that I understand.

8:26 rhickey: if the compiler needs to form the collection matching & more, then it will have to evaluate what you have passed. But in the case of apply, you have already created the collection

8:27 chouser: apply accepts a seq on the end. fns using & accepts a seq on the end. 'apply' does the work of fixing up the point at which the input switches to a seq to match what the fn is expecting

8:27 rhickey: fns using & don't accept seq on end really

8:27 i.e. not via direct calling

8:28 esj: yeah

8:28 rhickey: but the logic of the function is in fact applied to a sequence

8:29 so & in arglist say - please form a sequence of any additional args passed, after evaluating them. apply short-circuits that

8:30 tricky part about apply is any intervening args between fn and argseq

8:32 a_strange_guy: why?, they seem just to be consed onto the seq

8:32 or will that go away?

8:33 rhickey: a_strange_guy: nothing's going away

9:12 * _fogus_ reading the Linux Journal interview with rhickey

9:12 rhickey: _fogus_: where is that?

9:13 _fogus_: rhickey: The print magazine

9:13 rhickey: ah

9:13 _fogus_: A co-worker just handed it to me

9:13 The logo gets center-stage on the cover

9:13 ohpauleez: yeah, I just read the write up

9:13 er, the synopsis of the issue

9:14 online

9:24 opqdonut: do C-M-{up,down} work for others in clojure-mode?

9:25 I tend to get "Containing expression ends prematurely" or "Unbalanced parentheses" around square brackets

9:36 chouser: somebody make me stop optimizing this! It's fine. I just need to stop.

9:36 * chouser tries just one more thing...

9:41 stuartsierra: heh

9:42 rhickey: chouser: I thought Clojure was too fast for you?

9:42 :)

9:43 chouser: shaddup ;-)

9:43 it's a bit addictive, moving things from runtime to compile time... O(n) to O(1)

9:44 hehe. user$eval__2146$eval$reify$reify__2188$eval$reify__2208$eval__2210$fn__2218

9:45 stuartsierra: blerg

9:45 Sooner or later we're going to have to do something about fn names.

9:45 * chouser chuckles maniacally to himslef

9:46 chouser: that's a fn generated by an eval called in the method of a reify from code eval'ed in a reify method...

9:46 stuartsierra: yikes

9:48 a_strange_guy: big question: ... WHY?!

9:48 Maddas: Not because it is easy, but because it is hard!

9:49 chouser: just a stack of stuff generated, usually at compile time, to make runtime access type-specific and fast.

10:00 djpowell: what's the story with binary compatability of aot compiled libs with different clojure releases? I know that there isn't any, but is this something that clojure should address at all, or do there need to be any recommendations for library authors or anything?

10:01 ordnungswidrig: Insn't there a limit on method name length in the jvm?

10:02 djpowell: 64k i think

10:02 that might lead to ugly stack traces though

10:04 eg - perhaps leiningen should have an option to re-aot compile namespaces of libs with the version of clojure that is in use

10:05 stuartsierra: djpowell: only recommendation re AOT is to avoid it unless necessary; not a great solution

10:06 djpowell: yeah - i noticed that compojure currently aot compiles all of its namespaces. i don't know whether it needs to or not

10:21 chouser: bah. that's *slower*. grrr.

10:22 stuartsierra: ha

10:27 chouser: oh, it was re-eval'ing each time. that's not right..

10:38 zmila: how to know what parameter type expects given function?

10:39 ,(doc file-seq)

10:39 clojurebot: "([dir]); A tree seq on java.io.Files"

10:39 zmila: what is "dir"?

10:40 stuartsierra: zmila: the argument to file-seq

10:40 zmila: i look into source, "dir" is "root" in tree-seq

10:41 chouser: the docstring could be a bit more specific.

10:41 ,(file-seq ".")

10:41 clojurebot: java.lang.ClassCastException: java.lang.String cannot be cast to java.io.File

10:41 chouser: there's a hint -- it wants a java.io.File

10:41 ,(file-seq (java.io.File. "."))

10:41 clojurebot: java.security.AccessControlException: access denied (java.io.FilePermission . read)

10:42 zmila: ho, thanx, it's File object

10:52 a_strange_guy: does anyone know what the #^ reader macro does exactly?

10:52 does it add or replace metadata to forms

10:52 Chousuke: hmm

10:52 a_strange_guy: seems to do that or the other sometimes

10:53 (meta (quote #^foo (+ 5 6)))

10:53 ,(meta (quote #^foo (+ 5 6)))

10:53 clojurebot: {:tag foo}

10:53 Chousuke: I don't think it matters, since forms can't have metadata before they're read :P

10:53 a_strange_guy: they have line numbers

10:53 Chousuke: that's added after reading

10:54 a_strange_guy: ,(meta (quote #^{:foo "bar"} #^foo (+ 5 6)))

10:54 clojurebot: {:foo "bar"}

10:54 chouser: heh. didn't know that was supported at all

10:54 I mean, that it worked. I'm pretty sure it's not "supported"

10:54 Chousuke: that's probably undefined behaviour, yes :P

10:55 a_strange_guy: i was just thinking because there are so many case with:

10:55 bobo_: any easy way to add a jar to slime/swank/emacs thingy? compojure.jar to be exact

10:56 a_strange_guy: #^{:macro true} or #^{:private true} etc.

10:56 that you could make #^:keyword == #^{:keyword true}

10:57 Chousuke: hm

10:57 that wouldn't be so bad.

10:57 a_strange_guy: then (def #^:private #^macro ..)

10:58 chouser: I think I'd prefer to have options elsewhere in the forms that need them

10:58 a_strange_guy: or even (def ^String ^:private)

10:59 came to my mind when looking at #^{:unsynchronized-mutable true}

10:59 Chousuke: that's verbose on purpose

10:59 so that you won't use it :P

10:59 chouser: (defn sillyquote {:macro true} [x] `'~x) ; works today

11:00 a_strange_guy: keywords seem already reserved but unused

11:00 ,(meta (quote #^:foo bar))

11:00 clojurebot: {:tag :foo}

11:03 technomancy: bobo_: place it in lib/ and do another M-x swank-clojure-project to restart your session

12:46 Clojure just passed CL to become the #19 on the github high score chart: http://github.com/languages/Clojure

12:46 bsteuber: any ideas about an exception "java.lang.String cannot be cast to clojure.lang.Named" when compiling a project with lein?

12:46 chouser: something is a string when it should be a keyword or symbol

12:47 bsteuber: ic - wasn't sure about what Named means

12:50 chouser: look for [N] here: http://tinyurl.com/clojure-classes ...because that's, you know, easy. :-P

12:50 it would be nice to have a way that lists everything currently known to implement X

12:51 bsteuber: wow - what a graph :)

12:51 Raynes: Yay!

12:51 arohner: chouser: is there a way to iterate through all known classes?

12:51 chouser: it's old and probably out of date, but a lot of it is still correct

12:51 bsteuber: the strange thing is that I don't even get a source file name in the exception

12:51 so I'm wondering if anything gets compiled at all

12:51 arohner: (filter #(contains? (ancestors %)) magic-class-list) should do it

12:52 chouser: arohner: not a good way. You could iterate through classes imported into a given namespace, or walk through .class files in a given .jar or directory. :-/

12:53 bsteuber: I think Java doesn't provide a nice way to list all classes of a package

12:53 stuartsierra: bsteuber: it doesn't provide any way at all

12:54 bsteuber: well, you can parse your classpath :)

12:54 browse

12:54 chouser: ,(filter #(instance? clojure.lang.Named %) (vals (ns-imports *ns*)))

12:54 clojurebot: ()

12:55 chouser: nope

12:55 ,(filter #(isa? % clojure.lang.Named) (vals (ns-imports *ns*)))

12:55 clojurebot: ()

12:55 chouser: ,(import [clojure.lang Symbol Keyword])

12:55 clojurebot: clojure.lang.Keyword

12:55 chouser: ,(filter #(isa? % clojure.lang.Named) (vals (ns-imports *ns*)))

12:55 clojurebot: (clojure.lang.Keyword clojure.lang.Symbol)

12:55 chouser: There! so as long as you know the answer ahead of time, you're all set.

12:55 arohner: ,(identity *ns*)

12:55 clojurebot: #<Namespace sandbox>

13:25 arohner: I have a question: I have some code that looks like (defn my-fn [] (sql/transaction (foo) (bar) (baz))) . I want the return value of the function to be the return value of (bar). Is there any way to do this with a let or anything else "normal"? Do I have to resort to e.g. an atom?

13:26 tomoj: is there not an official clojureql in clojars?

13:26 arohner: I don't understand

13:27 (defn my-fn [] (let [bar (bar)] (sql/transaction (foo) bar (baz)) bar))

13:27 arohner: tomoj: but then the call to (bar) happens outside the transaction. (bar) has to be called inside the transaction

13:28 danlei: arohner: if the order of execution of (foo) (bar) and (baz) is important, you can just do all three of them in a let, otherwise tomoj's solution will suffice

13:28 tomoj: oh, I see

13:29 arohner: so then I do (defn my-fn [] (transaction (let [foo (foo) bar (bar) baz (baz)] ???) bar)

13:29 but that last bar is outside my let block, because the let is inside the transaction

13:29 tomoj: so return bar from the let block?

13:30 arohner: ah, it does look like contrib.sql/transaction promises it returns the value of the last expression

13:30 thanks

13:39 dakrone: is there a more idiomatic way of doing this, ww is (["foo" 1], ["bar" 0], ["baz" 3]), I want {"foo" 1, "bar" 0, "baz" 3} : (reduce merge (map #(hash-map (first %) (second %)) ww)) ?

13:39 chouser: (into {} ww)

13:40 dakrone: ahahaha, that's much better :) thanks chouser

13:40 chouser: :-)

13:40 dakrone: lisp makes it very easy to make doing simple things very difficult

13:40 it's an amazingly-obfuscatable language

13:41 danlei: arohner: btw, (nitpicking) don't say "let-block", there is no such thing as a block, everyting is an expression

13:42 chouser: eh

13:43 hiredman: what is the diff?

13:54 danlei: hiredman: you mean the difference between a block and an expression?

13:57 hiredman: sure

13:57 does block have a formal definition?

13:58 http://en.wikipedia.org/wiki/Block_%28programming%29 <-- has a scheme example

13:58 stuartsierra: "any expression where the hanging indent doesn't line up with the first argument" ;)

13:58 danlei: well, in procedual languages, there usually is a distinction between statements, expressions and blocks (in C-like syntax stuff between { }). I don't think this distinction exists in Lisps and using that terminology might convey the impression, that there is such a difference in lisps.

13:58 hiredman: ok

14:05 Chousuke: I'm not sure if calling let expressions blocks is a bad thing

14:05 they can contain more than one expression

14:06 stuartsierra: Maybe anything with an implicit "do"

14:07 danlei: maybe not a bad thing per se, but it sounds a bit strange to me. surely one can use terms like "block of scope", but "block" like in {} doesn't fit in my opinion.

14:07 but it's just my opinion

14:08 And I haven't heard it used like this in a Lisp context before

14:08 "let block", hm ...

14:08 pretty sure that sounds strange to me

14:08 arohner: well, I'm the guy that also got flack for calling Ruby Dictionaries hash-maps

14:09 stuartsierra: Common Lisp talks about blocks, if I recall

14:09 Chousuke: common lisp actually has its own definition for a block :)

14:09 "block n. a named lexical exit point, established explicitly by block or implicitly by operators such as loop, do and prog, to which control and values may be transfered by using a return-from form with the name of the block."

14:09 stuartsierra: sheesh

14:09 Chousuke: not very well applicable to clojure

14:09 Raynes: Does it really matter?

14:10 Chousuke: well, as long as you don't talk about lisp statements it's fine :P

14:10 danlei: well, CL has features of imperative languages, like the "prog" feature and stuff. but ok, don't wanna argue about that. let's just say I think "let block" sounds strange.

14:12 Raynes: I think 'muffler' sounds strange, but my car still needs one.

14:17 danlei: It's not about the muffler, it's more akin to the question "is clojure for a loop"

14:17 but, enough about that.

14:18 stuartsierra: ~for

14:18 clojurebot: for is not a loop

14:18 wthidden: Has the java static method interop syntax changed in 1.2.0? I'm using class/static method interop and the interperter is confusing this with a

14:18 danlei: :)

14:18 wthidden: a namespace expression

14:18 chouser: wthidden: nope, hasn't changed

14:19 stuartsierra: wthidden: that usually means you haven't imported the class name

14:19 or you mistyped the class name

14:19 wthidden: hmm.. so (def dbconn (DBusConnection/getConnection 1)) should be valid, if DBusConnection is a valid class?

14:20 with static method getConnection of course.

14:20 chouser: if you've imported DBusConnection, yes

14:23 wthidden: hmm it seems my (:import '(org.freedesktop.dbus.DBusConnection)) form on my namespace was not "importing" as i expected....

14:25 stuartsierra: wthidden: replace the last . with a space

14:25 and remove the quote

14:26 danlei: I'm still wondering if the #:...{} representation of types will be made readable ... (throwing an error if the type is not defined)

14:26 wthidden: stuartsierra: yes.. i re-read the spec... quoting it is bad..

14:27 chouser: danlei: I think some mechanism for readable deftypes is planned, but I don't know if the syntax will be anything like what deftypes currently print

14:27 danlei: chouser: ok, thanks

14:27 stuartsierra: danlei: it opens a whole can of worms, though. literal objects, compile-time objects, ...

14:28 chouser: mmmm worms

14:28 wthidden: stuartsierra: hmmm if i replace the last '.' with a spec, i get a class loader error, but with the last '.' still there it does not complain.

14:28 *space

14:28 danlei: stuartsierra: maybe that's a naive question, but couldn't it be handled like [] or {}?

14:28 stuartsierra: danlei: Maybe, but the compiler knowns what the class of [] should be.

14:29 danlei: If the compiler encounters #:... or whatever, it has to create an instance of a totally unknown class.

14:29 Probably doable, just tricky.

14:29 danlei: stuartsierra: since the compiler in lisps is part of the language, is that a problem?

14:30 stuartsierra: dunno

14:30 danlei: I haven't thought through the implications, I'm just asking

14:32 Chousuke: you mean the reader. hm

14:34 danlei: reader sees #:Foo{:x 1} and calls (Foo 1), compiler compiles it like anything else?

14:35 Chousuke: something like that.

14:36 chouser: is there really no way to implement my own IKeywordLookup with deftype?

14:37 or even ILookup?

14:39 anyway, reify is fine, but using it to close over 3 values appears to take 60% longer than closing over 1 value.

14:39 rhickey_: (deftype T [] clojure.lang.ILookup (valAt [k] :foo))

14:39 (:fred (T))

14:39 danlei: is there javadoc online for the clojure classes and interfaces implemented in java?

14:42 chouser: rhickey_: ok, thanks. That works for me too, but I'm getting a java.lang.ClassFormatError: Duplicate interface name in my real code.

14:43 programble: hello all o/

14:43 i have a question:

14:45 say i have 2 sequences (right term?), and i want to create one sequence out of these

14:45 say

14:45 '(1 2 3)

14:45 and

14:45 '(3 4 5)

14:45 and i want '(1 2 3 3 4 5)

14:45 danlei: (into [1 2 3] [4 5])

14:45 programble: thanks

14:46 wait...

14:46 i actually have

14:47 chouser: oh, my deftype was macro-generated and I had (valAt ...). Using (~'valAt ...) fixes it.

14:47 programble: im trying to implement quicksort as a beginner exercise

14:47 so really i need

14:47 to create a sequence/list/whatever from a list, a number and another list

14:48 chouser: ,(concat [1 2 3] [4] [5 6 7])

14:48 clojurebot: (1 2 3 4 5 6 7)

14:48 programble: ah

15:02 dakrone: is there a (distinct ...) for hash-maps that filters by key? or should I just manually do it

15:02 hiredman: uh, what?

15:03 dakrone: something like (distinct {:a 1 :a 2}) -> {:a 1}

15:03 throw out all recurring keys

15:03 hiredman: hash maps can't have recuring keys

15:04 programble: lol

15:04 dakrone: ,(keys {:a 1 :a 2})

15:04 clojurebot: (:a :a)

15:04 hiredman: that is not a hash map

15:04 and it is operator error

15:05 array maps don't check for duplicate keys for performance reasons, but the behaviour of duplicate keys is undefined

15:05 Chousuke: ,(apply hash-map '(:a 1 :a 2))

15:05 clojurebot: {:a 2}

15:05 Chousuke: at least that works :)

15:05 dakrone: you're right, I was assuming (into {} ...) would put duplicates in, it doesn't

15:05 chouser: (into {} {:a 1 :a 2})

15:05 ,(into {} {:a 1 :a 2})

15:05 clojurebot: {:a 2}

15:06 dakrone: thanks

15:06 * hiredman has a patch that has the reader check for duplicate keys and throw an exception

15:07 dakrone: hiredman: if it threw an exception, would the preferred usage be to wrap (into ...) with a try/catch if we wanted it to remove duplicates?

15:08 hiredman: dakrone: don't use map literals with duplicate keys

15:09 unless you try hard, that is the only way to produce a map with duplicate keys

15:09 chouser: hiredman: does it check only at read time?

15:09 hiredman: wrapping in a try/catch would not catch the exception, because the reader would throw the exception

15:09 chouser: yes

15:09 it doesn't touch array map

15:09 chouser: ,{3 :a (+ 1 2) :b}

15:09 clojurebot: {3 :a, 3 :b}

15:10 hiredman: mm

15:10 that is unfortunate

15:10 dakrone: so, I have a list like (["bobby" 1/3] ["fire" 1/2] ["truck" 1] ["city" 1/2] ["truck" 1] ["state" 1/2] ["colorado" 1/3]) that I'm collapsing into a {}, how would I get around that then?

15:11 map (distinct? val) over all of it and filter it before?

15:11 hiredman: get around what?

15:11 chouser: what do you want it to do? does (into {} your-seq) not do what you want?

15:12 dakrone: duplicate keys, I thought you were saying it would throw an exception since there are 2 occurrences of the "truck" key?

15:12 kotarak: hiredman: chouser: comes from the fact, that the reader makes a map containing "3" and "(+ 1 2)" as keys. The + call is not evaluated by the reader.

15:12 dakrone: chouser: no, (into {} ..) works great, I'm trying to understand if hiredman's change would affect it

15:12 hiredman: kotarak: I think we both know that

15:13 chouser: dakrone: hiredman has a non-standard patch that throws exceptions. But it wouldn't throw in your case, and won't be applied to clojure anyway.

15:13 * kotarak ducks

15:13 chouser: dakrone: ie, you're safe.

15:13 hiredman: chouser: oh, your words are like razors to my wounded heart

15:13 rads: is there a way to get ring/compojure to auto reload files rails-style?

15:14 dakrone: chouser: okay, thanks for the clarification

15:14 chouser: hiredman: :-) sorry.

15:14 just being realistic here.

15:15 hiredman: clojurebot: ticket #87

15:15 clojurebot: {:url http://tinyurl.com/y92lmv8, :summary "GC Issue 83: PersistentArrayMap trust the reader (map literals) too much", :status :test, :priority :low, :created-on "2009-06-17T20:36:09Z"}

15:15 kotarak: rads: the reload-middleware delivered with ring?

15:15 hiredman: well, my patch also throws a nicer exception for {:a}

15:15 chouser: hiredman: oh yeah, I keep forgetting about that ticket.

15:15 hiredman: ,{:a}

15:15 clojurebot: java.lang.ArrayIndexOutOfBoundsException: 1

15:16 rads: kotarak: looks good, thanks

15:19 jasapp: who works at sentry data systems here?

15:20 chouser: jasapp: I do

15:20 jasapp: ahh, that's right.

15:20 I've got an interview with them tomorrow

15:20 chouser: jasapp: applying for a job?

15:21 excellent!

15:21 jasapp: I think I'm talking to Ben Mahan, and Cyrus Keck

15:22 roughly, how many developers do they employ?

15:23 programble: i cant get the clojure REPL to work with jline.

15:24 it gives me a ClassNotFound clojure.main

15:24 i am runnign the command java -cp ~/Stuff/clojure/jline-0_9_5.jar:~/Stuff/clojure/clojure-1.1.0/clojure.jar jline.ConsoleRunner clojure.main

15:25 chouser: jasapp: about 20 developers I think, not including technical analysts and other technical folk.

15:26 jasapp: interesting, that's good to know

15:27 chouser: programble: are you on a unix?

15:27 oh, you must be. your problem is with the ~, but I'd recommend just using rlwrap instead

15:27 programble: chouser: yes

15:27 ...

15:27 explain

15:28 chouser: java classpath doesn't support ~

15:28 programble: huh

15:28 it seems to support one ~ though

15:28 because

15:28 chouser: well, your shell is expanding the first one

15:28 programble: ah

15:28 so, whats rlwrap?

15:28 chouser: people seem to have better results with rlwrap though. it's a separate program.

15:29 rlwrap java -cp :~/Stuff/clojure/clojure-1.1.0/clojure.jar clojure.main

15:29 but skip that :

15:29 programble: k thanks

15:30 great, it works :)

15:30 clojurebot: twitteronia is where shaq lives

15:41 rads: is there a way to get ring's reload middleware to reload a namespace and all of it's child namespaces?

15:49 arohner: rads: you can use (require 'foo :reload-all) . That works in general, I don't know if it will work with ring

15:50 but I use it all the time on compojure

15:50 that reloads 'foo, and everything required in foo. It won't necessarily reload foo.bar unless foo requires foo.bar

15:54 rads: arohner: turns out ring does the same thing but with just :reload. I made a new fn that uses :reload-all instead and it works fine

15:56 although it is kinda slow since it reloads *everything*, not just my code. might just be best to add all of my namespaces

15:59 programble: is there an equivalent of haskell's zipWith in clojure?

15:59 dakrone: programble: (reduce ...)

15:59 ,(reduce + [1 2 3])

15:59 clojurebot: 6

16:00 hiredman: dakrone: I don't think so

16:00 programble: map takes multiple collections

16:00 dakrone: is that not what zipWith does?

16:00 hiredman: dakrone: nope

16:00 the-kenny: dakrone: Isn't that foldl?

16:00 hiredman: reduce is a fold

16:00 kotarak: dakrone: I think reduce is foldl or foldr, can't remember those

16:00 hiredman: ,(map + [1 2] [3 4])

16:00 dakrone: hiredman: okay, I'm wrong, sorry programble

16:00 clojurebot: (4 6)

16:01 programble: zipWith takes a function and two lists, the function is called with the first item of the first list and the first item of the second list, etc

16:01 oh, map works

16:01 nvm

16:01 hiredman: right

16:01 kotarak: programble: even with more lists

16:01 ,(map vector [1 2 3] [ 4 5 6] [ 6 7 8])

16:01 clojurebot: ([1 4 6] [2 5 7] [3 6 8])

16:05 programble: how can i convert int to char and back?

16:05 like a -> 97

16:05 hiredman: (char 97)

16:05 Raynes: ,(char 97)

16:05 clojurebot: \a

16:05 programble: and back?

16:05 Raynes: hiredman: I win.

16:05 hiredman: ,(int \a)

16:05 clojurebot: 97

16:05 Raynes: (int \a)

16:05 You got that one. :(

16:07 programble: hrm...

16:08 and how can i go to and from a /string/ and int

16:08 like

16:08 between string and list of ints

16:09 hiredman: ,(String. (make-array Byte/TYPE [97 99 100]))

16:09 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Character

16:09 icemaze: Hi everyone. Can anyone help me with a Java-clojure problem?

16:09 hiredman: ,(String. (into=array Byte/TYPE [97 99 100]))

16:09 clojurebot: java.lang.Exception: Unable to resolve symbol: into=array in this context

16:09 hiredman: ,(String. (into-array Byte/TYPE [97 99 100]))

16:09 clojurebot: java.lang.IllegalArgumentException: argument type mismatch

16:09 hiredman: BLEH

16:10 ,(String. (into-array Byte/TYPE (map byte [97 99 100])))

16:10 clojurebot: "acd"

16:10 icemaze: Eheh, I see you already have a lot of those ;)

16:10 chouser: ,(apply str (map char [97 99 100]))

16:10 clojurebot: "acd"

16:10 chouser: ,(map int "acd")

16:10 clojurebot: (97 99 100)

16:11 Raynes: chouser: Beat you to it in another channel. :p

16:11 programble: lol

16:11 i answered my own question actually

16:11 rads: is there a way to restart a jetty server running in a swank repl without restarting the whole repl?

16:14 icemaze: i'm having a problem loading java classes, can anyone give me tips on how to solve this problem?

16:14 * nDuff waits for icemaze to clarify beyond "a problem".

16:15 icemaze: i have a .class file, which is generated by ANTLR, and i'd like to instantiate the class inside it

16:15 Raynes: "My computer broke. How do I fix it?" :>

16:15 icemaze: (I'm using the enclojure plugin under netbeans, it this helps)

16:15 nDuff: icemaze, ...and does your classpath include an appropriate entry?

16:16 icemaze: This is a good question: I think Netbeans adds the project's directory in the classpath but I'm not 100% sure. What can I do to verify this?

16:17 Maybe Netbeans does so for pure Java projects only

16:19 kotarak: icemaze: try (System/getProperty "java.class.path") in the Repl. This should give you a clue, what is on the classpath.

16:19 icemaze: Thanks. I'll try it.

16:20 Yes: "...../build/classes", that's where the .class is (this is under a "clojure.lang.LazySeq", hope it's ok)

16:22 hiredman: what?

16:22 clojurebot: what is short for ,(doc ...)

16:22 icemaze: (The error I get when compiling is: "Unable to resolve classname: TLexer")

16:22 programble: huh

16:22 hiredman: what do you mean: under a "clojure.lang.LazySeq"

16:22 programble: what zip

16:23 no?

16:23 clojurebot: da da king of the road

16:23 hiredman: zip?

16:23 clojurebot: zipper is http://clojure.org/other_libraries#toc5

16:23 hiredman: clojurebot: knock it off

16:23 clojurebot: Clojure ranked #21 on 8/14/2009

16:23 programble: wtf?

16:24 icemaze: yes, it doesn't make much sense. Wait, I'll copy what I get:

16:24 dakrone: is it possible to define a multimethod using regex for an argument as the dispatch? if so, can someone point me to an example of what that looks like?

16:24 icemaze: "[some normal paths]:clojure.lang.LazySeq@3081b84b:#{#<ClassPath /usr/share/clojure/clojure.jar....."

16:25 maybe the enclojure plugin is messing this up

16:25 hiredman: sounds right

16:25 I mean

16:25 yes, the plugin is messing that up

16:25 icemaze: mh, ok

16:26 I'll report a bug then

16:26 hiredman: it looks like it is relying on very old behaviour of .toString on lazy-seqs

16:26 which changed eons ago

16:26 icemaze: that's strange: I donwloaded the plugin from github, it's the jan-2010 version

16:26 hiredman: *shrug*

16:27 icemaze: thank you for your help!

16:29 hiredman: hmm

16:30 well, even with the old .toString behavior you wouldn't get a valid classpath

16:32 icemaze: My environment is a little odd: arch linux + Netbeans 6.8 + clojure v1.1.0.

16:32 If it was a common bug, I would already be reported.

16:33 hiredman: you'd be surprised

16:58 dakrone: ,(contains? ["foo" "bar" "baz"] "foo")

16:58 clojurebot: false

16:59 dakrone: what's the right way to see if a vector has a string in it?

16:59 Chousuke: ,(some #{"foo"} ["foo" "bar"])

16:59 clojurebot: "foo"

16:59 hiredman: ,(doc contains?)

16:59 clojurebot: "([coll key]); Returns true if key is present in the given collection, otherwise returns false. Note that for numerically indexed collections like vectors and Java arrays, this tests if the numeric key is within the range of indexes. 'contains?' operates constant or logarithmic time; it will not perform a linear search for a value. See also 'some'."

16:59 Chousuke: that's one way

17:01 dakrone: is there a method that returns boolean? otherwise I can wrap (if (some #{} []) true false)

17:02 chouser: why do you need a boolean?

17:02 dakrone: chouser: passing into a java method that can't reflect if it's not boolean

17:02 Chousuke: dakrone: you can use boolean to cast it to one

17:02 ,(boolean "foo")

17:02 clojurebot: true

17:03 brandonw: interesting how contains? doesn't work on strings. i thought it recursively generates a set

17:03 dakrone: Chousuke: cool, that does it, thanks!

17:03 Chousuke: brandonw: it doesn't test for membership, it tests whether a collection contains a *key*

17:03 hiredman: brandonw: did you read the docstring?

17:03 Chousuke: oops

17:03 chouser: ,(.contains ["foo" "bar"] "foo")

17:03 clojurebot: true

17:04 Chousuke: hm

17:04 dakrone: it's confusing to share the same name as the java method

17:04 Chousuke: yes it is :P

17:04 hiredman: contains? does work on strings

17:04 chouser: ,(contains? #{"foo" "bar"} "foo")

17:04 hiredman: ,(contains? "foo" 1)

17:04 clojurebot: true

17:04 true

17:04 chouser: there. now we're fully muddled.

17:06 dakrone: hiredman: does (contains? "foo" 1) work because it does something like (get "foo" 1)?

17:06 ska2342: contains? is broken by design. It's behaviour is documented (with the exception of lists) but it does not do what the name suggests under all conditions. Nah, me no friend of contains? ;-)

17:06 hiredman: dakrone: no

17:06 dakrone: hiredman: how does (contains? "foo" 1) work?

17:06 Chousuke: ~contains?

17:06 kotarak: ,(some #{false} [true false true])

17:06 clojurebot: contains? is for checking whether a collection has a value for a given key. If you want to find out whether a value exists in a Collection (in linear time!), use the java method .contains

17:06 nil

17:06 hiredman: (> (count x) n)

17:06 kotarak: Beware the boolean.

17:06 hiredman: where x is the string and n is the number

17:07 Chousuke: but yeah, it's horribly named :P

17:07 chouser: I think the relationship to 'get' is sound.

17:07 ,(get "foo" 1)

17:07 clojurebot: \o

17:08 ska2342: chouser: I think most people would expect (contains? "foo" \o) to work. Not?

17:08 dakrone: conceptually that is very difficult to wrap my head around

17:08 brandonw: ohhh it was distinct? i was thinking of

17:09 not contains?

17:09 Chousuke: dakrone: contains? would make more sense as has-value-for-key? or something

17:09 chouser: if you pretend 'contains?' is named 'has-key?', your instincts may serve you better.

17:09 dakrone: chouser/Chousuke: yea, those make more sense to my brain

17:10 thanks

17:10 ska2342: chouser: what about lists? ;-)

17:10 Chousuke: it's probably the number one faq about Clojure. besides "how do I get slime to work?" or something :P

17:10 chouser: ska2342: holds ok, I think. do lists have keys? no. so contains? always returns false.

17:11 ska2342: chouser: OK, got me. Nevertheless, I'm not convinced. Whatever...

17:12 chouser: not convinced that 'has-key?' is a better name? or that the functionality of 'contains?' should exist at all?

17:12 drewr: I always do (when (:foo m) ...) or similar

17:13 don't think I've ever used contains?

17:13 chouser: yeah, it's hardly ever needed, except when you need to detect keys that have nil or false values.

17:13 ska2342: chouser: has-key would be a better name, the functionality as expected by users should exists with the given name. However the distinction between lists and vectors and other iterables or instances of Counted feels weird

17:13 bhenry: what would you use if you really wanted to know if a string contained a substring?

17:13 chouser: even then 'find' is often better.

17:14 hiredman: clojurebot: jdoc String

17:14 kotarak: ska2342: does performance promises help here? O(1) on vectors vs. O(n) on lists?

17:15 hiredman: bhenry: I would read the javadoc for String

17:15 chouser: or use clojure.contrib.string

17:16 kotarak: drewr: your approach works if you can guarantee that there are no nils and booleans in your collections. If you can't, you have to (when (contains? m :foo) ...)

17:16 chouser: or (when-let [[_ v] (find m :foo)] ...)

17:17 ska2342: kotarak: no. contains takes special care of several counted things (e.g. String) but not Counted and PersistentList extends Counted so it's O(1). Or am I mistaken here?

17:17 drewr: kotarak, chouser: usually when I have a nil as value I still want the predicate to be false

17:17 technomancy: is there anything like the namespace function that returns the namespace itself instead of the name of the namespace?

17:17 wow, that was a mouthful =)

17:18 dnolen: well looking the source of core.clj contains? is used 12 times. Source also points out that it searches the collection in constant time.

17:18 kotarak: ,(the-ns 'sandbox)

17:18 clojurebot: #<Namespace sandbox>

17:19 technomancy: kotarak: the namespace function takes a symbol and returns its namespace

17:19 rather than taking a namespace name

17:19 ,(namespace reduce)

17:19 chouser: ,(the-ns (symbol (namespace `map))) ;-(

17:19 clojurebot: java.lang.ClassCastException: clojure.core$reduce__4509 cannot be cast to clojure.lang.Named

17:19 #<Namespace clojure.core>

17:19 dnolen: ,(find-ns 'user)

17:19 clojurebot: #<Namespace user>

17:20 dnolen: ,(find-ns (symbol "user"))

17:20 clojurebot: #<Namespace user>

17:20 chouser: technomancy: symbols and keywords only know their namespace name. they don't actually point to the namespace object, I think.

17:20 bsteuber: ,(namespace 'reduce)

17:20 clojurebot: nil

17:20 technomancy: chouser: I see. feels a bit like an implementation detail leaking out, but I'm just being extra picky.

17:20 bsteuber: ,(namespace `reduce)

17:20 clojurebot: "clojure.core"

17:20 Chousuke: symbols are just names

17:20 technomancy: calling (the-ns (symbol )) is not a big deal

17:20 Chousuke: ,(namespace 'foo.bar/blah)

17:20 clojurebot: "foo.bar"

17:21 Chousuke: the namespace doesn't have to actually exist :P

17:21 technomancy: Chousuke: ah, good point. that's a good explanation

17:21 kotarak: chouser: ad find... what's the difference to get?

17:21 technomancy: I find that property to be very useful in other situations.

17:22 chouser: find returns a key/value pair, or nil if not found

17:22 kotarak: ah. it returns the map entry.

17:22 k

17:25 hiredman: ,(doc the-ns)

17:25 clojurebot: "([x]); If passed a namespace, returns it. Else, when passed a symbol, returns the namespace named by it, throwing an exception if not found."

17:25 * hiredman uses create-ns

17:42 Raynes: Shouldn't args surrounded in double quotes on the command-line be treated as a single argument? Calling a clojure application with "meow meowz" results in two args instead of one. I'm not sure that should be expected behavior.

17:44 Most other languages treat arguments surrounded in double quotes as a single argument.

17:49 chouser: Raynes: windows?

17:49 Raynes: No.

17:49 programble: Not windows, right?

17:50 programble: ...no

17:50 * programble now has to take a shower

17:50 programble: i feel dirty after the mention of windows

17:50 Raynes: :p

17:51 chouser: This isn't a bug, is it?

18:07 pcapriotti: is it possible to recursively define a lazy-seq in clojure?

18:08 something like the following haskell: fib = 0 : 1 : map (uncurry (+)) (zip fib (tail fib))

18:10 * the-kenny isn't very fluent in haskell

18:11 pcapriotti: the-kenny: that would be in clojure: (def fib (concat [0 1] (map + fib (rest fib))))

18:12 but fib is unbound inside the declaration of fib, so that doesn't work

18:15 the-kenny: pcapriotti: hm.. not sure if it's helpful, but fibs is defined in contrib as: (map first (iterate (fn [[a b]] [b (+ a b)]) [0 1]))

18:17 pcapriotti: the-kenny: yeah, that was just an example... of course in this case there's no need to define it recursively

18:25 danlei: pcapriotti: (def fib (lazy-cat [0 1] (map + fib (rest fib))))

18:28 bsteuber: danlei: nice

18:28 so lazy-seq does the trick, as fib is defined when the body is finally evaluated

18:28 pcapriotti: danlei: oh, cool, lazy-cat does the right thing

18:28 programble: my cat is lazy

18:28 sorry, just needed to make that joke

18:30 rickmode: I've got a newbie question: I'm starting to hack a compojure app. I started the app using lein new my-app. Now, do I compile the hello world and use slime-connect in Emacs, or can I somehow use the SLIME in Emacs? I'm trying to do the latter but my SLIME (fired up with M-x slime) doesn't know about compojure.

18:30 pcapriotti: now, is it possible to do that without creating a global binding?

18:30 like: (let [fib ??])

18:31 bsteuber: rickmode: swank-clojure-project is your friend

18:31 or lein-swank

18:32 rickmode: bsteuber: OK, so using M-x slime is just for fooling around, but when working on a project you connect your Emacs with the running project via M-x slime-connect. Do I have that right?

18:32 (I know it works, I'm asking the best-practice)

18:32 the-kenny: rickmode: Or you fire the repl for the specific project up in emacs with M-x swank-clojure-project

18:32 bsteuber: yeah - though you also have M-x swank-clojure-project

18:32 too slow :)

18:33 the-kenny: I personally use swank-clojure-project, so I don't have to remember port-numbers etc.

18:33 bsteuber: me 2

18:34 also, it is just one single step compared to starting the server by hand and connecting from emacs

18:34 dnolen: rickmode: M-x slime, M-x slime-connect are both for real work. M-x slime-connect is more useful in conjunction with lein swank (you don't have to configure your classpath)

18:34 powr-toc: I tend to use a shell script to start a jvm with my vm settings and classpath... as you'll probably have to specify this in production anyways

18:34 then connect with slime-connect

18:35 bsteuber: true, slime-connect gives you more options

18:35 but as long as I don't have a reason to do so I'll stick with the most lazy version

18:35 rickmode: OK so I've created my app with lein new my-app. Next is what? (I'm missing a step - using M-x swank-connect-project is polling for something...)

18:36 bsteuber: you can look in your *inferior-lisp* buffer to see the error

18:36 powr-toc: bsteuber: fine advice :-)

18:36 bsteuber: but probably you need to run lein deps

18:36 to get clojure and contrib

18:37 also you need to add the swank dependancy to your project.clj

18:38 e.g. :dev-dependencies [[swank-clojure "1.1.0-SNAPSHOT"]]

18:38 dammit, my IRC client always gives me a smiley for :d

18:39 programble: lol?

18:40 rickmode: bsteuber: OK I got the dev-dependency, and it's still polling. So when I fire up my Emacs, I don't have an inferior-lisp or slime. Do I need to fire up M-x slime first?

18:40 bsteuber: by the point it's polling you should have that buffer

18:41 maybe rerun lein deps after adding the dev-dep?

18:42 rickmode: bsteuber: heh - it was there... I'm still Emacs challenged (my foray into Lisp started just over a month ago as I started reading PCL, following along with Aquamacs/SLIME/SBCL)

18:44 bsteuber: I'm using emacs for some years now and still don't have clue about most stuff ;)

18:44 functional programmers are just too lazy xD

18:44 dakrone: too much emacs in here :), any other vim users get a useable folding method around (defn ...) they care to share?

18:46 rickmode: bsteuber: i've spent the last couple months looking for my ultimate web dev environment rather than pick something easy and go with it. That's how lazy i am.

18:47 So I"m getting issues in my *inferior-lisp*: Could not locate swank/swank__init.class or swank/swank.clj on classpath: (NO_SOURCE_FILE:0)

18:47 (BTW: where do we paste in this channel?)

18:48 bsteuber: and I spent a year trying to invent my own lisp instead of reading about clojure :)

18:48 rickmode: egad... you aren't pg in disguise are you?

18:48 Maddas: dakrone: I use vi emulation in Emacs instead ;)

18:48 bsteuber: I guess most use github gists, but I guess you're free to do what you like

18:48 lol

18:49 rickmode: ok so you're sure there's a swank-clojure jar in lib?

18:51 hiredman: lisppaste8 is a bot that used to help with pastebin stuff, but it seems to be dead

18:51 bsteuber: but no, I'm not pg lol

18:51 dnolen: rickmode: compojure is pretty easy and certainly no worse going than setting up and configuring a working python web development environment or even a PHP one.

18:51 Raynes: lisppaste sucks anyways.

18:53 hiredman: it had irc integration

18:53 I dunno of any other pastebin that does

18:54 rickmode: dnolen: I agree. I noodled with Python and Django for a bit. Liked it. Looked at Ruby on Rails. There seems to be one way for library writers to create libraries (with all the monkey patching and such) and another for mortals to use Ruby. I didnt' like that. Tried CL - loved the language, then wasted a few weeks building a web stack. (I ranted about this on my blog.) Went back to Django and... decided to look at Clojure. I had discarded the Clojure route

18:54 initially because of the JVM dependency.

18:55 danlei: rickmode: link to that rant?

18:55 bsteuber: me two - having to use Java all the time at university kind of gave me a trauma

18:56 so I didn't want a lisp that is connected to it somehow

18:56 rickmode: danlei: http://rickmode.com/2010/02/21/common-lisp-pain/

18:56 powr-toc: rickmode: the JVM is a pretty awesome piece of kit

18:56 danlei: rickmode: thanks

18:56 lancepantz: is there a way i can remove one of the into #{} functions in this? http://www.pastie.org/850851

18:57 rickmode: I started with Clojure Friday night. I was totally sold after the first video on blip.tv.

18:57 lancepantz: i'm using the filter to compact nil values

18:57 dnolen: rickmode: at first JVM dependency seems lame. But then you realize there's a quite lot of good software written for the JVM. Also that it's the only thing remotely near the speed of C++ without the suckiness (IMO).

18:58 hiredman: lancepantz: for has a lot of keyword modifiers

18:58 maybe :when or :while

18:59 dnolen: except for maybe Haskell, but I'm attached REPL style development, and not convinced about types.

18:59 bsteuber: actually, having to deal with some aborted c++ project for a few months made me love Java again

18:59 rickmode: dnolen: well the problem in java is that there is so much boilerplate that to keep things anywhere near DRY you need a library or framework. So then there's the framework explosion. The mess gets so big Ant can't keep up. So then there's maven. Ugh. Well at least I can code happily now and cherry pick the best bits. If Clojure really takes off, hopefully the crufy java bits will fall away.

18:59 bsteuber: well, not love, respect

19:00 lancepantz: hiredman: can i use them to change the returned datastructure though?

19:00 powr-toc: rickmode: I think clojure has a good chance of avoiding the whole framework composability problem... It seems like a return to simple API's

19:00 danlei: rickmode: feel your pain (regarding cl). I think it's best to always check out heads by hand, and not use asdf-install at all (am not a friend of clbuild either)

19:00 hiredman: :when (not (nil? v))

19:00 or just :when v

19:01 rickmode: bsteuber: Ya... C++ is even harder. The object-orgy is worse there than java. Actually I was against Java from the beginning because only the compiler writers could write something like string contatention ala "foo" + "bar". Tha'ts lame. But at this point I appreciate what Java got write. The inner classes are cool (but closures are better). The gc is cool. The packaging system is really good.

19:01 hiredman: or just remove the inner into

19:01 lancepantz: i see

19:03 rickmode: daniel: My biggest problem is that I would look at, say UCW.. and no docs at all. Then Weblocks - looks *really* good, but then I can't get 3 of 4 demos to run due to busted dependencies. Anyway CL does feel like stepping back to the early 90's. The library ecosystem is a bit of a wasteland. I want to stand on the backs of giants, and that isn't possible as a new CL coder.

19:03 bsteuber: rickmode: platform independence (more or less) is great

19:03 Raynes: rickmode: That was one hell of a rant. :>

19:04 bsteuber: the java guis always said they wanted to drag the c++ crowd halfway to lisp - and I thing they did a good job concerning the environment, gc etc.

19:04 * rickmode is very good at being grumpy

19:04 bsteuber: so clojure is the next logical step

19:05 rickmode: ugh gotta run - i'll be back with more questions later... thanks for the help so far guys

19:05 powr-toc: personally I think Java did a lot of good for the industry... It popularised garbage collection, and made VM's acceptable... As a language it was pretty unambitious, but it did a lot of things well... Now Clojure makes the JVM awesome.

19:06 danlei: rickmode: I absolutely agree regarding documentation/libraries, but as far as the language itself is concerned: There's a lot to learn there. Even if there are warts and things which feel really old nowadays (e.g. in the pathname system), it's one of my favorite languages. Many of those things, clojure gets right, but some things I miss from CL.

19:06 lancepantz: hiredman: got it, thanks for your help

19:07 danlei: rickmode: so I'm all for learning both of them ;)

19:07 bsteuber: I don't miss much from CL

19:08 danlei: well, I said "some" ;)

19:08 Raynes: I see nothing in CL that I would miss if I learned it.

19:08 bsteuber: but I had been a haskell convert before finding clojure :)

19:08 danlei: Raynes: condition system, debugger ...

19:09 bsteuber: danlei: but those will hopefully be possible in clojure with the new &env stuff, not?

19:10 danlei: bsteuber: clojure is young, and I think those things will be done in the future. I've great expectations ... I mean, it started in 2007, right?

19:10 that's just 3 years

19:11 Raynes: 2, actually.

19:11 danlei: or 2, yesw

19:11 bsteuber: what I miss in clojure is static type inference

19:12 in haskell, this really made up for 80% of my tests

19:12 danlei: bsteuber: have a look at Qi or typed scheme

19:13 I'm more of a dynamic typing guy (but still, I check out haskell ... slowly ;)

19:13 bsteuber: I think dynamic typing with a type-time inference engine would be awesome

19:13 but that could be done on top of clojure

19:14 the term type-time might be confusing :)

19:14 but I will have a look at Qi and typed scheme

19:17 danlei: bsteuber: I think if you're coming from haskell, you'll prefer Qi, last time I checked typed Scheme, there was no type inference

19:17 bsteuber: qi looks nice

19:17 but I want it on top of clojure :)

19:17 danlei: :)

19:20 bsteuber: btw. did a standard prolog-in-clojure evolve yet?

19:21 should not be hard with all the CL examples

19:21 powr-toc: bsteuber: There's a datalog implementation in contrib

19:22 dmiles_afk: CL in cojure comming soon?

19:22 bsteuber: powr-toc: the difference was depth vs breadth first, right?

19:23 between prolog and datalog, I mean

19:23 powr-toc: bsteuber: Not entirely sure... I've not had a chance to look at datalog

19:23 bsteuber: dmiles_afk: why would you want CL in clojure? there are already CL implementations for the JVM

19:24 so many thing I should look at :)

19:25 dmiles_afk: ah yes indeed.. i just wondering

19:26 i seen a few lisps on jvms.. but would be nice since people seem to be liking clojure alot.. and to do both at the same time w/o marshalling would be good

19:29 bsteuber: I guess it would be a hard job to get the interop right without much marshalling

19:30 but I don't care anyways - left CL behind forever :)

19:31 I'll need to get some sleep now - have fun everybody

19:42 rickmode: so I got swank-connect-project working. I had to add [swank-clojure "1.1.0"] to my :dependencies. it didn't work as a :dev-dependency as that doesn't cause the swank-clojure*.jar file to be copied to the lib directory. Is this right?

19:42 er... sorry I mean swank-clojure-project (not swank-connect-project)

19:54 Raynes: Damn freenode and it's security measures.

20:32 zaphar_ps: is there some reason that printing to stdout wouldn't show up in a clojure app?

20:32 it works from repl

20:32 but when I run the app nothing shows up on the terminal

20:32 I'm assuming *out* has been changed somehow?

20:32 programble: zaphar_ps: try adding (flush) after your println or printf or whatever

20:34 technomancy: rickmode: putting swank-clojure in dependencies will work, but if another project relies on yours it will include it

20:34 rickmode: putting it in dev-dependencies should work; I've never heard of that failing to get copied to lib/

20:34 zaphar_ps: programble: nope still no dice

20:35 programble: i dunno, im just guessing lol

20:35 im a clojure n00b

20:35 technomancy: zaphar_ps: I have had issues with *out* not being bound correctly when using clojure.main -e

20:35 not sure what the solution is, sorry. =\

20:35 zaphar_ps: hrmmm

20:36 this isn't using clojure.main specifically

20:36 it's using my own main method

20:36 I'll add some logging to see if I can see what *out* is bound to

20:39 tomoj: have there already been "I heard you like * so I put clojure in your clojure so you can * while you *"s?

20:40 programble: lawl

20:40 tomoj: with a picture of rich talking about cinc

20:40 programble: I heard you like recursion so I put clojure in your clojure so you can recurse while you recurse?

20:40 technomancy: "so you can lazily persist while you lazily persist."

20:44 zaphar_ps: it looks like it's bound to something

20:44 is there anyway to tell if it's bound to stdout or not?

20:46 hiredman: ,(identical? System/out *out*)

20:46 clojurebot: false

20:47 zaphar_ps: this is incredibly frustrating

20:48 hiredman: how are you starting the app?

20:49 what happens if you (.println System/out "foo") ?

20:50 zaphar_ps: hiredman: java -cp foo.jar foo.class <args>

20:50 and doing (.println System/out "foo")

20:50 also has no output to the terminal

20:50 it's weird

20:50 hiredman: are you sure the code you think is being run is being run?

20:50 zaphar_ps: logging indicates it is

20:51 oh wait... doh!!!

20:51 I'm using a wrapper script and capturing the output

20:51 hiredman: :(

20:51 * zaphar_ps now feels sufficiently foolish he can go back to coding

21:00 rickmode: technomancy: swank-clojure gets copied iff it is before leiningen/lein-swank

21:18 jcromartie: what the heck is this guy talking about when he says "functions are inherently non-deterministic"

21:18 in regards to FP

21:20 hiredman: opposite date

21:21 day

21:26 jcromartie: http://rebelscience.blogspot.com/2007/10/half-century-of-crappy-computing.html

21:28 hiredman: jcromartie: I think if you read "procedure" for function

21:29 jcromartie: yeah but he specifically mentions "FP"

21:31 hiredman: are you talking about in the comments?

21:31 DeusExPikachu: I want to be able to manage launching "jobs" in different threads. What's the cool way to do this? So storing future objects in a map in a reference in the var mapped to symbol *threads*. Should I be using executors?

21:31 hiredman: executors are cool

21:32 DeusExPikachu: s/so/I am currently

21:32 jcromartie: hiredman: comments by the author

21:32 hiredman: *shrug*

21:35 rickmode: jcromartie: could be something related to real-time programming where you need predictable time guarantees? (Java/JVM languages can't be used for this sort of real-time stuff, AFAIK).

21:36 hiredman: it can, you just can't use the gc

21:36 jcromartie: yeah, I don't see how a pure function written in C would be non-deterministic

21:36 hiredman: no allocation

21:37 jcromartie: hmm

21:37 hiredman: I've heard tell of people tuning java apps to get them to that point

21:37 rickmode: jcromartie: in real-time stuff you can't just code such that you *think* it is deterministic, it needs to be formally provable

21:38 jcromartie: I see

21:38 rickmode: it's been a while since I heard of this stuff - i prolly have the details mixed up

21:38 hiredman: ya i've heard there is a real-time version of java, but i'm pretty sure it isn't the usual sun jdk

21:42 DeusExPikachu: rickmode, or maybe hardware specific like for phones or azulsystems

21:43 gravity: Is there a way to define multiple vars in one call? Like let allows when you have multiple parameters in the argument list?

21:44 jcromartie: gravity: you mean like def them to the same thing?

21:45 gravity: jcromartie: Yes, exactly

21:58 jcromartie: gravity: well if you haven't done so yet, you could use a macro

21:58 but it's a strange question

22:04 zaphar_ps: gravity (let [foo "bar" bar foo bleh bar] ...)

22:04 gravity: jcromartie: Yeah, it's sort of a strange condition. I'm trying to figure out a way to restructure the idea so I don't need to do something so bizarre.

22:05 zaphar_ps: that sort of does what you want

22:05 unless you need it defined for the whole namespace

22:05 gravity: zaphar_ps: I'd like for things to be accessible outside the namespace, yeah.

22:05 It's for a complex data structure

22:05 zaphar_ps: ahh multiple nodes all sharing the same item?

22:06 gravity: Right

22:06 Or referencing the same item

22:06 zaphar_ps: couldn't use refs for that

22:06 gravity: In the simplest case, a graph with two nodes each linking to the other.

22:06 zaphar_ps: I mean couldn't you use refs for that

22:07 gravity: Don't I still need to def them?

22:07 jcromartie: no

22:08 zaphar_ps: no you couldn't? or no you don't need to def them?

22:08 :-)

22:10 actually I'm not sure refs would help either

22:18 brandonw: could anyone point out what i am doing wrong here? http://pastie.org/851077

22:18 trying to make a lein plugin for nailgun that applies classpath. macros just own me at the moment, though.

22:19 actually: http://pastie.org/851078 is what i last have tried

22:20 unquoting addr-port when constructing the array to send to the main method of NGServer

22:25 hiredman: it says addr-port and you are just passing an ip address

22:25 unquoting inside and an unquoted part is not going to work

22:25 brandonw: the arg is parsed in NGServer

22:25 can be ip, port, or ip and port

22:26 all as one arg

22:26 oh right, i forgot to take the unquote off before the into-array

22:27 hiredman: what is the error?

22:27 brandonw: that's the hardest part: i'm not sure exactly how to debug something like this

22:27 i create the jar, put it in another project's lib directory to test it

22:27 it also has the nailgun dep specified

22:28 hiredman: if that is the case you may want to start smaller

22:28 brandonw: hold on, i screwed up a paren somewhere...

22:28 hiredman: working on code you can't debug is a bad idea

22:28 a recipe for pain and frustration

22:29 brandonw: err

22:29 nevermind, it works...

22:29 i swear i had tried that combination before...

22:30 that's pretty sweet :) i can actually contribute something now

22:30 i'm sure a lein-nailgun plugin would be useful for vimclojure users

22:30 that is, one that applies the project's classpath

22:36 jcromartie: I guess it's bad to use (decorate) in compojure with big chunks of routes?

22:36 like (defroutes foo ...) (decorate foo with-bar) (defroutes bat foo ...)

22:37 if foo is something like a login handler, the you can never use a 404 handler,right?

22:38 I mean with-bar

22:38 tomoj: why not?

22:38 jcromartie: if with-bar is something like with-account that returns an "unauthorized" response

22:38 tomoj: I'm not asking because I think you're wrong, I'm asking because I don't understand

22:38 ah

22:38 so, the 401 will come in instead of 404

22:38 jcromartie: yeah

22:38 tomoj: or the 401 will redirect to a login page

22:38 instead of being a 401

22:39 jcromartie: right

22:39 tomoj: hmm

22:39 have you seen webmachine?

22:39 jcromartie: nope

22:39 tomoj: I would like it if we had a webmachine in clojure

22:39 http://bitbucket.org/justin/webmachine/wiki/BigHTTPGraph

22:40 http://blog.therestfulway.com/2009/05/video-slideshow-introducing-webmachine.html

22:40 I haven't used it

22:40 jcromartie: hm, yeah

22:40 tomoj: but my understanding is that it takes care of all the http details for you

22:40 and lets you hook into any point in the http graph easily

22:40 and hopefully in a sensible way so that you can do what you're wanting to do

22:41 I think a set of clojure middleware could do that, maybe with some extra functions and macros

22:41 er, compojure middleware

22:46 brandonw: hmm. not quite yet after all. the server seems to start okay, but vimclojure has trouble connecting to it

22:47 tomoj: didn't someone already work on a lein plugin for that?

22:48 brandonw: i don't know. i only see one lein plugin on clojars, and it doesn't apply the classpath at all

22:48 tomoj: have you seen this? http://lisp4fun.blogspot.com/2010/02/leiningen-and-vimclojure.html

22:49 brandonw: yes, but the way they apply the classpath is kind of hacky, and doesn't use lein

22:49 well, not really hacky i guess

22:50 it works and it won't ever fail

22:50 a lein plugin would be a tiny bit easier, though (and more portable)

22:50 and it is a good exercise in learning more about clojure :)

22:50 tomoj: well, good luck

22:51 I got this idea to build a framework that turns chunks of clojure namespaces into a command line tool with an embedded repl

22:51 hiredman: clojure -> sh compiler!

22:52 cp2: clojure -> brainfuck

22:52 tomoj: yeah, but I don't want to bother with nailgun

22:52 and the jvm startup time is too big

22:52 I'm envisioning something more like irb or the mongodb js console

22:52 but customizable with whatever code you want to use interactively

22:53 hiredman: that sounds ridiculous

22:53 tomoj: why?

22:53 clojurebot: why not?

22:54 tomoj: I admit my judgement is impaired

22:54 the ec2 command line api tools are terrible, so I want an ec2 console with embedded clojure

23:07 brandonw: okay, got it working, but now i have to test clojure versions

23:07 turns out, the lein plugin needed to have the clojure and clojure-contrib deps specified

23:08 have to make sure that if i specify a different version than the plugin requires, that the different version is used

23:09 kind of wondering if i am doing something wrong, though-- the lein-swank plugin didn't need to specify clojure versions. i assume that is because swank-clojure specifies them

23:12 ah, the vimclojure jar i am using requires clojure 1.1 i think

23:13 it seems kind of unstable to have swank-clojure and vimclojure not specify the version of clojure that they need

23:13 what if the version you are using in your project is not compatible with the version required by the plugin?

23:35 fanatico: Any reason types don't support vararg-style constructors?

23:35 brandonw: hmm, how exactly does one contact a group owner on clojars?

23:41 dakrone: brandonw: good question, I've been searching github to hope they have the source up so I can send them a message

23:43 * dakrone adds a way to show a user's email to his fork of the clojars project

23:58 brandonw: does the version of clojure that swank-clojure requires force you to use that same version in your project?

23:59 Raynes: No.

23:59 tomoj: with lein repl, it does, doesn't it?

23:59 brandonw: how does it manage that?

23:59 Raynes: Yes.

23:59 tomoj: with emacs slime-connect, it doesn't

Logging service provided by n01se.net