#clojure log - Feb 10 2009

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

0:46 whirlycott: wondering if someone can give me a nudge with a question

0:46 i have a map

0:46 strings are keys

0:46 i want the vals to be functions

0:47 i'm having trouble deciphering the syntax for getting a value from the map and then calling that function....

0:48 offby1: pity I don't know enough clojure to answer.

0:53 ayrnieu: whirly, you didn't ask a question.

0:53 whirlycott: the question is: what's the syntax? :)

0:53 i can get stuff from a map

0:53 (duh)

0:53 it's getting the function out and calling it that is stumping me

0:53 ayrnieu: ,(({"a" (fn [] 1), "b" (fn [x] (+ 2 x))} "b") 4)

0:53 clojurebot: 6

0:54 whirlycott: ok, that's using an anonymous function

0:54 ayrnieu: you get it out the same way you get anything out of a map. You bind it to a name the same way you do anything-- one way: (if-let [f (some-map ...)] (f arg1 arg2) "no function!")

0:54 whirlycott: what if the function has been defined with defn in the current ns or another ns?

0:55 ayrnieu: then you just name it in the map.

0:55 whirlycott: (defn hello [username] (println ("Hello, " username)))

0:55 (def *routes* { "key", hello } )

0:55 ayrnieu: ,(({"a" +, "b" println} "b") "hello")

0:55 clojurebot: hello

0:55 whirlycott: how do i call the function pointed to by "key"?

0:56 ayrnieu: you put it at the head of a list, the way you call any function.

0:57 whirlycott: ((*routes* "key") "phil")

0:57 java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn (NO_SOURCE_FILE:0)

0:57 ayrnieu: ,(let [ops {"+" +, "-" -, "*" *, "/" /} this-op (ops "*")] (this-op 2 4))

0:57 clojurebot: 8

0:57 ayrnieu: ,("not a function" 2)

0:57 clojurebot: java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn

0:58 whirlycott: why am i seeing a comma before your opening paren?

0:58 ayrnieu: you said you mapped strings to functions. You've pulled a string out of the map, there.

0:58 clojurebot responds to initial comams.

0:58 whirlycott: k

1:04 so could you put my hello fn as a key in the map? that's my problem, as you have helped me understand it

1:05 (a val, not a key, i mean)

1:05 ayrnieu: ,(let [ops {"+" +, "-" -, "*" *, "/" /} this-op (ops "*")] (this-op 2 4))

1:05 clojurebot: 8

1:05 whirlycott: k, gotta stare at that for a sec :) many thanks for your help ayrnieu

1:05 ayrnieu: that binds ops to a map of strings to functions, and then this-op to a function taken out of ops by its string key, and then applies this-op to two arguments.

6:05 antirealist: /quit

7:13 AWizzArd: In my (ns XYZ ...) I have a (:require [clojure.contrib.sql :as sql]). When I (compile 'XYZ) I get this error: java.lang.RuntimeException: java.lang.ClassNotFoundException: clojure.contrib.def$defvar__1337 (sql.clj:18)

7:14 in sql.clj I find at line 18 the NS setup, and in line 19 it says: (:use [clojure.contrib.def :only (defalias)])

7:14 Is that a problem for compilation?

7:16 I commented out that require and now I get a complaint for the next I have: java.lang.RuntimeException: java.lang.ClassNotFoundException: clojure.contrib.seq_utils$flatten__1375

7:18 seems that all my requires produce an error during compilation

7:19 any ideas?

7:19 Do I first need to compile clojure.contrib to .class files?

7:31 Holcxjo: You don't have the clojure-contrib .jar file in your classpath?

7:32 AWizzArd: it is in my classpath

7:33 And when I (load-file "/.../XYZ.clj") then everything works fine.

7:34 Holcxjo: Oh, I see that clojure-contrib.jar contains only .clj files...

7:34 So, I am officially out of my depth here...

7:36 AWizzArd: Right, only CLJs in there. So, I don't know if that is enough. I thought they can maybe get compiled on-the-fly.

7:37 Holcxjo: Seems, one has to provide the clojure.jar for the ant build for ant to compile the files as well...

7:39 So, how does one set a property with ant?

7:39 ant -Dclojure.jar=../../clojure.svn/clojure.jar

7:40 Now it compiles the files as well...

7:40 rsynnott: Hey, I'm currently calling a clojure function from a Java app by using RT.getVar and using 'invoke' on the result

7:40 is this reasonable, or is there a better approach?

7:41 Holcxjo: ... and the .jar file contains the .class files -- I guess that is what you want

7:41 rhickey: rsynnott: RT.var + invoke is fine

7:42 AWizzArd: well, now it seems even more strange.. when I have a .clj file with only the (ns ... (:gen-class)) and no functions in there, but only a few (def)s, then it compiles.

7:43 But as soon I put just one (defn foo []) inside, it complains: java.lang.ClassNotFoundException: my.namespace.XYZ$foo__1400

7:46 rsynnott: rhickey: thanks

7:47 isn't there some way to fake a java class, as well?

7:47 Holcxjo: AWizzArd: Problems with compile-path and classpath not being consisteny?

7:49 AWizzArd: Holcxjo: I do (binding [*compile-path* "something/in/my/classpath"] (compile 'my.namespace.XYZ))

7:57 rhickey: when the minimal example of compilation from http://clojure.org/compilation doesn't work as long the (defn ..) is in the file and produces a java.lang.ClassNotFoundException: clojure.examples.hello$_main__1258 what source of problem could there be?

7:58 but as soon the defn is (comment)ed out it compiles

7:58 jdz: your classes directory is not in classpath

7:59 make sure the directory exists before you start java

8:00 AWizzArd: I see. But why can it then produce .class files as long there is no defn?

8:00 And is there a way to let Clojure throw a different exception?

8:08 * rsynnott has finally gotten a chance to mess about seriously with clojure, and is really, really impressed with it

8:11 rsynnott: oh, by the way, is java 1.5 okay, or would 1.6 be better?

8:16 AWizzArd: About commercial development with Clojure: in its current version (compile ...) produces a .class file with the name of each function. Are there obfuscation tools that can safely (and automatically) rename those .class files, and change all references to them in a whole project?

8:25 Chouser: rsynnott: 1.5 is ok and officially supported, afaik.

8:28 AWizzArd: it can *produce* class files either way, but functions have to be loaded again in order to be used in subsequent expressions. It's then that the incorrect classpath becomes a problem.

8:29 rsynnott: what did you mean by fake a java class?

8:35 rsynnott: Chouser: looks like :gen-class is what I'm looking for, actually

8:40 though it seems that java classes have to be available when a java file using them is compiled; is that correct?

8:41 (I haven't used java for about 5 years...)

9:18 notyouravgjoel: i'd like to create a sequence with n 1's in it. Is there any good way to do this?

9:19 nvm, just thought of how easy it was

9:21 gnuvince: notyouravgjoel: replicate

9:22 notyouravgjoel: thankss

9:23 AWizzArd: Does anyone of you know an obfuscator that actually works for .class files generated by Clojure?

9:43 Chouser: l.;'hf.g'f/b'

9:45 hm, sorry about that.

9:50 cemerick: I have a class with two constructors -- one that takes all Objects, another of the same arity that takes specific types. In pre-AOT clojure, I was able to create instances of this class without a problem; with current clojure, I'm now getting a "More than one matching method found" exception when loading code that references those constructors.

9:51 Two interesting things there: (a) it looks like clojure has gotten pickier (or more strict) about args going into methods that have ambiguous overloads (i.e. I suppose pre-AOT clojure may have just been falling back on the all-Object overload)

9:52 (b) in the code that's failing to compile right now, all of the arguments are either literals (booleans, in fact) or proxied instances, so the args should align perfectly with the non-Object constructor.

9:52 any thoughts on the above?

9:53 AWizzArd: proguard doesn't work?

9:56 AWizzArd: cemerick: I hoped someone has already made positive experiences with an obfuscator (+clojure) and can suggest one

9:57 cemerick: AWizzArd: well, proguard is the best open-source one out there. We've used it for years with pure java stuff (and the classfiles it generates even distill nicely into .NET assemblies via ikvm)

9:58 I've not tested it with clojure classfiles yet

10:02 AWizzArd: msg cemerick Hallo :)

10:02 sorry, forgot the /

10:42 cemerick: rhickey: not sure if you were here when I talked about it earlier, but I'm pretty sure I've hit a bug related to resolution of overloaded same-arity methods

10:43 or, I suppose it could be an issue with how gen-class is emitting type information for constructors/methods, although that seems less likely...

10:44 rhickey: cemerick: missed it

10:46 cemerick: rhickey: so, I've got a gen-classed lib with two constructors -- one that accepts 4 Objects, another that accepts 4 other arguments (three booleans and a defined interface type, specifically). I have other code that attempts to create an instance of the generated class with three literal booleans and a proxyied instance of the interface type; clojure is emitting a "More than one matching method found" exception on loading that code.

10:47 cemerick: FWIW, this is code that was running and working well using pre-AOT clojure.

10:48 * cemerick likes talking to himself :-P

10:48 cemerick: also FWIW, I double-checked that clojure can properly resolve references to overloaded constructor impls written and compiled from Java -- that works as expected still

10:49 same-arity overloads, that is

10:52 Chouser: oh, so it's only clojure code calling clojure-generated constructors?

10:53 ...that causes a problem?

10:54 cemerick: Chouser: I'm not sure I can say 100% that it's only a problem when calling clojure-generated constructors, but yeah, that's the current idea.

10:54 kefka: In Clojure, how does one write a transaction so as to ensure that if any read variable changes, the transaction restarts?

10:54 ,(def *x* (ref 0))

10:54 clojurebot: DENIED

10:55 kefka: Ok, so the example I was going to show can't be done.

10:55 (i.e. if any read variable is changed from outside)

10:56 rhickey: cemerick: these ctors are explicitly specified or gotten from superclass?

10:57 cemerick: rhickey: explicitly specified via a separate gen-class form -- no subclassing going on, only implementing

10:57 rhickey: can you paste your :constructors clause?

11:00 kefka: The issue is that I want a transaction to restart any time something it reads changes

11:01 rhickey: kefka: ,(doc ensure)

11:01 ,(doc ensure)

11:01 clojurebot: "([ref]); Must be called in a transaction. Protects the ref from modification by other transactions. Returns the in-transaction-value of ref. Allows for more concurrency than (ref-set ref @ref)"

11:01 cemerick: rhickey: yeah -- scratch my last comment, it's subclassing PSM (as usual for me, I guess :-) )

11:01 lisppaste8: cemerick pasted "rhickey: constructors clause" at http://paste.lisp.org/display/75198

11:02 kefka: rhickey: Thanks. Cool.

11:03 rhickey: So ensure seems somewhat like a lock. Is there any danger of deadlock?

11:04 cemerick: rhickey: ah -- interestingly, the all-object constructor doesn't show up in Netbeans when I import the lib's class in Java. Don't know if that's at all helpful.

11:04 rhickey: kefka: no deadlocks w/STM

11:05 cemerick: you have those semicolons in there?

11:06 cemerick: rhickey: no, that's just how they printed out from my macroexpand

11:06 "they" being the reference to the Object[] class

11:07 rhickey: cemerick: and the failing call looks like what?

11:08 kefka: rhickey: Cool. I figured that was the case.

11:08 cemerick: (CharAttrsStruct. (proxy [Font] [] ...) false false false) (where CharAttrsStruct is the class with the 4-arg constructors)

11:08 rhickey: cemerick: several dupes in the ctors list

11:09 cemerick: rhickey: dupes, in that the all-object ctor shadows the others?

11:10 rhickey: triple of [clojure.lang.IPersistentMap clojure.lang.PersistentStructMap$Def [Ljava.lang.Object; clojure.lang.IPersistentMap]

11:11 cemerick: rhickey: well, that's the signature of the superclass' constructor...

11:12 rhickey: why 3 times?

11:12 cemerick: once for each of the subclass' constructors?

11:14 rhickey: isn't this :constructors clause user written?

11:15 cemerick: rhickey: no, it's emitted by a macro into a separate gen-class form

11:15 rhickey: well, it's the same question, why 3 times?

11:16 Did you try: (CharAttrsStruct. (proxy [Font] [] ...) (boolean false) (boolean false) (boolean false))?

11:19 cemerick: rhickey: no, adding explicit boolean calls doesn't change the result

11:22 rhickey: cemerick: (map #(vec (.getParameterTypes %)) (.getConstructors CharAttrsStruct))

11:22 cemerick: rhickey: there are three references to the PSM's constructor sig because there are three constructors in the subclass -- :constructors is a map, after all

11:24 rhickey: cemerick: sorry, right

11:24 lisppaste8: cemerick annotated #75198 with "rhickey: result of (map #(vec (.getParameterTypes %)) (.getConstructors CharAttrsStruct))" at http://paste.lisp.org/display/75198#1

11:25 cemerick: so, that verifies what Netbeans was reporting via its code-completion -- no all-Object constructor

11:25 rhickey: cemerick: and if you hint Font as well as the booleans?

11:25 cemerick: sorry, scratch that :-/

11:26 rhickey: no dice, same error with all four args explicitly hinted

11:26 though, they're three literals and a proxy --- shouldn't clojure have those types available anyway?

11:35 rhickey: cemerick: yes, the problem is neither 4-arg ctor subsumes the other and the call still matches both

11:36 cemerick: rhickey: OK -- but shouldn't the most-specific match be chosen?

11:37 lisppaste8: cemerick annotated #75198 with "rhickey: what's the difference between the current situation and this?:" at http://paste.lisp.org/display/75198#2

11:37 cemerick: Clojure does well in choosing the right constructor in that pasted java code, which is analogous to the current situation (I think)...

11:39 e.g. (Foo. 5 "") chooses the "typed" ctor

11:39 rhickey: cemerick: it's not, due to primitives, Integer is derived from Object, as is String, so Integer+String subsumes

11:39 cemerick: hrm. Isn't everything derived from Object?

11:39 rhickey: cemerick: no

11:40 Chousuke: cemerick: primitives aren't objects at all :/

11:40 cemerick: Right, well, their boxed versions are. But, I'm wading out past my depth.

11:40 rhickey: cemerick: your best hope is an exact-match-wins, which may require hints

11:41 cemerick: rhickey: I guess I'm wondering why this worked pre-AOT?

11:45 rhickey: cemerick: primitives used to trump Object, but that was tightened up for numerics inlining, a long time ago iirc

11:47 cemerick: rhickey: yeah, we were off HEAD for a long time, relatively speaking. What's the general solution then, if hinting to the 9's doesn't work (as I tried 10 min ago)?

12:08 rhickey: cemerick: try svn 1264

12:09 clojurebot: svn rev 1264; added exact-match-wins in getMatchingParams

12:10 cooldude127: how can i find out from inside clojure what rev i'm running on?

12:10 is there a way?

12:12 cemerick: rhickey: same exception, I'm afraid. Everything's still hinted.

12:15 danlarkin: cooldude127: nope

12:15 cooldude127: fine, fine, i'll go to the stupid terminal and run git log ;)

12:16 Chousuke: some version information could probably be added after a real release is made :/

12:16 cooldude127: clojurebot: latest?

12:16 clojurebot: latest is 1264

12:17 cooldude127: woohoo! git is only one rev behind!

12:17 Chousuke: like, have a global variable be 1.0 for 1.0, and 1.0+SVN or something for SVN releases after that, but prior any other version

12:18 cooldude127: it's not a huge issue right now, it's just kinda would be nice to be able to know from the repl just how far behind i am

12:20 Chousuke: with SVN it's a bit problematic that the revision number increases with any commit; even if in some other branch than trunk.

12:20 so you could have 1264 and 1265 be identical as far as trunk is concerned :/

12:20 cooldude127: boo svn

12:21 Chousuke: and even worse, 1266 could actually be "behind" 1265 if the branch has more advanced stuff and something just gets backported.

12:22 ergo, revision numbers make no sense. :)

12:22 cooldude127: yeah

12:25 rhickey: cemerick: try 1265

12:25 cooldude127: woah now 1264 isn't the latest!?

12:25 this crazy rapid development ;)

12:25 Chousuke: clojurebot is a bit lagged I guess

12:25 cooldude127: clojurebot: latest?

12:25 clojurebot: latest is 1264

12:25 Chousuke: it just polls the server.

12:25 cooldude127: yeah looks like it

12:25 Chousuke: every... 5 minutes?

12:26 something like that anyway

12:26 cooldude127: yeah

12:27 cemerick: rhickey: same-same w/1265

12:28 rhickey: would it be helpful if I produced a simple testcase for you?

12:29 I can imagine that this feels like pushing on rope.

12:29 clojurebot: svn rev 1265; added inlining on remaining coercions

12:32 rhickey: cemerick: what is your fully-hinted call?

12:32 cemerick: rhickey: ah, wait, wait, 1265 does work (a clean ant build was needed, it turns out)

12:32 rhickey: voila

12:33 * rhickey rope-pusher

12:33 cemerick: :-)

12:33 rhickey: so, now my question is, why doesn't false/true automatically get hinted "properly"?

12:34 note that I don't have to hint the proxy instance, FWIW

12:34 kylesmith: I just fixed a bug where I was accidentally trying to deref nil. That obviously gave me a null pointer exception, but could there be a more specific error message?

12:34 rhickey: cemerick: false/true are Booleans, not booleans

12:35 cemerick: oh, that's an interesting detail

12:35 durka42: kylesmith: that's basically the definition of a null pointer exception. how much more specific could it be?

12:36 rhickey: my 2 cents - any method that takes Object and a primitive and doesn't do the same thing when passed the boxed version of the primitive as an Object is broken

12:37 i.e. your Object/Object/Object/Object ctor

12:37 danlarkin: kylesmith: just be glad you didn't SEGFAULT!

12:37 kylesmith: durka42: the idea is that a npe can happen anywhere in javaland, but it would make debugging a lot easier if you knew the npe was from deref'ing nil

12:37 danlarkin: true..

12:38 Chousuke: kylesmith: you'd have to make deref check for null :/

12:38 durka42: kylesmith: true. but (deref nil) is just a java method call. you can also do (.printStackTrace *e) and see deref at the top of "caused by"

12:38 cemerick: rhickey: well, note that the impl. of those two ctors (the all-object and the specifically-typed one) are both implemented the same -- the latter is provided only to offer code completion to java tooling

12:39 so the only issue is convincing Clojure that it should simply latch onto the Object ctor, and allow the primitives to be boxed (maybe?)

12:39 durka42: i wonder if names like clojure.core$deref__3595.invoke can be munged back into clojure function names

12:39 even if it was only semi-deterministic

12:39 alinpopa: hi to all from here

12:39 durka42: because then a stacktrace parser could make clojure traces much more readable

12:40 alinpopa: I just need some small help here, please

12:40 kylesmith: actually, (.printStackTrace *e) says nothing about deref for me...

12:40 Chousuke: durka42: well, that's "deref" I suppose /:

12:40 durka42: the problem is anonymous functions.

12:40 durka42: yeah

12:40 and macros which expand to them

12:40 kylesmith: (.printStackTrace (.getCause *e)) ?

12:41 Chousuke: isn't there already a stacktrace pretty printer in contrib though.

12:41 alinpopa: Is there a clojure way to create threads beside of natural Java way ? (new Thread)....

12:41 maybe something like actors model ?

12:41 kylesmith: i suppose I could make a function "my-deref" that just checks for nil and calls deref

12:41 Chousuke: alinpopa: you can use futures if you have a very recent SVN checkout

12:41 alinpopa: or agents

12:41 durka42: Chousuke: yes, although it doesn't do any name munging

12:42 kylesmith: durka42: yep, just says "java.lang.NullPointerException". is my clojure messed up?

12:42 durka42: kylesmith: you could try clojure.contrib.stacktrace/print-cause-trace, i would think deref should be in there somewhere

12:42 alinpopa: Chousuke: thanks

12:42 ayrnieu: alin - http://github.com/ayrnieu/clj-actors/tree/master gives you self-aware agents that receive keyword messages with arguments, that can loop, etc.

12:42 alinpopa: Chousuke: Agents are someway equivalent to actors ?

12:42 Chousuke: not quite.

12:42 Chouser: whoa. self-aware agents!?

12:43 Chousuke: agents are one way, in that you don't explicitly communicate back from agents to the caller.

12:43 durka42: all agents are self-aware

12:43 alinpopa: maybe there is somewhere on the web where to read some diffs between agents and actors ?

12:43 Chouser: new chart for anyone interested: http://tinyurl.com/clojure-classes

12:43 lisppaste8: durka42 pasted "kylesmith: this is what i see" at http://paste.lisp.org/display/75206

12:44 Chousuke: Chouser: still not too much of a mess :)

12:44 alinpopa: ayrnieu: I'll look at that, thanks

12:44 Chouser: Chousuke: it's getting worse. dot is doing what it can, but... :-)

12:46 kylesmith: Okay, (.printStackTrace (.getCause *e)) works in the terminal, but doesn't in slime/emacs. Looks like I might have a fubared setup.

12:48 Chouser: I think there's a slime keystroke to show the next cause

12:48 slime helpfully hides the root cause in a lot of cases apparently.

12:51 kylesmith: well, this is all fine and dandy, but getting back to my original point: would it be possible for deref to just check for nil beforehand and give a better error message?

12:52 te: Hey all

12:52 technomancy: te: hi

12:54 danlarkin: kylesmith: can't you catch NPE and then it'll be the same thing?

13:00 technomancy: duck streams is the closest thing to an HTTP library that ships with contrib, right?

13:07 te: hey technomancy

13:07 technomancy: do you have the URL for concourse?

13:14 technomancy: te: I don't have it public, but if you're interested I could try to push it to github later today.

13:14 it doesn't actually *do* very much at all, but I know examples for compojure are scarce.

13:39 Lau_of_DK: Good evening everyone

13:39 kotarak: Hi Lau.

13:44 danlarkin: Hi Lau!

13:47 kylesmith: I just uploaded bsptree.clj to the group. I blatantly misuse atoms (among other things), so some feedback would be nice.

13:48 specifically, if anyone could improve it's performance, that would be great

14:14 te: technomancy: would you please? ( pass it to github ) -- You said it. I need example code in clojure that do things besides math.

14:15 technomancy: Furthermore, I think compojure looks like a nice way to learn clojure while producing something

14:15 i have to run, but you can PM me a link to the code if you get the itch

14:15 technomancy: thanks!

14:15 technomancy: te: if you just want example code, check out mire

14:16 it's not web-based, but it's a lot more interesting

14:17 Chouser: rhickey__: should IPersistentMap promised Counted even though it doesn't provide an implementation for count() itself?

14:20 Lau_of_DK: Chouser: Have you started working on the STM yet ?

14:21 Chouser: what do you mean? Trying to patch it or something?

14:21 Lau_of_DK: I remember rhickey_ said, at one point, that the STM was the only part of Clojure that you hadn't begun patching your way through yet

14:22 So I was just wondering, when do you start? :)

14:22 hiredman: Lau_of_DK: I think he meant for clojurescript, Chouser hasn't implemented stm for clojurescript

14:23 Lau_of_DK: hiredman: I dont think thats what he meant

14:23 hiredman: Ok

14:24 Chouser: Either way, the answer is no, I have not. :-)

14:24 STM is still a magical mystery to me.

14:25 It would almost be a shame to understand it, like learning that the tooth fairy isn't real, and it's just Dad leaving you a quarter..

14:25 technomancy: heh.

14:25 Lau_of_DK: Chouser: You actually believed in fairies?

14:26 Chouser: in our house he wasn't a traditional fairy. His name was Thumbkin, and he left behind a quarter and a tiny little note.

14:28 Lau_of_DK: Oh ...

14:30 technomancy: Lau_of_DK: I got concourse on github if you're interested: http://github.com/technomancy/concourse/tree/master

14:31 Lau_of_DK: Of course I am, thanks technomancy

14:32 kotarak: Is that similar to doodle?

14:32 technomancy: Lau_of_DK: are you interested in hacking it or just reading the code?

14:33 Lau_of_DK: technomancy: I'd like to help hack it together, but time-wise Im not able to involve myself with more project atm :( But I'll enjoy watching your progress

14:33 mrsolo_: is there a something simliar to ruby splat for clojure?

14:33 ayrnieu: what's ruby splat?

14:34 mrsolo_: foo(*see) where see is an array

14:34 then argument gets plug into functionall

14:34 ayrnieu: ,(apply + [1 2 3])

14:34 clojurebot: 6

14:34 kotarak: mrsolo_: (apply foo see9

14:35 technomancy: Lau_of_DK: ok, cool. well I'm not really going to be working on it for a while, but te was interested

14:35 mrsolo_: right how that going to work with map? for example i like to map + '((1 2 3) (4 5 6))

14:35 Lau_of_DK: technomancy: Its a very good way to get a little familiar with compojure

14:35 mrsolo_: etc.. can't figure out an easy way to peel the outer ()

14:35 ayrnieu: ,(map #(apply + %&) '((1 2 3) (4 5 6)))

14:35 clojurebot: java.lang.ClassCastException

14:36 kotarak: mrsolo_: ,(apply map + [[1 2 3] [4 5 6]])

14:36 ayrnieu: ,(map (fn [& rst] (apply + rst)) '((1 2 3) (4 5 6)))

14:36 clojurebot: java.lang.ClassCastException

14:36 Chouser: kotarak: right

14:36 kotarak: ,(apply map + [[1 2 3] [4 5 6]])

14:36 clojurebot: (5 7 9)

14:37 mrsolo_: ,(apply map + [[1 2 3] [4 5 6] [7 8 9]])

14:37 clojurebot: java.lang.NoClassDefFoundError: clojure/core$map__3634$fn__3649

14:37 technomancy: Lau_of_DK: yeah, but I'm focusing on mire for now.

14:37 ayrnieu: oh, duh.

14:37 ,(map #(apply + %) '((1 2 3) (4 5 6)))

14:37 clojurebot: (6 15)

14:42 mrsolo_: thanks.. (5 7 9) is the desired result

14:42 hiredman: hah

14:42 Lau_of_DK: technomancy: mire?

14:43 technomancy: Lau_of_DK: http://github.com/technomancy/mire/tree/master (a multiplayer text adventure)

14:44 Lau_of_DK: Ah yes -Giving WoW some competition ?

14:44 hiredman: ,(#(map + (first %) (second %)) '((1 2 3) (4 5 6)))

14:44 clojurebot: (5 7 9)

14:44 ayrnieu: ,(apply map + '((1 2 3) (4 5 6)))

14:44 clojurebot: (5 7 9)

14:44 technomancy: Lau_of_DK: more like zork. =)

14:45 mrsolo_: need to work for '((1 2 3) (4 5 6) (7 8 9) ....) as well :-)

14:45 durka42: ,(apply map + '((1 2 3) (4 5 6) (7 8 9)))

14:45 clojurebot: java.lang.NoClassDefFoundError: clojure/core$map__3634$fn__3649

14:45 hiredman: ayrnieu's should

14:45 durka42: say what

14:45 hiredman: huh

14:46 ayrnieu: WFM.

14:46 orroz: how does compose work in clojure?

14:46 hiredman: ,(doc comp)

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

14:46 hiredman: lisppaste8: url?

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

14:46 Lau_of_DK: technomancy: I remember playing a MMORPG called Valhalla when I was a kid, I'd connect through a dial-up connection to this BBS type terminal where I could play with others - It was fantastic fun, because you had to visualize all the scenarios instead of having them painted on your screen - It was a pay-per-the-hour-service though, so it wasnt much fun until I ... got a password from one of the admins :)

14:47 ayrnieu: MUDs are still around -- as are IF games.

14:48 technomancy: Lau_of_DK: nice

14:48 hiredman: http://paste.lisp.org/display/74521 <-- fun for comp and partial

14:52 orroz: how do i compose a function out of map and map like in haskell

14:52 (map . map) (\x -> x*x) [[1,2,3],[4,5,6]] -> [[1,4,9],[16,25,36]]

14:53 hiredman: you want partial application

14:53 gnuvince: ,(map (fn [x] (map #(* % %) x)) [[1 2 3] [4 5 6]])

14:53 clojurebot: ((1 4 9) (16 25 36))

14:53 hiredman: not composition

14:53 er

14:54 wait

14:54 ,(map first [[1 2][3 4]])

14:54 clojurebot: (1 3)

14:54 gnuvince: ,(map (partial map #(* % %)) [[1 2 3] [4 5 6]])

14:54 clojurebot: ((1 4 9) (16 25 36))

14:55 hiredman: ,((comp (partial map #(+ % 1)) (partial map first) [[1 2][3 4]])

14:55 clojurebot: Eval-in-box threw an exception:EOF while reading

14:55 hiredman: ,((comp (partial map #(+ % 1)) (partial map first) [[1 2][3 4]]))

14:55 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: LazilyPersistentVector

14:55 hiredman: ,((comp (partial map #(+ % 1)) (partial map first)) [[1 2][3 4]])

14:55 clojurebot: (2 4)

14:56 hiredman: the main issue to watch out for with composing map is map is arity 2

14:56 but all functions (including map) return a single value

14:56 Chouser: gnuvince's solutions are both good idiomatic Clojure.

14:57 comp and partial are both much less commonly used in Clojure than in Haskell, I would imagine.

14:57 hiredman: yeah

14:57 unless you are playing some kind of golf

14:58 most people just use function literals

15:02 * technomancy likes the idea behind partial and friends

15:02 technomancy: but hasn't used it much

15:06 drdo: Hello

15:06 are there no lambda's in clojure?

15:06 ayrnieu: ,((fn [x] x) 2)

15:06 kotarak: drdo: fn

15:06 clojurebot: 2

15:07 kotarak: ,((#(+ x x) 2)

15:07 clojurebot: Eval-in-box threw an exception:EOF while reading

15:07 kotarak: ,(#(+ x x) 2)

15:07 clojurebot: java.lang.Exception: Unable to resolve symbol: x in this context

15:07 kotarak: -.-

15:07 ,(#(+ % %) 2)

15:07 clojurebot: 4

15:07 drdo: oh

15:07 what does "fn" mean?

15:08 ayrnieu: it means 'lambda'

15:08 drdo: oh right of course

15:08 hiredman: fn means function

15:08 drdo: how could i not see it

15:08 Hun: unicode names ftw

15:08 drdo: -_-

15:08 ayrnieu: ftl.

15:08 drdo: Hun: does it support unicode lambda?

15:09 Hun: i have a symbol macro ? in my CL

15:09 oh, wrong one

15:09 without the stroke

15:09 drdo: kotarak: what does that #() mean?

15:10 ayrnieu: drdo - it meas 'abbreviated syntax for lambda'

15:10 kotarak: #() is a shorthand notation for short fns

15:10 clojurebot: #()

15:10 clojurebot: #() is not a replacement for fn

15:10 drdo: for fns of one argument and one expression?

15:10 ayrnieu: (defmacro ? (& rst) `(fn ~@rst))

15:10 kotarak: ,(map #(+ %1 %2) [1 2 3] [4 5 6])

15:10 clojurebot: (5 7 9)

15:10 ayrnieu: drdo - for fns of any number of arguments and any number of expressions.

15:10 hiredman: ,((? [x] (+ 1 x)) 2)

15:10 clojurebot: 3

15:10 kotarak: #(foo %) is equivalent to (fn [x] (foo x))

15:10 ayrnieu: ,((apply + %&) 1 2 3)

15:10 clojurebot: Eval-in-box threw an exception:arg literal not in #()

15:11 kotarak: ,(apply #(+ %&) [1 2 3])

15:11 clojurebot: java.lang.ClassCastException

15:11 ayrnieu: ,(#(apply + %&) 1 2 3)

15:11 clojurebot: 6

15:12 kotarak: drdo: http://clojure.org/reader has more information on #() and other reader related info

15:14 drdo: i actually think clojure might be the holy grail i've been looking for xD

15:24 durka42: wait, what's %&

15:24 ayrnieu: ,(#(list %&))

15:24 clojurebot: (nil)

15:24 ayrnieu: ,(#(list %&) 1 2 3)

15:24 clojurebot: ((1 2 3))

15:25 kotarak: durka42: (fn [x y & z] ..) <=> #(.. %1 %2 %&)

15:25 durka42: ah ok

15:25 ayrnieu: ,(#(list %4 %&) 1 2 3 4 5 6 7 8 9)

15:25 clojurebot: (4 (5 6 7 8 9))

15:26 durka42: small steps closer to perl :p

15:26 hiredman: :(

15:29 tomsw: can I access previously-printed values on the clojure REPL (in Lisp I'd use *, **, ***)?

15:30 ayrnieu: *1 *2 *3

15:31 tomsw: ayrnieu: thanks :)

15:31 ayrnieu: similarly, *e gives you the last exception. (.printStackTrace *e)

15:32 leafw: suppose I want to list all files in a directory ... but I want to return that list as a lazy list. What is the proper idiomatic way to do that? With a let wrapping a function that works as a generator, or how?

15:33 durka42: how do you get the list one at a time?

15:33 java.io.File/listFiles gives you the whole array, doesn't it

15:33 leafw: durka42: true

15:33 hiredman: I don't think you will be able to do it lazy like

15:33 leafw: hum

15:33 hiredman: why do you want lazy?

15:34 durka42: what if the dir changed while your function was lazing around in the middle of listing it?

15:34 leafw: true

15:35 fine, I am convinced. The directory contains 100,000 files, that's all.

15:35 was thinking on how to avoid loading such list of strings. But there doesn't seem to be away with java.io.File

15:35 I woul have to ls >> list.files and then line-seq that file in.

15:36 hiredman: are the file names well-formed according to some schema?

15:36 leafw: hiredman: yes, they are, but cannot be trivially called individually. There are many sets together.

15:37 hum actually, I could to the line-seq on the file by Runtime getRuntime exec "ls" ... that'd do it too.

15:37 ayrnieu: it looks like java7 may have a better directory interface.

15:37 hiredman: you could make a lazy-seq of names and then filter out non-existent files

15:38 ayrnieu: I assume that this is one of those situations where a library writer says "this underlying library is too hard to use! And for no good reason!"

15:39 leafw: ayrnieu: or rather, they didn't anticipate ext3 supporting so many files per folder.

15:42 tomsw: ayrnieu: although it turns out I didn't want to do (def icon *1)...

15:43 ayrnieu: toms - why didn't you?

15:44 Chouser: hm... shortest path to a stackoverflow? (def x #'x) (x)

15:44 eh, I guess that's pretty unremarkable.

15:44 ,((fn x [] (x)))

15:44 clojurebot: java.lang.StackOverflowError

15:45 gnuvince: ,(throw (java.lang.StackOverflowError.))

15:45 clojurebot: java.lang.StackOverflowError

15:45 Chouser: heh

15:45 gnuvince: thanks. I appreciate that.

15:45 tomsw: ayrnieu: because instead of returning the icon I created, icon returns whatever was last printed on the repl

15:46 ayrnieu: which keeps changing

15:46 ayrnieu: tomsw - that isn't what I observe. What version do you have?

15:47 hiredman: yeah that is just not right

15:48 tomsw: have you tried it and it doesn't work? or are you running this on your mental repl?

15:49 tomsw: hiredman: it fits what I'm seeing on the repl. let me try again

15:49 ayrnieu: how do I find out the version?

15:49 hiredman: * *e etc are relatively new features

15:49 like a two or three months old I believe

15:51 so if he has them at all his version can't be that old

15:51 tomsw: ayrnieu: I can't reproduce it, but I can see what I did on the repl and it doesn't make sense:

15:53 drdo: how do i test for nil?

15:53 ayrnieu: ,(nil? nil)

15:53 clojurebot: true

15:53 drdo: thank you

15:53 tomsw: ayrnieu: (def icon *1) .then. (def mon (fn [l] (. l setIcon icon))) .then. (maplabels (fn [l] (. setIcon icon)))

15:54 ayrnieu: at which point I got an error. When I then evaluated icon I got #'user/mon

15:55 * ayrnieu shrugs.

15:55 * tomsw shrugs too

15:55 tomsw: btw, this is a much nicer way to learn java than java :)

15:55 ayrnieu: I think you can't see your version from within clojure, but you can just checkout the svn repo and build from trunk.

15:55 this is also what I've found :_)

15:56 tomsw: (I'm really reaching for the stars tonight) - is there an equivalent of import java.awt.* ?

15:58 Chouser: tomsw: no, there's not.

15:58 tomsw: Image

15:59 kotarak: tomsw: but you can save the common prefix (import '(my.package Class1 Class2)) ....

16:00 tomsw: kotarak: thanks, I've been using that. The "Image" was me at the wrong prompt trying to find out why Image.SCALE_DEFAULT wasn't found

16:00 kotarak: Image/SCALE_DEFAULT

16:01 (in case that is a static field)

16:01 durka42: question about the import prefix thing, does it nest?

16:01 kotarak: durka42: no, not that I am aware...

16:01 durka42: hmm, that's unfortunate

16:01 i could write a wrapper around it

16:02 hiredman: then you would have to wrap ns

16:02 :(

16:03 tomsw: is there any shorthand for (fn [obj]

16:03 (. obj method arg)

16:04 Chouser: #(.method % arg)

16:04 ,(#(.replace % "." "/") "foo.bar.baz")

16:05 clojurebot: "foo/bar/baz"

16:05 tomsw: Chouser: neat. What's the % for?

16:05 durka42: % is the parameter in an anonymous function

16:05 cemerick: has anyone else noticed that test-is drops swallows exceptions?

16:06 durka42: ,((fn [x y & z] (list x y z)) 1 2 3 4 5 6)

16:06 clojurebot: (1 2 (3 4 5 6))

16:06 kotarak: ,(macroexpand-1 '#(.replace % "." "/"))

16:06 clojurebot: (fn* [p1__1604] (.replace p1__1604 "." "/"))

16:06 durka42: ,(#(list %1 %2 %&) 1 2 3 4 5 6)

16:06 clojurebot: (1 2 (3 4 5 6))

16:06 kotarak: ,(macroexpand-1 '#(.replace %1 %2 %3))

16:06 clojurebot: (fn* [p1__1617 p2__1618 p3__1619] (.replace p1__1617 p2__1618 p3__1619))

16:08 leafw: is there any function that returns a sequence of increasing numbers?Or should I roll my own

16:09 kotarak: (iterate inc 0)

16:09 leafw: iterate! thanks

16:12 does pmap works as intended by default or do I need extra libs?

16:13 ayrnieu: it does not require extra libs.

16:13 leafw: thanks.

16:13 * durka42 notices that pmap has been changed to use futures instead of agents

16:13 leafw: yeah, isn't that nice

16:16 hiredman: yay, java.util.concurrent

16:17 gnuvince: "yay" and "java" in the same sentence: a year ago, I wouldn't have believed it was possible.

16:18 leafw: :)

16:18 Rick is the kind of guy that "reads Knuth so we don't have to" as the python devs claimed.

16:18 tomsw: python, yuk, give me java

16:19 ayrnieu: gnuvince - clojure makes it possible.

16:19 leafw: java, yuk, give me clojure.

16:19 gnuvince: ayrnieu: that's what I'm implying ;)

16:20 tomsw: leafw: that's what I meant. I'm trying to make myself employable after working with CL, by learning java

16:20 leafw: imagine my dismay - until I found clojure

16:21 leafw: clojure is young.

16:21 gnuvince: That's the cool thing: I'm learning the Java standard library bit by bit without having to forsake my programming soul.

16:21 tomsw: gnuvince: +1

16:21 leafw: yeah

16:21 Chouser: gnuvince: I'm with you there.

16:21 leafw: by the way: what is the difference between mod and rem

16:22 aren't they the same

16:22 gnuvince: leafw: negative numbers

16:22 ,(mod -3 2)

16:22 clojurebot: 1

16:22 leafw: ah I see

16:22 Chouser: ,[(mod -2 5) (rem -2 5)]

16:22 clojurebot: [3 -2]

16:22 gnuvince: ,(rem -3 2)

16:22 clojurebot: -1

16:22 leafw: thanks.

16:22 cemerick: clojure-contrib doesn't yet have its own google group and such, right?

16:22 gnuvince: It's a bit odd that div has not yet been added to complement mod

16:23 Chouser: ,(map #(mod % 3) (range -9 9))

16:23 clojurebot: (3 1 2 3 1 2 3 1 2 0 1 2 0 1 2 0 1 2)

16:23 Chouser: cemerick: that's correct, afaik

16:24 kotarak: does it need one?

16:25 gnuvince: ,(map #(rem % 3) (range -9 9))

16:25 clojurebot: (0 -2 -1 0 -2 -1 0 -2 -1 0 1 2 0 1 2 0 1 2)

16:25 Chouser: does mod look right?

16:26 ruby: (-9..9).map{|x| x % 3} => [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0]

16:26 gnuvince: Bug apparently

16:27 Chouser: pretty sad, if the only difference between rem and mod is negative numbers, and it gets the negative numbers wrong.

16:27 gnuvince: file a report

16:28 Chouser: yessir

16:28 visage_: Hey all. I do not really have much history with lisp-styled languages, but I am looking to convert my scientific computing work to clojure. I recognize the benefits that a functional language offers from my work with SML and the benefits of a dynamic language and metaprogramming from work with Ruby. I know most people consider parentheses paralysis an unfounded concern (in fact, it has its benefits), but does anybody find the prefix

16:28 gnuvince: find the prefix...?

16:28 visage_: err, as in (+ 1 2) instead of 1+2.

16:29 I was trying to translate a bunch of lengthy formulas into clojure and couldn't keep them straight

16:29 gnuvince: Your phrase cuts off at "find the prefix"

16:29 visage_: Oh, sorry

16:29 (cont.)...notation cumbersome when they are trying to translate fairly lengthy inline mathematical formulas? I am trying to determine whether clojure is really the language for me before I make the jump.

16:29 I really like what clojure has to offer as a language in general, but am having a bit of trouble crossing this conceptual gap when it comes to this sort of coding specifically.

16:30 gnuvince: visage_: I guess it's a question of habit.

16:30 drewr: visage_: You may need to break your formulae into smaller components to make them easier to read.

16:30 hiredman: you can also write an infix macro that lets you use infix notation

16:30 visage_: ...all very valid and very good answers

16:31 hiredman: ineffect making a dsl for math

16:31 visage_: well...consider me a convert then!

16:31 gnuvince: visage_: the other benefits of Clojure's syntax can probably outweigh the awkward moments of converting a formula

16:31 technomancy: and you don't have to think about precedence rules at all

16:32 I guess if you *like* precedence rules then this could be considered a disadvantage, but it's hard to argue against regularity.

16:33 gnuvince: Well then go for Haskell and write only operators and mix and match the precedence!

16:33 Chouser: I do agree that when doing math and comparisons is when I'm most likely to feel the prefix notation to be awkward.

16:33 for object, method, and function calls, I find Clojure's syntax quite natural.

16:34 gnuvince: Mind you, I'm into math homeworks these days, and I suck at reducing expressions because of precedence

16:34 durka42: i catch myself writing (< 3 x) when i mean "is x {less than three}?"

16:35 * Chouser nods at durka42

16:35 Hun: durka42: it helps to think of < and > as injecting

16:35 think of running them with 3 args

16:35 then it's easy

16:35 its true iff the args are preordered

16:35 ayrnieu: (st 3 isLessThan x)

16:35 hiredman: maybe an infix macro for contrib's math lib?

16:37 durka42: would it have to be a macro

16:37 ayrnieu: it wouldn't.

16:37 Chouser: if you want to allow parens for grouping, it would

16:38 ayrnieu: however, a macro would more naturally let you-- right.

16:38 Chouser: ...but then again, if parens are for grouping, then how would you call functions? :-P

16:38 ayrnieu: you could group with vectors, instead.

16:38 Chouser: which is a fascinating solution.

16:39 leafw: is pmap eager or do I have to call dorun on it?

16:39 ayrnieu: ,`(1 + sqrt(2) + [3 - 2])

16:39 clojurebot: (1 clojure.core/+ sandbox/sqrt (2) clojure.core/+ [3 clojure.core/- 2])

16:39 ayrnieu: pmap is not eager.

16:40 leafw: thanks.

16:40 hiredman: pmap does stay a few steps a head of consumption though, doesn't it?

16:40 Chouser: (inf 1 + (Math/sqrt 2) + [3 - 2])

16:40 ayrnieu: it does.

16:42 Hun: there exist lots of infix-macros from CL and before. i don't know anybody that uses them

16:42 hiredman: maybe alias the unicode sqrt symbol to Math/sqrt

16:42 Chouser: Hun: that's been my impression too.

16:43 cemerick: any ideas why test-is reports only the first 5 frames of caught exceptions' frames?

16:43 Hun: sooner or later you always want to escape

16:44 drdo: what does a pair mean in clojure?

16:45 ayrnieu: where do you see 'a pair'?

16:45 drdo: (cond & clauses)

16:45 Macro

16:45 Takes a set of test/expr pairs.

16:45 Chouser: drdo: generally just alternating values

16:46 drdo: I'm trying something like (cond #{(true . 2)}) without much success

16:46 ayrnieu: ,(map #(cond (even? %) :even (odd? %) :odd) (range 10))

16:46 clojurebot: (:even :odd :even :odd :even :odd :even :odd :even :odd)

16:46 Chouser: drdo: no dotted pairs in Clojure

16:46 ayrnieu: drdo - Clojure doesn't have dot notation for cons pairs.

16:46 drdo: ok

16:46 Hun: there is no cons

16:46 drdo: user=> '(2 . 2)

16:46 (2 . 2)

16:46 ayrnieu: ,(map #(.getName %) (.getMethods java.util.Iterator))

16:46 clojurebot: ("hasNext" "next" "remove")

16:46 drdo: what is this then?

16:46 ayrnieu: ,(length '(2 . 2))

16:46 clojurebot: java.lang.Exception: Unable to resolve symbol: length in this context

16:46 durka42: a list of 2, ., and 2

16:47 ayrnieu: ,(count '(2 . 2))

16:47 clojurebot: 3

16:47 drdo: i see

16:47 kotarak: ,(cons 1 nil)

16:47 clojurebot: (1)

16:47 Hun: ,(cons 1 2)

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

16:48 Hun: so no `real' cons here

16:48 drdo: i see

16:48 durka42: (doc cons)

16:48 clojurebot: Returns a new seq where x is the first element and seq is the rest.; arglists ([x seq])

16:48 durka42: ,(cons 1 [2])

16:48 clojurebot: (1 2)

16:48 drdo: the documentation is somewhat misleading

16:48 for cond

16:48 "Takes a set of test/expr pairs." , i assumed "set" to mean a real Set

16:49 ayrnieu: what other word could it possibly use?

16:49 Hun: how could it possibly work on a set data structure?

16:49 ayrnieu: "Takes a list" "Takes a sequence" "Takes a ..."

16:49 drdo: ayrnieu: an example below that would clarify

16:49 kotarak: There was someone complaining about "pairs". I guess there is no non-misleading description....

16:50 Chouser: docs for such things are tricky. it's not a seq, and a "pair" is not a thing. :-P

16:50 ayrnieu: drdo - yes, an (exdoc foo) with examples would be nice.

16:50 Chouser: I've stumbled around trying to write the docstring for several such beasts.

16:50 drdo: :)

16:50 durka42: ~examples

16:50 clojurebot: examples is http://en.wikibooks.org/wiki/Clojure_Programming/Examples/API_Examples

16:51 durka42: how does condp work?

16:51 kotarak: (condp = x :a 5 :b 6 :c 7)

16:51 ayrnieu: it's helpful to realize that docstrings aren't documentation.

16:51 kotarak: durka42: is equivalent to (cond (= x :a) 5 (= x :b) 6 ...)

16:52 drdo: so it's like a "switch" from most other languages

16:52 except that you can specify the comparison

16:52 ayrnieu: it's more like a switch than cond is, yes.

16:53 durka42: ,(condp #(= (class %1) %2) 3 Integer "int" String "str")

16:53 clojurebot: java.lang.IllegalArgumentException: No matching clause

16:53 Chouser: ayrnieu: except that docstrings are just about the *only* documentation.

16:54 durka42: ,(condp = (class 3) Integer "int" String "str")

16:54 clojurebot: "int"

16:54 kotarak: drdo: yes and it can do (condp some coll #{:a :b :c} :>> #(println "first" %) #{:x :y :z} :>> #(println "else" %))

16:54 durka42: why didn't the first one work?

16:55 Chouser: I think the first arg to the predicate is each text value

16:55 kotarak: ,(condp instance? 3 Integer "int" String "str")

16:55 clojurebot: "int"

16:55 Chouser: ,(condp #(= (class %2) %1) 3 Integer "int" String "str")

16:55 clojurebot: "int"

16:55 hiredman: at least in java classes always are capitalized so you can differ between a Integer and a integer

16:55 kotarak: ,(condp some [1 :b 2] #{:a :b :c} :>> #(println "first" %) #{:x :y :z} :>> #(println "else" %))

16:55 clojurebot: first :b

16:56 kotarak: ,(condp some [:z :b 2] #{:a :b :c} :>> #(println "first" %) #{:x :y :z} :>> #(println "else" %))

16:56 clojurebot: first :b

16:57 drdo: another thing i've noticed is that the exception string isn't very helpful most of the times

16:57 hiredman: depends

16:57 you get familiar with what throws what exception

16:58 Chouser: the stack trace is probably more often helpful than the exception itself.

16:59 drdo: how can i get a stack trace?

17:00 Chouser: (.printStackTrace *e)

17:00 drdo: or are you using slime?

17:00 drdo: does slime work with clojure?

17:00 Chouser: some people seem to think so.

17:01 * shoover sighs

17:01 Chouser: shoover: ?

17:02 shoover: I'm shaking my head at you!

17:02 (and smiling a little)

17:02 Chouser: shoover: :-) got your presentation ready?

17:02 shoover: as I see the gauntlet is thrown down, my presentation visuals will be entirely in emacs and firefox

17:02 ayrnieu: drdo - http://github.com/jochu/swank-clojure/tree/master

17:03 Chouser: shoover: well, maybe you'll win me over, then.

17:03 durka42: speaking of firefox, are applets still broken on os x?

17:03 * kotarak thinks, Vim is catching up... http://kotka.de/OmniWithCompletion.tiff

17:03 cemerick: Chouser: we won't let them take you, man! :-P

17:03 shoover: kotarak: 404

17:03 cemerick: I've got my trusty wooden stake right here ;-)

17:04 technomancy: drdo: try my clojure-mode fork; it should help with configuring slime

17:04 Chouser: durka42: Last I knew, my applets still didn't work in os X. I'm not sure none do, though.

17:04 kotarak: oops--- embarrasing.... http://kotka.de/OmniWithPreview.tiff

17:04 technomancy: drdo: http://github.com/technomancy/clojure-mode/tree/master

17:04 hiredman: nice

17:05 * hiredman should maybe look into getting gorilla working

17:05 kotarak: hiredman: wait a bit, this version is not yet released.

17:05 Currently working on getting things half-way stable.

17:05 Consider it a teaser. :)

17:05 hiredman: does the omnicompletion depend on gorilla?

17:06 kotarak: Yes.

17:06 hiredman: :(

17:06 kotarak: But the Ruby stuff will be gone.

17:07 hiredman: I guess that is a plus

17:07 kotarak: I hope so....

17:07 Although Windows still makes problems.....

17:07 hiredman: I like slime.vim just sending stuff to a repl using screen

17:08 but omnicompletion...

17:08 kotarak: That is relatively simple, but will always clutter your history.

17:08 hiredman: kotarak: history of what?

17:08 kotarak: gorilla works in parallel to the repl. So the history will really only what you typed there.

17:08 Your screen repl.

17:08 Unless you work in a different one.

17:09 hiredman: eh?

17:09 kotarak: Ok. Never mind.

17:09 * hiredman fails to understand

17:09 hiredman: plus I can switch which repl I send stuff to with a simple variable change

17:11 but yeah, maybe the writting is on the wall and it is time to figure out gorilla

17:13 does gorilla work ok with non-gui vim?

17:13 shoover: Chouser: to answer your question, I'm not ready. I'm getting there, and excited to impart some new ideas on the unsuspecting masses of the Indianapolis .NET community

17:14 kotarak: hiredman: In general it should.

17:14 Chouser: shoover: well, you've got time yet. I'm looking forward to it.

17:14 kotarak: hiredman: although I never tested....

17:16 * durka42 tests

17:16 durka42: it works

17:16 the repl does anyway

17:17 hiredman: I do a lot of clojure at work on a windows machine ssh'ed into a freebsd machine

17:17 durka42: so does omnicompletion

17:17 kotarak: hiredman: the connection can also be forwarded via ssh.

17:18 hiredman: ugh, I wouldn't want to

17:19 would rather have everything on the unix side

17:19 kotarak: hiredman: whatever you like

17:19 durka42: autoclose.vim does not even pretend to work in the console

17:19 or mine anyway

17:20 hiredman: I use surround.vim

17:21 I think

17:21 acutally

17:21 I have both in ~/.vim/ somewhere

17:32 kotarak: Aehm. I just noticed a strange problem.

17:33 c|p: hello all

17:33 kotarak: When starting gorilla from the src/classes directories, everything works.

17:33 c|p: i like how this channel is logged, makes for a good read during programming class when im not doing anything

17:33 kotarak: But when starting the same code from a jar I get an exception.

17:34 java.lang.IllegalStateException: Var clojure.core/*1 is unbound.

17:34 hiredman: ...

17:34 kotarak: Is there some easy explanation for this?

17:35 hiredman: is using a jar the only change you made?

17:35 kotarak: Yes.

17:35 *1 should be bound via Var/pushThreadBindings.

17:35 And indeed it works, when not using the jar.....

17:36 Chouser: *1 is bound by clojure.main/repl, so if your code is getting called outside that, *1 won't be bound.

17:37 kotarak: The code looks like this (try (Var/pushThreadBindings { ..... #'*1 (something ...} (thunk) (finally (save *1 away "Exception here!") (Var/popThreadBindings)))

17:37 So my understanding is, that *1 should be bound inside the try.

17:38 and finally...

17:39 Chouser: hm

17:41 kotarak: here is the actual code: http://bitbucket.org/kotarak/gorilla/src/tip/src/de/kotka/gorilla/repl.clj

17:42 line 147 is the problem....

17:42 but only when executing from a .jar ......

17:43 Chouser: compiled, or from .clj (in the .jar)?

17:46 kotarak: Compiled, I guess. Both are in the .jar. But even when not using the .jar the cp is src:classes. So the compiled should be used in both cases, no?

17:46 Can also try the different combinations. Just a sec.

17:46 Chouser: if the .class file is available and newer than the .clj, it should use the .class (whether from a .jar or not)

17:48 kotarak: I tried only .class files from the directories and only .clj from the directories and both work.

17:49 Just a sec. Will build special jars.

17:52 Huh? Obviously something strange is going, since I use gen-class. So I need actually AOT compilation.

17:53 Why did src only work then? Have to check again. Sorry for the noise.

17:53 visage_: This might be a stupid question, but does clojure have a library manager like Ruby's 'gem'?

17:54 technomancy: visage_: no. the closest thing so far is ties

17:54 ~ties

17:54 clojurebot: ties is http://www.bitbucket.org/achimpassen/clojure-ties/wiki/Home

17:55 visage_: okay, thanks

17:55 technomancy: visage_: most people just bundle dependencies right now. it works since there aren't that many clojure libs... but in the future I suspect a package manager will become more important.

17:56 (ties is not actively developed, btw)

17:56 visage_: After rails, I blame ruby's success on gem. Having a package manager makes things so nice

17:56 Chouser: isn't that the OS's job, though?

17:56 technomancy: Chouser: the OS can't keep up

17:56 Chouser: hm.

17:57 danlarkin: aye, easy_install/PyPI for python is super useful

17:57 technomancy: Chouser: since devs can generally handle more hiccups, they are willing to put up with more of their own "test to make sure it works with the latest version" than your average apt-get user

17:58 Chouser: but I suspect you could build a clojure-specific package manager as a thin layer on top of apt-get. the difficult part is getting buy-in from library maintainers; no system can succeed without that.

17:59 visage_: It can get more complicated, though. Gem allows users to specify which library version to load, et cetera.

17:59 technomancy: yeah, you wouldn't get multiple-versions-at-once with apt-get

17:59 hiredman: gems are really annoying in my experience

18:00 kotarak: Chouser: thanks for your thoughts. Proxy generates also classes in classes/clojure/proxy/... These .class files were not included in the .jar file. The proxy in question was used before *1 was bound by Var/pushThreadBindings. => Exception => second Exception in the finally clause were *1 is used......

18:00 hiredman: my OS has a package manager, I don't need another.

18:00 kotarak: So the second Exception shadowed the first...

18:01 technomancy: hiredman: then you're stuck with 6-month to year-old packages.

18:01 plus the added burden of every library maintainer creating a .deb, an .rpm, and whatever the deuce macports uses... it just won't happen

18:02 hiredman: technomancy: oh, you mean I am stuck using software that is stable and has been released?

18:02 how terrible

18:02 technomancy: hiredman: well considering it excludes everything that's ever been written in clojure, I'd say that's pretty lousy

18:02 hiredman: *shrug*

18:02 Chousuke: hiredman: gems are just CPAN envy ;(

18:02 hiredman: ugh

18:02 CPAN

18:02 all of it

18:02 Chousuke: CPAN works well though.

18:02 Chouser: kotarak: ah. wow.

18:03 Chousuke: it's too much work to package all of it

18:03 I guess that's the rationale behind gems and whatnot as well

18:03 technomancy: I'm just plain not going to ever build an .rpm for my libraries.

18:03 hiredman: ugh

18:04 who whould ever want to do that?

18:04 technomancy: if I only target a single format, I'll be much more inclined to actually make a release.

18:04 hiredman: (build an rpm)

18:04 Chousuke: I don't really mind them being outside package management either, as long as they know their place.

18:04 technomancy: hiredman: not everyone is lucky enough to have apt-get installed on their box... or so I hear.

18:05 Chousuke: I could actually install it, but I prefer macports :P

18:05 * technomancy shudders

18:05 dreish: hiredman: So what's your solution when your lib requires libs A, B, and C, B requires D, E, and F, etc.? Just tell people to spend a weekend hunting for dependencies?

18:06 technomancy: anyway, the point is that nobody can agree on a single OS-level packager, so coherence is just not going to happen

18:06 hiredman: actaully, outside of openoffice, I dunno of any opensource project besides the freebsd project that builds packages of opensource software for freebsd

18:07 Chousuke: perhaps that is because building packages for freebsd is easiest if you're part of the project?

18:07 you don't really build packages anyway; just ports :/

18:08 hiredman: Chousuke: packages are built for every release

18:08 for a very large part of ports

18:09 so pkg_add -r will fetch a precompiled package and install it

18:09 so, uh, ports has no problem with people just providing a source tarball

18:10 dreish: Sure.

18:10 a weekend

18:10 pfft

18:10 in the README "this requires version X of lib Y from url Z"

18:11 technomancy: "...which requires version X` of Y` but conveniently fails to give a URL for download"

18:11 "and then X` depends on X``, but not the latest version; that will blow up..."

18:11 ad nauseum

18:12 dreish: I guess that's when you tell people they're using the incorrect OS. ;-)

18:13 hiredman: anyway, I am not happy with gems or ant or maven

18:25 lisppaste8: Chouser pasted "infix fn" at http://paste.lisp.org/display/75230

18:25 Chouser: don't shoot me or anything.

18:26 hiredman: cute

18:26 Hun: shoot!

18:30 Chousuke: Chouser: that last infix example is perverse.

18:35 Chouser: maybe put it in contrib next to macro-apply in the evil stuff section? :>

18:36 Hun: that reads like the evil that haskellers do

18:36 lives on and on...

18:36 durka42: what is the point of a fn that calls a macro?

18:36 hiredman: I could just alias � to partial and use that in place of my pl macro

18:37 or comp

18:37 or whatever I was using it for

18:38 Hun: durka42: what is the point of a fn using numbers?

18:38 the concepts are orthogonal

18:38 durka42: no, i mean

18:38 Chousuke: interesting though that the infix thingy isn't even a macro.

18:38 durka42: oh, i see

18:38 wait why the indirection then

18:38 * durka42 is slow today

18:39 Hun: durka42: so that the args don't have to be quoted

18:39 durka42: to allow destructuring by infix*

18:40 Chousuke: Hun: I don't think it's for that

18:40 Hun: then i understood that wrong

18:40 Chousuke: because it's a function you can actually do (infix (+ 5 7) * [3 + 4])

18:41 it's a function of functions and values into a value :(

18:42 I think if someone were in my room with me right now they could hear my mind making a boggly sound.

18:42 ayrnieu: I had that problem, but I got it resealed.

18:54 Chousuke: hmm, that infix thing seems to actually be trivial to transform into a macro

18:55 no, wait, my mistake :(

18:55 hmm...

18:55 no, wait, it actually works.

18:57 lisppaste8: Chousuke annotated #75230 with "macrofied" at http://paste.lisp.org/display/75230#1

18:57 Chousuke: (infix (+ 5 7) * [3 + 4]) expands nicely into (* (+ 5 7) (+ 3 4)) at least :)

19:06 durka42: er

19:06 #<CompilerException java.lang.NoClassDefFoundError: clojure/lang/Agent (REPL:59)>

19:06 that's not good

19:22 Chouser: Chousuke: yeah, that's probably better. faster at runtime and only groups on literal vectors, not expressions that return vectors.

19:23 Chousuke: it was surprisingly easy though, given your function solution

19:23 I'm tempted to believe there is some situation where it blows up.

19:24 Chouser: (infix 5 + 2 * 3 < 6 + 6)

19:28 Chousuke: adding < to the ranking seems to have no effect :/

19:29 this is not the time to wonder about that though. must sleep.

19:31 ozy`: haskell copes pretty well with allowing user-defined operators, without knowing operator precedence at compile time

19:31 er, at parse time, I mean

19:32 ayrnieu: oh? How interesting.

19:33 ozy`: you can even modify operator precedence in local scopes, as we just discovered in #haskell :p

19:34 durka42: that sounds...confusing

19:36 ozy`: it helps that unary operators aren't allowed

19:37 ayrnieu: you have to see features like that in the context of Haskell's community, which is something like Perl's community in the garden of Eden: detached from all shame or need to do any work.

19:38 what would you do in that circumstance? Why, you'd golf your programs forever, and react to pointlessly cryptic code with joyful curiousity.

19:40 Chouser: that's a beautiful line.

19:44 clojurebot: svn rev 1266; IDeref print method honors *print-level*, patch from Chouser

19:45 lisppaste8: Chouser annotated #75230 with "fix for macro version" at http://paste.lisp.org/display/75230#2

19:48 durka42: next: allow (infix Math/sqrt 9)

19:50 wait, that already works with binary fns

19:50 ha

19:50 (infix 3 Math/atan2 5)

19:53 (infix "%s = %d" String/format (into-array Object ["nine" 9]))

19:54 ozy`: now that's just gratuitous

19:54 ,''(quote)

19:54 clojurebot: (quote (quote))

19:59 svn rev 1267; catch method redef in proxy, patch from jbondeson

20:23 hiredman: clojurebot may need a qdb feature

20:23 just so I have a place for what ayrnieu said

20:35 erohtar: is there an official version of clojure?

20:36 hiredman: clojurebot: svn?

20:36 clojurebot: svn is http://clojure.googlecode.com/svn/trunk/

20:36 hiredman: ^-- official

20:38 erohtar: hiredman: is there trouble with slime/swank with the latest version?

20:39 hiredman: dunno

20:40 not an emacs user

20:40 clojurebot: emacs?

20:40 clojurebot: "Learning Emacs and SLIME was just about the most painful computer experience I've ever been through."

20:41 erohtar: haha, okie - thanks!

20:53 any idea why i get this error - clojure.lang.MultiFn.<init>(Lclojure/lang/IFn;Ljava/lang/Object;)V (NO_SOURCE_FILE:0)

20:53 oops

20:53 java.lang.NoSuchMethodError: clojure.lang.MultiFn.<init>(Lclojure/lang/IFn;Ljava/lang/Object;)V (NO_SOURCE_FILE:0)

20:55 Chouser: erohtar: what are you trying to do?

20:55 we'll be most able to help you if you paste your code and the full stack trace

20:55 lisppaste8: url

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

21:23 erohtar: let me do that

21:24 lisppaste8: erohtar pasted "clojure-json trouble" at http://paste.lisp.org/display/75236

21:25 erohtar: chouser: that generates a stack trace on the latest clojure

21:25 * danlarkin 's ears perk up

21:25 erohtar: Caused by: java.lang.NoSuchMethodError: clojure.lang.MultiFn.<init>(Lclojure/lang/IFn;Ljava/lang/Object;)V

21:25 at org.danlarkin.json.encoder__init.load(Unknown Source)

21:25 at org.danlarkin.json.encoder__init.<clinit>(Unknown Source)

21:25 at java.lang.Class.forName0(Native Method)

21:25 at java.lang.Class.forName(Class.java:247)

21:25 at clojure.lang.RT.loadClassForName(RT.java:1512)

21:25 etc etc

21:26 danlarkin: I guess I should update clojure and check it out hm

21:26 erohtar: that would be awesome :D

21:26 i know it works on svn rev 1195

21:26 which is way old

21:28 hiredman: (require '[org.danlarkin.json :as json])

21:28 is what that should be, I believe

21:29 danlarkin: ok I just updated and rebuilt clojure and (require '(org.danlarkin [json :as json])) worked for me

21:32 hiredman: danlarkin: oh

21:32 erohtar: hmmm

21:33 let me experiment some more

21:34 danlarkin: erohtar: does it work if you just fire up the REPL and paste that in?

21:36 erohtar: danlarkin: no

21:38 danlarkin: can you paste the whole stacktrace to lisppaste?

21:48 ayrnieu: http://groups.google.com/group/comp.lang.lisp/browse_thread/thread/0d05837df1efe075#

21:54 clojurebot: svn rev 1268; added Counted interface and counted? predicate implement stack/heap safe count in RT stack-safe count in ASeq/Cons, patch from Chouser

22:04 svn rev 1269; repl read refactoring, patch from scgilardi

22:08 notyouravgjoel: are there any datastructures that have 0(1) seek time?

22:08 at least, those that are native to clojure?

22:09 danlarkin: hash maps are pretty close

22:10 Chouser: maps and vectors are effectively O(1)

22:10 hiredman: by native to clojure, you mean those provided by clojure.lang?

22:10 notyouravgjoel: yeah

22:11 danlarkin: oh yes vectors too

22:11 notyouravgjoel: that is, I don't need to start using the java stuff

22:12 ayrnieu: notyour - http://blog.higher-order.net/2009/02/01/understanding-clojures-persistentvector-implementation/

22:13 notyouravgjoel: thanks

22:14 hiredman: the datastructures from clojure.lang are java stuff

22:14 clojurebot: svn rev 1270; improved Maven integration, patch from hlship [issue 70]

22:14 notyouravgjoel: sure, I mean using the (. ...) methods

22:14 Chouser: well, they're written in Java, but they're pretty clumsy to use from java

22:15 notyouravgjoel: right

22:15 hiredman: :P

22:16 ayrnieu: notyour - there are already functions to deal with Java arrays, and you can write functions to prettify them for your purposes.

22:20 notyouravgjoel: oh i see; would they be faster than vectors, then?

22:20 ayrnieu: that depends on what you're doing.

22:21 notyouravgjoel: I'm creating a constant datastructure, and I'm trying to get fast access time

22:22 Chouser: an array should do very nicely

22:22 ayrnieu: if you can't describe the problem better than that, you should use vectors and worry about this after your profiler leads you back this way.

22:23 until.

22:23 Chouser: yeah, ignore me. do what ayrnieu says

22:23 notyouravgjoel: ah, thanks

22:23 I'm not sure what exactly you're looking for in a description

22:24 ayrnieu: well, think of your data structure as a mathematical function with a domain and a range.

22:25 immediately you realize that you should have something to say about the domain and the range. Are you mapping (range 100) exactly to (range 100)? Then you don't need a data structure, just the identity function.

22:26 if you're mapping arbitrary objects to arbitrary objects, then a hash makes more sense than a Java array.

22:27 notyouravgjoel: it maps integer edge weights between nodes i and j, using 2d colletions

22:27 which is why arrays do seem fairly intuitive

22:34 clojurebot: svn rev 1271; fixed ensure to use deref

22:35 gnuvince_: Lots of activity tonight

22:35 stimuli: Hi

22:37 ayrnieu: http://compulsiontocode.blogspot.com/2009/01/bowling-with-clojure.html

22:39 stimuli: I think rules of bowling are harder than the clojure

22:40 ayrnieu: ,((fn [[x1 x2 x3 & rst]] [x1 x2 x3 rst]) '(30 60 90 120 150 180 210 240 270 300))

22:40 clojurebot: [30 60 90 (120 150 180 210 240 270 300)]

22:44 ayrnieu: that doesn't quite get you to his purposes.

22:44 stimuli - I think code kata doesn't count unless the result is somewhat idiomatic.

22:45 hiredman: yeah

22:45 stimuli: true

22:50 notyouravgjoel: aside from YourKit, any suggestions on profilers?

23:02 stimuli: I'm prolly going to want a good profiler soon myself

23:03 http://java-source.net/open-source/profilers

23:03 I haven't used any of those ....

23:19 blbrown: the eclipse clojure plugin is not working all that well...so far

23:35 technomancy: so is it right that you can't have circular dependencies between namespaces?

23:46 arohner: technomancy: you're not supposed to

23:47 there's a bug that you don't get an exception when you do have a circular dependenc

23:47 http://code.google.com/p/clojure/issues/detail?id=3&colspec=ID%20Type%20Status%20Priority%20Reporter%20Owner%20Summary

23:48 you used to get an exception when clojure detected a circular load, and rhickey disabled that to make AOT work. The bug I just linked is the bug to re-enable the exception

Logging service provided by n01se.net