#clojure log - May 13 2010

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

0:02 brweber2: what is the current state of creating a Java Enum in clojure?

0:09 _brian2_: technomancy : whats the right way to use lein and clojars to develop patches for pre-existing libraries do you put [lein-clojars "0.5.0"] in project file and take the original dependenicies out, or leave in, or am I on the wrong track?

0:53 Raynes: technomancy: ping

0:54 technomancy: _brian2_: you don't need the lein-clojars plugin; just scp pom.xml foo.jar clojars@clojars.org:

0:54 Raynes: pongo

0:54 _brian2_: and be sure to change the group-id to org.clojars.brian2

0:54 Raynes: Is there a way to have global plugins that don't require a project?

0:55 I have a couple of ideas for some plugins, but they wouldn't be very useful if they had to be added to a project's dependency list.

0:55 technomancy: Raynes: it's on the list for 1.3, but I haven't started it yet

0:55 Raynes: Alright. :\

0:55 technomancy: Raynes: however, a guy called "sids" said he might start prototyping it when I told him about my plans

0:55 you should ping him, see if you can help put something together

0:56 _brian2_: technomancy : what about the original dependencies, do I leave them in?

0:56 technomancy: _brian2_: yeah, you should only change the group-id

0:57 _brian2_: technomancy : ok, so they wont over write the changed files (?)

0:57 technomancy: _brian2_: you won't have permissions to upload anything that will overwrite the existing one

0:58 _brian2_: that's why you have to change the group-id

0:58 _brian2_: technomancy : ok

1:02 technomancy : I'm not sure what this means "scp pom.xml foo.jar clojars@clojars.org:

1:03 whats foo.jar

1:03 i know I have pom.xml

2:11 vIkSiT: hello all

2:11 anyone know where the code for the sort function is?

2:13 ah found it (core.clj)

2:24 hmm, in a function defnition - what exactly does this refer to ? (defn myfn [[a & b]]) - what are a and b?

2:24 and the & symbol.

2:26 TheBusby: it indicates that the function expects a single argument which should be a list/vector/seq type

2:26 and that a will be the first element, and b will be every remaining element

2:26 ,(let [[a & b] [1 2 3 4]] [a b])

2:26 clojurebot: [1 (2 3 4)]

3:06 maxhodak: is there a way to round to arbitrary precision in the clj api?

3:06 or do i need to do it myself?

3:10 LauJensen: Morning all

3:21 MadWombat: hello

3:22 I am trying to run a jetty server from a lein target, for this I need to pass it a routes function, so I use a project key for it. But so far I cannot seem to get it working, I get java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.IFn

3:23 LauJensen: MadWombat: M-x gist-region plz

3:23 MadWombat: LauJensen: ?

3:23 LauJensen: MadWombat: Are you an Emacs user?

3:23 MadWombat: LauJensen: yes

3:24 I don't have gist-region function

3:24 LauJensen: Ok, then get gist.el, mark the code which is causing the problem, hit M-x gist-region and the code will be uploaded to github and the url will be in your kill-ring, then you can paste it here and we can all have a looksie :)

3:24 http://github.com/defunkt/gist.el/blob/master/gist.el

3:25 MadWombat: And from now on, when you see somebody gisting, you can just hit M-x gist-fetch, and get their code right in a new buffer

3:26 MadWombat: LauJensen: OK, I will need to clean up the code a bit

3:31 http://gist.github.com/399596

3:32 there are some extraneous deps, but you can get the idea

3:33 I got the error when I tried to quote the app method, so I removed the quote and now I don't get any errors, but I don't get the response either

3:36 and here is my app code http://gist.github.com/399601

3:39 LauJensen: MadWombat: I haven't deployed on GAE yet, but your 'handler' isn't claiming any route. AFAIK run-jetty's handler is a combination of routes and handlers, ["/"] (fn [r] (println r))

3:41 http://github.com/weavejester/compojure/blob/master/src/compojure/core.clj#LID54

3:41 Here is how Compojure compiles it routes if your familiar with that. If not, 'app' in Moustache is actually simpler, but its just a pairwise collection

3:42 MadWombat: that might explain why I get Problem accessing /. Reason: NOT FOUND

3:42 LauJensen: yea, and if you want routing - I would recommend checking out Moustache

3:43 MadWombat: LauJensen: I don't need much routing, that is why I don't even use compojure

3:44 LauJensen: k

3:44 MadWombat: strange thing though, if I miss the gae-app setting entirely, the same handler (default) seems to work

3:44 LauJensen: Sounds like a bug

3:45 MadWombat: LauJensen: I am trying to implement something similar to what hackers-with-attitude post described, but with leiningen instead of ant and running recent ring instead of old compojure

3:46 LauJensen: Look forward to seeing it in action

3:47 MadWombat: hmm... readme for ring seems to describe app the same way, it is a function that takes request object and returns response

3:47 http://github.com/mmcgrana/ring

3:50 LauJensen: You're right

3:50 Try running with his code, ie. associating to the req

3:53 MadWombat: interesting... seems like the app source directory is not on the classpath

3:55 seems like lein is not including the source in the classpath when running tasks

3:55 I tried to hardcode the route function and got an error

3:55 tomoj: I don't think that's a bug

3:56 MadWombat: well, wonder if I can get around that

3:56 tomoj: dunno.. maybe look into the source for e.g. 'lein test'?

3:56 since that must run some code in the subclasspath

3:57 MadWombat: good idea

3:57 tomoj: I shouldn't really be giving advice, I don't actually know much at all about lein's innards

3:57 MadWombat: :)

3:58 me neither :)

3:59 Raynes: LauJensen: You live in Denmark, right?

3:59 LauJensen: MadWombat: Perhaps if you've too much syntax like #() or named your variables something like 'chunk', technomancy may have put in easter eggs which prevents what he thinks is ugly code - you know, like he does with project names

3:59 Raynes: Still here, yes

3:59 Raynes: Just wondering. Oliver Twist comes from Denmark.

4:00 LauJensen: Here I would counter with someone famous from Alabama, but you're the only one I know Im afraid :|

4:00 MadWombat: LauJensen: no, I don't much like macro shorthands myself

4:00 Raynes: LauJensen: Gomer Piles came from Jasper, 22 miles east of my home. But I'm not talking about the book.

4:01 LauJensen: Whos' Gomer ?

4:01 Raynes: $wiki Gomer Piles

4:01 sexpbot: First out of 27 results is: Gomer Pyle - Wikipedia, the free encyclopedia

4:01 http://en.wikipedia.org/wiki/Gomer_Pyle

4:01 Raynes: $wiki Oliver Twist tobacco

4:01 sexpbot: First out of 48 results is: Oliver Twist Tobacco - Wikipedia, the free encyclopedia

4:01 http://en.wikipedia.org/wiki/Oliver_Twist_Tobacco

4:01 LauJensen: Pyle ?

4:01 or Piles?

4:02 Raynes: I thought it was Piles. This is before my time, mind you.

4:04 LauJensen: Nice

4:04 Raynes: A couple of other, generally famous people have come from Alabama. None recently though. Unless you count that American Idol winner a few years ago.

4:04 Gray haired dude.

4:05 zmila: maxhodak, you can use (format )

4:05 ,(format "aaa %10.4f zzz" Math/PI)

4:05 clojurebot: "aaa 3.1416 zzz"

4:07 Raynes: Does clojurebot cut out duplicate whitespace?

4:07 $(format "aaa %10.4f zzz" Math/PI)

4:07 sexpbot: result: aaa 3.1416 zzz

4:09 zmila: no idea about spaces

4:11 Raynes: Yeah.

4:11 He must, because it comes out the same way in the REPL.

4:13 zmila: ,(str "oaeu" " " "aoeu")

4:13 clojurebot: "oaeu aoeu"

4:13 zmila: repl of CCW inside Eclipse does not cut

4:16 TheBusby: how do you include a quotation mark character in a string?

4:16 tomoj: ,"\""

4:16 clojurebot: "\""

4:16 TheBusby: ,(str "\" this doesn't work")

4:16 clojurebot: "\" this doesn't work"

4:16 tomoj: (println "\" this doesn't work")

4:16 ,(println "\" this doesn't work")

4:16 clojurebot: " this doesn't work

4:16 TheBusby: so what's the trick the for str and format then?

4:17 tomoj: str is the identity on strings

4:17 I don't think there is a trick

4:17 TheBusby: ahh

4:17 Chousuke: clojurebot prints strings with quotes

4:17 ,"foo"

4:17 clojurebot: "foo"

4:18 Chousuke: ,(print "foo")

4:18 clojurebot: foo

4:18 TheBusby: ,(println "$(println \",(println \\\"haha\\\")\")")

4:18 clojurebot: $(println ",(println \"haha\")")

4:18 sexpbot: result: ,(println "haha")

4:19 tomoj: does sexpbot always use "result:" for this reason?

4:20 if it didn't, I wonder if you could set up an infinite loop

4:20 Raynes: tomoj: Yes.

4:20 tomoj: Whether or not an infinite loop is possible, I don't want to find out. Which is why result: is there.

4:20 :)

4:21 TheBusby: some how I can imagine many hours wasted in pursuit of that...

4:23 tomoj: seems like you'd need something quine-like

4:24 never thought about quine-like things with period>1 before

4:26 TheBusby: ,(println ",(println \"No quines here\")")

4:26 clojurebot: ,(println "No quines here")

4:27 tomoj: (and (= (eval a) b) (= (eval b) a) (not= a b)) -- possible?

4:28 Raynes: $google rosettacode quine clojure

4:28 sexpbot: First out of 7 results is: Category:Clojure - Rosetta Code

4:28 http://rosettacode.org/wiki/Category:Clojure

4:28 Raynes: There is a quine example in there somewhere.

4:28 tomoj: I don't think I can work with it, unfortunately :(

4:28 I've never understood a quine so it seems unlikely I'll solve my puzzle

4:29 TheBusby: ahh, that's the same as the old lisp one

4:30 tomoj: hmm http://www.pagiamtzis.com/articles/iterating-quine-with-transient/

4:30 sexpbot: "Kostas Pagiamtzis: Oscillating (Iterating) Quine with Initial Transient"

4:44 Raynes: cgrand: ping

4:57 MadWombat: damn, I hate jetty, you start the server by accident and it keeps running in the background with no way to stop it :(

4:57 now I have to restart the swank AGAIN

5:15 arbscht: MadWombat: a naive solution is to save a reference to your servlet, and call .stop on it

5:59 somnium: are there any known corner cases where you cant recur out of very deeply nested let/if statements (despite being in tail-position) ?

6:07 Chousuke: none known to me :P

6:12 somnium: hmm, the macroexpansion is hard to read, but chaning recur to the function name works

6:12 http://gist.github.com/399685

6:18 ah, I am blind, nm ...

7:04 Raynes: LauJensen: You use, Chrome, don't you?

7:04 LauJensen: Not anymore Raynes

7:06 Raynes: I need somebody to confirm that automatic scrolling to the bottom of this div isn't working in Chrome. Not that I give a damn, but it's not working here either. It was working until I put it in the iframe. It works fine in FF.

7:06 tcrayford: Raynes: I have chrome installed and stuff (mac though)

7:07 Raynes: If anybody who is using Chrome has a moment, please navigate to http://tryclj.licenser.net/ and enter (doseq [x (range 1 100)] (println x)) and tell me whether or not it scrolls all the way to the bottom of the div properly.

7:07 I mean, I've tried three different ways of scrolling, and none of them work in Chrome, so if it doesn't work, it's beyond my abilities to fix it.

7:07 tcrayford: scrolls all the way to the bottom here

7:07 Raynes: I'd just like it confirmed.

7:07 tcrayford: on chrome

7:07 Raynes: Oh, good. It must just be my Chrome.

7:08 Thanks.

7:08 tcrayford: even on a second run

7:08 LauJensen: Raynes: Scrolls fine on Linux as well

7:08 tcrayford: what version fo chrome are you using?

7:08 Raynes: Uh. /me checks

7:08 5.0.375.38 beta

7:08 tcrayford: on windows?

7:09 Raynes: No.

7:09 Linux.

7:09 tcrayford: :S

7:09 ho hum

7:09 Raynes: Weird.

7:09 tcrayford: I can fire up a windows box if you want it tested on there as well

7:09 Raynes: At least it's working for everyone else. :)

7:09 I'd definitely appreciate it, but don't go out of your way to do so. :p

7:09 tcrayford: it takes like 5 minutes, so meh

7:10 Raynes: <3

7:10 tcrayford: *waiting for his very very slow windows box to boot*

7:10 * Raynes does a hard restart of Chrome to see if it fixes it.

7:11 spariev: heh, Chrome on Windows 7, doesnt scroll

7:11 Raynes: No dice.

7:11 It works for most people. This is the most I can ask of my budding web development skills.

7:11 :)

7:12 * tcrayford fails

7:12 tcrayford: turned windows box on, but forgot to plug in ethernet

7:12 so synergy timed out

7:12 also spariev just gave you a windows thing

7:12 so no need for me now

7:13 Raynes: Indeed. Windows result: suckage.

7:13 tcrayford: surprise surprise

7:13 rsynnott: Raynes: are you using the dev version of chrome?

7:13 Raynes: Luckily, I don't know many Clojure people on Windows, and nobody outside of Clojure people would have a good reason to use tryclojure.

7:13 rsynnott: the latest one (5.0.396) is pretty broken

7:13 Raynes: rsynnott: Whatever came off of the official chrome site.

7:14 rsynnott: Raynes: there are three channels, though

7:14 (release, beta and dev)

7:14 Raynes: I'm on the beta channel.

7:15 AWizzArd: Is the Java-Plugin working well with Chrome?

7:15 Now as we know how to run any applet html+js is no longer required :)

7:20 LauJensen: Raynes: uhm... scroll actually doesn't work in IE6

7:20 Raynes: I care so little about IE6 that you can't even see the care if I put it in a clear crystal cup.

7:20 LauJensen: Careful with that :)

7:21 I did a client site not 6 months ago, where in the first month 10% of all visitors were IE6 users

7:21 To avoid having to redesign I had to ban all of their IPs in iptables

7:21 (j/k)

7:21 Raynes: If a Clojure developer is using IE6 for anything south of testing their websites, they should be shot to death by a firing squad.

7:21 :p

7:21 somnium: http://ajaxian.com/archives/jquery-one-line-plugin-to-crash-ie6

7:21 sexpbot: "Ajaxian » jQuery one-line plugin to crash IE6"

7:22 LauJensen: somnium: perfect

7:22 somnium: Raynes: just add this you'll be all set :)

7:22 AWizzArd: yes, write Applets or WebStart applications in Clojure, not html+js

7:22 Raynes: I should add one of those condescending "Get a better browser" popups.

7:22 somnium: <3 js

7:22 AWizzArd: I prefer Clojure over js.

7:22 Raynes: I have a love/hate relationship with js.

7:22 AWizzArd: hehe (:

7:22 why?

7:22 clojurebot: why not?

7:22 Raynes: I love that it works (sometimes), but I hate that it's not Clojure.

7:23 LauJensen: Raynes: excellent point

7:23 AWizzArd: The good news is: we can write small and big apps in Clojure and distribute them with the browser.

7:24 Swing can be used, or clj-pivot for example, for the gui. You will have pmap on the client, can connect any host, can use Contrib and all libs you've written yourself.

7:25 abrenk: AWizzArd: so you fixed your webstart classloader problem?

7:25 AWizzArd: yes

7:25 somnium: AWizzArd: its an open standard, things like nodejs and cappucino ..., more reasons to like it than to hate it

7:25 abrenk: no fun dealing with stuff like that i suppose

7:26 LauJensen: We also have both clj-javascript and scripjure - though I dont know how much mileage they give you these days

7:26 AWizzArd: The JVM and Clojure are yeears ahead of what can be done with js. That is a pretty good reason for using that technology instead of something that is broken and works differently under each browser.

7:27 LauJensen: AWizzArd: well, can you do this? http://www.p01.org/releases/512b_jspongy/jspongy.htm

7:27 Raynes: But making it an applet would require making it an applet. :(

7:28 I thought the general consensus was that applets are teh dead.

7:28 somnium: AWizzArd: the browser's each provide a separate api that js can use

7:28 AWizzArd: LauJensen: yes, anything that can be done with the JVM+Clojure.

7:28 Raynes: you can use WebStart then.

7:29 LauJensen: AWizzArd: I dare you. Make a 512b raytraced menger sponge - and then explain the math to me

7:29 I only ask the you get 10% of the fps that the js version makes

7:29 AWizzArd: LauJensen: Java is not able to do it?

7:30 LauJensen: AWizzArd: No I very much doubt it

7:30 AWizzArd: LauJensen: how comes that Jake 2 runs with 250 fps? http://bytonic.de/html/jake2.html

7:30 sexpbot: "Bytonic Software"

7:31 LauJensen: AWizzArd: Lets try again: Make a _512b_ raytraced menger sponge. Doing that in Clojure require a huge amount of coercing numbers to primitives which in itself will put you over 512b

7:32 It might actually be possible with Penumbra now that I think of it

7:32 AWizzArd: Why should we try this? Why not compare software in general?

7:32 Chousuke: the JVM is in some sense ahead of javascript virtual machines

7:32 but on other areas, it's behind

7:32 the languages however don't matter.

7:33 AWizzArd: This is just a specific usecase. I could also ask for doing Clojure one-liners in JS, which suddenly would require lots of code.

7:34 There are reasons why we are in #Clojure and not in #JavaScript ;)

7:34 somnium: AWizzArd: thats like comparing clojure to java, there many many languages targeting javascript as a compile target

7:35 * AWizzArd is not aware of any Clojure implementation beside the one for the JVM that is as advanced as the one for the JVM.

7:35 AWizzArd: Also, what about the billions of man-hours that went into developing libs for the JVM? To use them all we would first need a lot of work to be done in JS.

7:35 Raynes: There is always #clojure-casual

7:38 Chousuke: did someone claim that JS as a platform is even nearly as mature as the JVM? :P

7:38 it's barely gotten started.

7:39 AWizzArd: true

7:39 Chousuke: the speed of development is nothing short of astounding but that's another thing :)

7:40 AWizzArd: Yes, in the next decade js can become a major player.

7:40 Chousuke: you mean in ten years or within the next ten years?

7:40 AWizzArd: within

7:40 Chousuke: right. indeed.

7:40 and it's not a bad language either

7:41 though I don't like how all the JS engines are pretty much tied to browsers :/

7:41 maxhodak: i need to voice my frustration that clojure is totally unable to deal with multidimensional primitive arrays in any reasonable way

7:41 AWizzArd: Yes

7:41 Chousuke: maxhodak: don't worry, so's java as far as I know :P

7:41 AWizzArd: (the “Yes” was for Chousuke)

7:41 maxhodak: Chousuke: java can do foo[i][j] ...

7:42 Chousuke: maxhodak: it's easier (and I think faster) to just use a single-dimension array

7:42 maxhodak: clojure has a confusing amap method which entirely complicated the issue of traversing a 2d array

7:42 i'm being passed a 2d array from a lib

7:42 AWizzArd: ,(doc aget)

7:42 clojurebot: "([array idx] [array idx & idxs]); Returns the value at the index/indices. Works on Java arrays of all types."

7:43 maxhodak: ,(doc amap)

7:43 clojurebot: "([a idx ret expr]); Maps an expression across an array a, using an index named idx, and return value named ret, initialized to a clone of a, then setting each element of ret to the evaluation of expr, returning the new array ret."

7:43 maxhodak: what?

7:43 clojurebot: what is exceptions

7:43 Chousuke: that's not very nice for 2d arrays, right.

7:43 maxhodak: anyways

7:43 mmarczyk: aren't Java's 2d arrays just arrays of arrays...?

7:44 Chousuke: yes.

7:44 mmarczyk: right, so (aget foo i j) = foo[i][j]

7:44 Chousuke: that is, the type of a[i] is an array type

7:44 AWizzArd: Maybe it would be indeed easier to make foo one-dimensional as Chousuke suggested?

7:44 mmarczyk: and you can roll your own loop

7:44 maxhodak: ,(count (int-array 2))

7:44 clojurebot: 2

7:45 Chousuke: but yes, clojure really isn't intended for array processing :P

7:45 maxhodak: yeah

7:45 LauJensen: maxhodak: I did an article on Fluid Dynamics, its basically a long piece on how to get the most out of Java arrays from Clojure

7:45 Chousuke: the easiest thing to do is probably to copy the array contents into a vector

7:45 AWizzArd: Though, with a few hours of work you could come up with respective fns :)

7:45 maxhodak: idk. one of the biggest draws of clojure was the ability to use java libraries

7:45 but ive been doing a lot of work with machine learning libraries recently

7:45 Chousuke: maxhodak: yeah but arrays are not nice from an api perspective

7:45 maxhodak: and i feel like clojure is *not* making things go faster

7:46 Raynes: Heresy.

7:46 Chousuke: there are no interfaces and it's just "raw data"

7:46 maxhodak: which is kind of the normal promise of a more sophisticated language like lisps

7:46 AWizzArd: Well, this is Lisp. You don't need to wait for anyone to let you work with arrays as you wish. You can implement that yourself.

7:46 maxhodak: i spend hours just fighting with stuffing things into data structures

7:46 Chousuke: maxhodak: arrays are about the only thing that clojure doesn't work well with in my experience

7:47 I wonder if a clojure.contrib.arrays would be useful...

7:47 AWizzArd: hmm yeah, could be nice

7:47 Chousuke: but what could it contain?

7:47 maxhodak: AWizzArd: that works when the abstraction is obvious or something is very repetitive; in this case it still feels like a lot of one-off data structure stuffings

7:47 LauJensen: http://www.bestinclass.dk/index.php/2010/03/functional-fluid-dynamics-in-clojure/

7:47 sexpbot: "Functional Fluid Dynamics in Clojure | BEST IN CLASS"

7:47 LauJensen: maxhodak: those arrays go pretty fast

7:48 AWizzArd: Chousuke: we can ask maxhodak what he needs right now. That is something that could go into such a contrib.

7:48 maxhodak: Chousuke: into-vec, for one

7:48 mmarczyk: maxhodak: if you need a generalised amap for traversing 2d arrays, then pick your order of traversal and write one

7:48 maxhodak: which would translate a prim array into a vec-of-vec[-of-vec...]

7:48 AWizzArd: maxhodak: can you list some more things that you wish you could write?

7:48 (my-amap ...)? Something like that?

7:49 Chousuke: hm

7:49 maxhodak: AWizzArd: i can write that one

7:49 (into-vec)

7:49 AWizzArd: so basically what you want is a fn into-vec

7:49 maxhodak: i'm not a total novice. this has just been frustrating

7:49 AWizzArd: yes, can be frustrating

7:49 I am just asking you which fns you would wish to exist

7:49 so that it would not be frustrating

7:50 maxhodak: i mean, the goal would be to make it so we didn't have to deal with arrays

7:50 AWizzArd: ,(into [] (make-array String 4 10))

7:50 clojurebot: [#<String[] [Ljava.lang.String;@843189> #<String[] [Ljava.lang.String;@d03e90> #<String[] [Ljava.lang.String;@1bb9091> #<String[] [Ljava.lang.String;@1103d33>]

7:50 maxhodak: right now there are a bunch of fns in core for clojure.lang.* -> [L

7:50 but not the other way around

7:51 ,(into [] (into [] (make-array String 4 10)))

7:51 clojurebot: [#<String[] [Ljava.lang.String;@114dc12> #<String[] [Ljava.lang.String;@7c297a> #<String[] [Ljava.lang.String;@1871a46> #<String[] [Ljava.lang.String;@cdec7f>]

7:51 maxhodak: er

7:51 raek: you can always (seq) an array...

7:51 AWizzArd: ,(vec (map #(into [] %) (into [] (make-array String 4 10))))

7:51 clojurebot: [[nil nil nil nil nil nil nil nil nil nil] [nil nil nil nil nil nil nil nil nil nil] [nil nil nil nil nil nil nil nil nil nil] [nil nil nil nil nil nil nil nil nil nil]]

7:51 maxhodak: ,(map #(into [] %) (into [] (make-array String 4 10)))

7:51 clojurebot: ([nil nil nil nil nil nil nil nil nil nil] [nil nil nil nil nil nil nil nil nil nil] [nil nil nil nil nil nil nil nil nil nil] [nil nil nil nil nil nil nil nil nil nil])

7:52 maxhodak: oh -- i remember my biggest problem

7:52 why i had to use nested amaps

7:52 i needed the indexes

7:52 AWizzArd: do you have a code example?

7:53 maxhodak: like, the indexes mattered

7:53 AWizzArd: hmm, there is a (map-indexed ...)

7:53 maxhodak: ,(doc map-indexed)

7:53 clojurebot: Gabh mo leithscéal?

7:53 AWizzArd: in fresh Clojure versions from http://build.clojure.org/

7:53 sexpbot: "Dashboard [Hudson]"

7:53 AWizzArd: but otherwise you can use clojure.contrib.seq/indexed

7:54 ,(doc indexed)

7:54 clojurebot: "([s]); Returns a lazy sequence of [index, item] pairs, where items come from 's' and indexes count up from zero. (indexed '(a b c d)) => ([0 a] [1 b] [2 c] [3 d])"

7:54 maxhodak: is that all in scope here?

7:54 (indexed (fn [a b] (vector a b)) (int-array 4))

7:55 ,(indexed (fn [a b] (vector a b)) (int-array 4))

7:55 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: seq-utils$indexed

7:55 AWizzArd: ,(doseq [[i s] (indexed ["a" "b" "c"])] (print i s))

7:55 clojurebot: 0 a1 b2 c

7:55 AWizzArd: ,(doseq [[i s] (indexed ["a" "b" "c"])] (print i s "-----"))

7:55 clojurebot: 0 a -----1 b -----2 c -----

7:55 maxhodak: ,(indexed (fn [a b] (vector a b)) (into [] (int-array 4)))

7:55 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: seq-utils$indexed

7:55 maxhodak: oh wait i'm looking at map-indexed

7:55 AWizzArd: right, here we have indexed for now

7:56 maxhodak: ,(indexed (int-array 4))

7:56 clojurebot: ([0 0] [1 0] [2 0] [3 0])

7:56 maxhodak: ok, that works

7:57 AWizzArd: (map-indexed vector (into [] (int-array 4))) should work on fresh Clojures.

7:57 maxhodak: also, i was wondering if anyone had details on the inner workings of pmap

7:57 i don't seem to get any speedup from it; it actually makes things run slower

7:57 AWizzArd: do you want to know something specific?

7:57 maxhodak: this is then because your fn is not expensive

7:57 maxhodak: so i usually end up using concurrent and an ExecutorService to manually deal with threads

7:58 AWizzArd: no, they're expensive

7:58 AWizzArd: (pmap inc (range 100)) is slower, because for each inc work needs to be done

7:58 thread scheduling here and there, copying data stackes, etc.

7:58 your inc should take at least 1-2 msecs

7:58 maxhodak: AWizzArd: each fn takes up a core for a solid 3-5 seconds

7:59 AWizzArd: ,(time (count (map #(Thread/sleep 500) (range 3))))

7:59 clojurebot: java.lang.RuntimeException: java.lang.IllegalArgumentException: Wrong number of args passed to: sandbox$eval--16172$fn

7:59 AWizzArd: ,(time (count (map (fn [_] (Thread/sleep 500)) (range 3))))

7:59 clojurebot: 3

7:59 "Elapsed time: 1503.154 msecs"

7:59 AWizzArd: ,(time (count (pmap (fn [_] (Thread/sleep 500)) (range 3))))

7:59 clojurebot: 3

7:59 "Elapsed time: 504.238 msecs"

8:00 maxhodak: that's strange

8:00 has it changed significantly in newer clojure?

8:00 i might be running 1.1 still

8:00 AWizzArd: not really

8:00 maxhodak: i am

8:00 AWizzArd: ,*clojure-version*

8:00 clojurebot: {:interim true, :major 1, :minor 1, :incremental 0, :qualifier "master"}

8:00 AWizzArd: The bot also runs 1.1

8:00 maxhodak: hmm

8:00 AWizzArd: try this map vs pmap thing from above

8:00 on your box

8:02 maxhodak: got the exact same result as you did here

8:02 so im running maps and reduces inside the fn

8:02 maybe it has to do with laziness and that just appearing slow?

8:03 also, how does pmap decide how many threads to run in? does it detect the number of cores and do something intelligent?

8:05 AWizzArd: pmap uses as many cores as are available + 2

8:05 threads

8:05 dual core cpu ==> up to 4 threads

8:05 new AMD Magny Cours ==> 14 threads

8:06 maxhodak: http://github.com/richhickey/clojure/blob/master/src/clj/clojure/core.clj#L5296

8:06 (+ 2 (.. Runtime getRuntime availableProcessors))

8:07 pmap guarantees the correct order of the results, but obviously it must not run side-effects.

8:07 maxhodak: hmm

8:07 right

8:07 AWizzArd: At least not if the order in which those side-effects will be executed matters.

8:08 In fact, I often cheated, as there is no (pdoseq ...) I just used (doall (pmap #(body here) my-seq)), to parallelize side-effect execution.

8:09 Although, now that futures use the same pool thread pool as agents do, a doseq fireing of futures would also be okay.

8:13 chouser: pmap uses the 'send' pool and future uses the 'send-off' pool, I believe.

8:13 I'd recommend sticking with doall+pmap

8:14 cemerick: parameterizing the usages of various pools seems like low-hanging fruit for 1.3

8:17 caljunior: clojure

8:27 zakwilson_: Has somebody written a version of pmap optimized for large sequences and fairly fast functions? A naive version should be pretty trivial to write, but I figured I'd ask before starting down that path.

8:27 Chousuke: well, sequences are not parallelisable.

8:27 AWizzArd: zakwilson: I am under the impression that vmap will be good for that

8:28 Chousuke: so you need a slow function to map over in order to get any benefits

8:28 zakwilson: Chousuke: right. Assume vectors then, which I think ought to be.

8:28 AWizzArd: though, this could perhaps also be done on the video card, with the clojure lib "penumbra"

8:28 Chousuke: but pvmap is rich's experimental function for mapping over vectors (which are not sequences) and it's very fast

8:29 AWizzArd: Video cards are extremly good in running cheap functions on vast amounts of data

8:29 Chousuke: it's in the clojure par branch and depends on the JDK7 forkjoin library

8:29 AWizzArd: such as: make each rgb pixel brither by 10%, and then do this for all pixels or such

8:30 Chousuke: zakwilson: http://paste.lisp.org/display/84027

8:32 zakwilson: What I actually want to do is run it on a map and return a vector, so I don't think vpmap would work out of the box. How fast is calling vec on a map?

8:32 Chousuke: linear

8:33 AWizzArd: And do you really need the result to be a vector?

8:33 zakwilson: 1.3 seconds on my data set. That would kill any benefit from parallalization.

8:34 No. I need a sorted collection.

8:34 AWizzArd: a sorted-set-by or sorted-map-by?

8:35 What I would really really love to have is a way to build up a sorted-set or map veeerry fast, if I can guarantee to insert in already sorted order

8:37 zakwilson: A map, sorted by value, which I'm currently getting with (sort-by val (comparator >) (into [] m))

8:37 Well, a sequence of key/value pairs. It doesn't need to be a map at this point.

8:38 AWizzArd: zakwilson: a map, sorted by value?

8:38 sorted by key you probably mean?

8:39 zakwilson: No, I mean sorted by value. {:a 2 :b 8 :c 4} is sorted to {:b 8 :c 4 :a 2}

8:39 ,(into {} (sort-by val (comparator >) (into [] {:a 2 :b 8 :c 4}))

8:39 clojurebot: EOF while reading

8:39 zakwilson: ,(into {} (sort-by val (comparator >) (into [] {:a 2 :b 8 :c 4})))

8:39 clojurebot: {:b 8, :c 4, :a 2}

8:40 AWizzArd: ,(class (into {} (sort-by val (comparator >) (into [] {:a 2 :b 8 :c 4}))))

8:40 clojurebot: clojure.lang.PersistentArrayMap

8:40 AWizzArd: it just happens to look sorted, because it is an ArrayMap

8:40 ,(doc hash-map)

8:40 clojurebot: "([] [& keyvals]); keyval => key val Returns a new hash map with supplied mappings."

8:41 zakwilson: I know, but what I'm really doing with it is (take n (sort-by val (comparator >) (into [] m)))

8:41 AWizzArd: Maybe you want to go with a sorted-set

8:42 if you have tuples you can sort them by any of their values

8:43 zakwilson: Or use the numbers as keys and go with a sorted map, but I'm actually happy with the current implementation of this. What needs work is the generation of the map that I'm taking the top values from.

8:44 AWizzArd: ,(into (sorted-set-by #(compare (second %2) (second %1))) [[:a 2] [:b 8] [:c 4]])

8:44 clojurebot: #{[:b 8] [:c 4] [:a 2]}

8:44 hamza: ~def pmap

8:44 AWizzArd: hamza: pmap is at http://github.com/richhickey/clojure/blob/master/src/clj/clojure/core.clj#L5296

8:45 hamza: AWizzArd: thanks, what was the command to get url to github for clojurebot?

8:45 AWizzArd: i guess it just is very slow

8:46 I happened to have the url still in my history, because I pasted it 40 minutes ago

9:00 zakwilson: AWizzArd: the sorted set is marginally faster, though swapping out my sort-by call for that seems to have broken my code. That makes no sense, as the results of calling it on test cases are identical.

9:01 AWizzArd: ok

9:01 zakwilson: Not that I expect you to fix that.

9:03 I'll try to get it working because it seems like the correct data structure, but what I really want is to speed up generation of the thing I'm sorting: (map a-fast-function a-big-map)

9:07 AWizzArd: zakwilson: if it were not a-big-map but a-big-vector then you try to cut it into 2 (or more) pieces and put the call to map into a future.

9:09 zakwilson: Yes, but I need to do fast lookups by key on it.

9:11 AWizzArd: and only afterwards you want to sort it?

9:12 if you had a-big-sorted-set then you can still slice it into pieces with subseq

9:12 though I don't know if this is efficient in the current implementation

9:12 zakwilson: I don't want to sort a-big-map. I want to sort the output of (map a-fast-fn a-big-map)

9:13 The sorting part is fast enough (~500ms).

9:17 Some speedup with (apply concat (pmap #(map a-fast-fn %) (partition (round (/ (count a-big-map) 4))))

9:19 cemerick: so, last-var-wins just falls down in some cases -- e.g. defining munge in one's own ns

9:35 chouser: cemerick: :-( I wonder if we're too late to replace that with something better in 1.2

9:35 cemerick: might be worth continuing to beat that drum on clojure-dev

9:35 cemerick: chouser: it's really quite bad. I'm willing to do whatever it takes to get last-var-wins eliminated.

9:36 yeah, I'll post a message shortly

9:38 AWizzArd: cemerick: do you have a minimal example of that problem?

9:39 cemerick: AWizzArd: looks like: add (defn munge [a b c]) to an ns, AOT-compile.

9:44 AWizzArd: Hmm, and what is the problem there?

9:44 Some other ns also has a (defn munge)?

9:44 cemerick: core does

9:44 and when you redef it locally, the compiler bonks trying to use your version

9:45 or, that's my reading of it

9:45 AWizzArd: So, you may not aot anything that already exists in core?

9:45 cemerick: the scope is surely not that large

9:45 perhaps anything that the compiler uses?

9:46 AWizzArd: ic

9:53 chouser: this could be fixed in the compiler without losing last-var-wins

9:53 unfortunately

9:53 but ... actually, it probably should be.

9:53 cemerick: did you have your own munge var before last-var-wins?

9:55 the compiler should be using clojure.core/munge, not *ns*/munge. If it's doing the latter, it would fail in the case you're describing, but seems like it would also fail if you excluded clojure.core/munge from your own ns and then def'ed your own munge

9:55 hm, actually I think I can test that in a moment here.

10:00 cemerick: chouser: yeah, it was already there; the compiler error actually is related to munge being a multimethod

10:00 and I get two warnings before the compiler error, with core/munge and my-ns/munge doing a dance

10:10 chouser: you were excluding clojure.core/munge from your ns and that was working fine?

10:10 mmarczyk: as far as I can see, munge is a regular function, defined with a defn in core_deftype.clj

10:11 cemerick: chouser: I was, yes, but then I dropped the exclude. I had a hunch. :-)

10:11 chouser: :-)

10:12 well then color me surprised. I'd have to dig into it to figure out why last-var-wins is behaving differently from exclude+def

10:13 zakwilson: Is there a way to persist a map to disk that's faster to read than (spit "foo" (str a-map))?

10:14 chouser: (future (spit "foo" (str a-map))) is pretty fast ;-)

10:14 there aren't many options. you could try the Serialization stuff, but I don't know if that's any faster or appropriate for your use-case.

10:15 zakwilson: It's the reading I'm interested in, not the writing.

10:15 It only takes a few seconds to write, but over a minute to read.

10:15 npoektop: hi! how to make smth like (apply (fn [& a] (println "numbers: " a)) [1 2 3]) to print "numbers: 1\n2\n3?

10:15 it prints "numbers: (1 2)"

10:18 abrenk: ,(apply str (interpose "\n" [1 2 3]))

10:18 clojurebot: "1\n2\n3"

10:18 chouser: abrenk: you beat me about ~1 second.

10:18 ,(apply str "numbers: " (interpose "\n" [1 2 3]))

10:18 clojurebot: "numbers: 1\n2\n3"

10:18 abrenk: chouser: but your answer's more complete :)

10:20 npoektop: i mean i need smth like this (find collection spliced-vector-of-params)

10:20 how to splice vector of params here?

10:23 zakwilson: Any good reasons not to use -XX:+AggressiveOpts?

10:25 chouser: npoektop: is 'apply' not what you want?

10:25 find only takes two args though, so I'm not sure why you'd want to splice in more than that.

10:25 npoektop: how to use it here?

10:27 chouser, (defn find [coll & params] ...) how to splice a vector v? (apply ...(find coll ...) v)

10:27 chouser: (apply find coll v)

10:28 but note there's a clojure.core/find, so replace that with caution

10:28 npoektop: chouser, thank you

10:29 cemerick: chouser: tip o' the iceberg, there :-/

10:40 zakwilson: Under what circumstances could (take n (sort-by val (comparator >) (into [] a-map))) and (take n (into (sorted-set-by #(compare (val %2) (val %1))) a-map)) yield different results?

10:50 rdsr: Hi all, I' m faced with the unfortunate task of extending innumerable wrapper classes from a single parameterized class, so that I'm able to use these with the proxy macro ,

10:51 Has anyone faced a similar problem?

10:51 any pointers, suggestions would be helpful :)

10:51 zakwilson: AWizzArd: sorted-set-by excludes items where compare returns 0.

10:58 So I've spent all afternoon on performance tuning that yielded no improvements, but I did learn some things. Win overall.

11:00 AWizzArd: zakwilson: it does not exclude them

11:00 but instead those are *identical* and only one is kept

11:01 zakwilson: ,(into (sorted-set-by #(compare (val %2) (val %1))) {:a 1 :b 2 :c 3 :d 2})

11:01 clojurebot: #{[:c 3] [:b 2] [:a 1]}

11:01 AWizzArd: When I want to sort things alphabetically after the first char of a string, then "Zakwilson" is exactly identical to "Zak the Wilsoner".

11:01 yes, nothing excluded, the element is already inside

11:01 zakwilson: [:d 2] is excluded.

11:01 AWizzArd: no, there it is: [:b 2]

11:01 They are identical, under your comparator.

11:02 zakwilson: Actually, that's your comparator.

11:02 AWizzArd: It was just an example. Write any that you like.

11:02 mmarczyk: AWizzArd: that would likely be what zakwilson is getting at ;-)

11:02 Chousuke: hm

11:03 the comparator shouldn't affect set membership, only the sorting order

11:03 that's a bug if you ask me.

11:03 AWizzArd: Chousuke: I mentioned this months ago

11:03 mmarczyk: as with sort-by you'll get both [:b 2] and [:d 2]

11:03 zakwilson: ,(into (sorted-set-by #(if (> (val %2) (val %1)) 1 -1)) {:a 1 :b 2 :c 3 :d 2})

11:03 clojurebot: #{[:c 3] [:d 2] [:b 2] [:a 1]}

11:03 AWizzArd: I discussed this with rhickey, but right now that is not a priority

11:03 We were at it when I asked him about persistent sorted multisets

11:04 zakwilson: That's what I want, however, it's slower than this:

11:04 AWizzArd: ,(into (sorted-set-by compare) {:a 1 :b 2 :c 3 :d 2})

11:04 clojurebot: #{[:a 1] [:b 2] [:c 3] [:d 2]}

11:04 AWizzArd: ,(into (sorted-set-by compare) {:a 4 :b 2 :c 9 :d 2})

11:04 clojurebot: #{[:a 4] [:b 2] [:c 9] [:d 2]}

11:04 zakwilson: ,(sort-by val (comparator >) (into [] {:a 1 :b 2 :c 3 :d 2}))

11:04 clojurebot: ([:c 3] [:b 2] [:d 2] [:a 1])

11:04 mmarczyk: so you'd be fine with nondeterministic ordering for sorted-set-by if the comparator happens to "glue together" some elements?

11:04 AWizzArd: uhm no, reverse the keys

11:04 mmarczyk: first wins

11:05 order can be like conj on vectors

11:05 This is how Google implemented their Multisets

11:05 But they are not fully persistent, so, not interesting (to me).

11:05 cemerick: well, there that goes. I wonder how badly I'm going to get spanked. ;-)

11:05 mmarczyk: AWizzArd: I don't know, I tend to expect tree sets to have an ordering independent of insertion order

11:06 AWizzArd: Anyway, I tend to say that if things are not (identical? a b) they should both go into the set.

11:07 mmarczyk: AWizzArd: that's contrary to my intuition, but I'll just say I need to think about it, thanks for the food for thought :-)

11:07 AWizzArd: zakwilson: you can use (identical? %1 %2) in your comparator if (zero? (compare %1 %2))

11:07 mmarczyk: AWizzArd: not really

11:07 ,(identical? [1] [1])

11:07 clojurebot: false

11:08 AWizzArd: why not? Can make sense for some applications

11:08 mmarczyk: =, maybe, though it's still a bit strange to me

11:08 AWizzArd: anyway, it was just a suggestion

11:08 mmarczyk: or .equals

11:08 zakwilson: AWizzArd: I just used (if (> a b) 1 -1) - the items are guaranteed not to be identical.

11:08 AWizzArd: ,(identical? [:b 2] [:d 2])

11:08 clojurebot: false

11:08 AWizzArd: that could be fine for zakwilsons case

11:08 mmarczyk: and also

11:09 ,(identical? [:b 2] [:d 2])

11:09 clojurebot: false

11:09 AWizzArd: you probably meant 2x [:b 2]

11:09 mmarczyk: ,(identical? [:b 2] [:b 2])

11:09 clojurebot: false

11:09 mmarczyk: yeah

11:09 AWizzArd: anyway, depending on the situation this can make sense

11:09 for zakwilson perhaps = would be better

11:10 ,(compare (second [:b 2]) (second [:d 2]))

11:10 clojurebot: 0

11:10 AWizzArd: ,(zero? (compare (second [:b 2]) (second [:d 2])))

11:10 clojurebot: true

11:10 AWizzArd: if this yields true just try (= [:b 2] [:b 2])

11:10 uhm, one of those ought to be a :d :-)

11:11 * zakwilson_ may have missed something due to a DSL resync.

11:11 AWizzArd: oh great :)

11:12 mmarczyk: if seqs where comparable, we could use rseq for reverse lexical ordering of vectors

11:12 AWizzArd: zakwilson_: (zero? (compare (second [:b 2]) (second [:d 2]))) ... if this yields true just try (= [:b 2] [:d 2])

11:13 zakwilson_: I don't care about the case where the items actually are identical: it can't happen.

11:14 mmarczyk: zakwilson_: right, so your solution with 1 -1 is ok, although I guess it leads to nondeterministic ordering on the set

11:14 zakwilson_: I'm ok with nondeterministic ordering when the values are equal.

11:15 The problem is, it's slower than (take n (sort-by val (comparator >) (into [] a-map)))

11:16 (which I'm calling some 30,000 times)

11:16 spariev: how would you guys rewrite this scheme code - http://gist.github.com/261189 ?

11:16 mmarczyk: I've never looked into the tree set implementation, but I'd expect it to perform some rebalancing etc.

11:16 spariev: here's my [nonworking because of wrong recur position] take - http://gist.github.com/399923

11:16 mmarczyk: no surprise here

11:18 Danmaku: spariev: why occurs-naive1?

11:18 AWizzArd: zakwilson_: perhaps you can use some of the mutable Java collections to speed it up?

11:18 mmarczyk: Danmaku: note string->list

11:19 zakwilson_: AWizzArd: I don't think this is actually the part that's slow. I'm using transients for the parts that previously profiled as being slow.

11:19 Danmaku: (let ((pat (string->list pat) (str (string->list str))) ... ?

11:20 mmarczyk: Danmaku: actually (let loop ((pat ...) ...) ...), which is basically the same

11:20 Danmaku: otherwise you'd have to do list->string before the recursive calls

11:21 Danmaku: Yes, i suposse depending on the implementation in turns the internal define into a letrec anyway.

11:21 mmarczyk: spariev: you could just use regular self-calls instead of recur; the Scheme version isn't tail-recursive either

11:22 Danmaku: the impls which don't do this turn letrecs into internal defines ;-)

11:22 Danmaku: heh

11:23 mmarczyk: bbl, there's a pizza waiting for me

11:23 zakwilson_: http://clojure.pastebin.com/K6zwG99h <-- what I *would* like is to make this work. Initial testing shows a brief spike in both cores no improvement on a dual-core system.

11:23 AWizzArd: mmarczyk: enjoy :)

11:24 spariev: Danmaku: the first gist called occurs-naive in contract with the same thing using memoize - http://gist.github.com/261193

11:24 mmarczyk: AWizzArd: thanks :-)

11:26 spariev: mmarczyk: thanks, I'll look into it

11:26 Danmaku: spariev: you can define "occurs" without memoization

11:26 and then define a "memoize" procedure.

11:27 savanni: So, I have a newbie macro problem that I put into a code snippet on http://pastebin.org/229880

11:27 And, if you are willing to attack that, my question is, why does my hex-replace macro get reported as a function? Or, how can I get hex-replace to expand into the other function?

11:28 Danmaku: spariev: for the memoization part there is an example here: http://clojure.org/atoms

11:28 spariev: Danmaku: thanks, I know about memoize, it was recur stuff I wasn't sure about

11:29 didn't notice that scheme code isnt tale-recursive

11:29 Danmaku: I don't think you need recur here

11:29 chouser: savanni: I think you just want -> instead of .. in both places

11:31 savanni: Hmm... well that changes the error message to "Wrong number of args passed to: pages$hex-replace (NO_SOURCE_FILE:0)". I thought my hex-replace macro only required one arg.

11:32 chouser: if this isn't just for learning macros, you might also be interested in:

11:32 ,(java.net.URLEncoder/encode "this has/did-have &strang chars!")

11:32 clojurebot: "this+has%2Fdid-have+%26strang+chars%21"

11:33 chouser: oh

11:33 savanni: Well, one day I will need to learn macros, but the URLEncoder is probably more correct than what I have written.

11:33 (I really do not know much of the Java library)

11:33 chouser: ok, I see some of what's going on.

11:34 savanni: me neither -- just learned (re-learned?) about URLEncoder yesterday.

11:35 savanni: you were expecting the inner hex-replace calls to be expanded first, and then .. to nest the resulting forms inside each other?

11:36 savanni: Umm... I think so. I was expected escape-uri-param to have a body of (.. param (replace ":" "%whatever") (replace "/" "%whatever") and so on

11:36 Modeling after a function in either compojure or ring that escapes HTML entities.

11:39 Ah, actualyl, a function in hiccup.

11:41 chouser: savanni: ok, that's the conceptual problem. An outer macro is expanded first, and only then are parts of what it returns expanded.

11:42 savanni: AH! Because .. itself is a macro!

11:42 chouser: savanni: so -> goes first, producing something like (replace (replace param \: "%..") \/ "%..")

11:42 right

11:42 savanni: Okay, I can restructure that!

11:48 ArkRost: Hi! I've taken a look into clojure source. There is a thing I don't understand. Why do we in method lookupVar(src/jvm/clojure/lang/Compiler.java line 5633) have to handle a situation when sym equals NS handle separatelly from others?

11:52 chouser: ArkRost: the symbols ns and in-ns are handled specially so that they always mean the same thing

11:53 when you're in namespace A and load B (perhaps via (ns A (:require B))), when B.clj first starts to load *ns* is still A

11:54 So if A has done something screwy with the 'ns' or 'in-ns' symbols, or failed it refer them from clojure.core, it could cause B to fail in some hard-to-understand way.

11:54 spariev: is it ok/idiomatic to mix recur with usual self-class like this - http://gist.github.com/399923 ?

11:55 chouser: Instead, ns and in-ns always mean clojure.core/ns and clojure.core/in-ns so that you can use their short names even in unknown circumstances or in new/empty namespaces.

11:56 ArkRost: You're right. Thanks

11:56 spariev: oops, s/self-class/self-calls

11:57 chouser: spariev: It's certinaly ok. I think it's sufficiently idiomatic as well -- using recur when you can (for speed, stack-depth, etc.) and not when you can't.

11:57 spariev: chouser: thanks, just wanted to be sure :)

12:03 alexyk: I manually implemented pmap with 8 agents and achieved 800% load on an 8-core box. pmap did 400% max. Is there a way to tell pmap to work smarter, not harder?

12:04 technomancy: alexyk: pmap never gets too far ahead of the consumer since it's semi-lazy

12:05 alexyk: ah! will it get to work inside doall?

12:05 I meant harder, not smarter :)

12:06 technomancy: not really, because one element that takes longer can block the consumer from the successive elements

12:06 though it might work if the amount of work for each element was relatively homogeneous.

12:07 alexyk: that's the case. I loath to reimplement the same map/reduce myself with my N agents, await for them, conj...

12:12 hugod: alexyk: out of interest, does (.. Runtime getRuntime availableProcessors) report 8?

12:13 alexyk: hugod: yep

12:14 joshua-choi: I'd like to know if there's a function similar to clojure.contrib.string/split that includes the characters between the spitted string: (split* #"\s+" "ab c de") -> ("ab" " " "c" " " "de").

12:16 arkahn: noob help - I want to read lines from a file, process each, until the call to readline returns 'nil'. I'm trying to decide what is the best branching and/or looping construct. Here's some sample code ;;; (with-open [r (BufferedReader. (FileReader. "./filename.txt"))] .readLine r)

12:17 I eventually want to tail the file, so I'll read until 'nil', sleep, then try reading again until some test condition is false

12:17 joshua-choi: If it weren't for that last part, you could simply use clojure.contrib.io/read-lines.

12:17 arkahn: true! : )

12:18 joshua-choi: Take a look at that function's source, though: http://github.com/richhickey/clojure-contrib/blob/9cd7b155149c6e20b799528c6d5bf2f0e553e9f3/src/main/clojure/clojure/contrib/io.clj#L308

12:19 cemerick: cgrand: it'd probably be more convenient if String's get-resource returned nil if there's no available stream for the given name. The NPE isn't so useful.

12:19 joshua-choi: arkahn: If you replaced the (.close rdr) part with (do ... (.close rdr)), you should be able to do what you want

12:20 arkahn: joshua-choi: thank you ... I should have looked at the cc code again : /

12:20 joshua-choi: No problem.

13:16 ninjudd: technomancy: is there a way to use "lein compile" when some code is java and some is clojure? (src/jvm and src/clj)

13:17 hiredman: there is a lein-java plugin

13:18 ninjudd: hiredman: lein-javac?

13:19 hiredman: something like that

13:20 ninjudd: that looks like the one... so here is what i don't get about lein. you have to run "lein compile-java". there is no easy way to make the standard "lein compile" be smart and do what you mean

13:21 which means that running "lein jar" is broken, because it depends on compile, but not on compile-java

13:23 it seems to me that the problem is that lein misses the difference between what would be tasks and targets in ant

13:23 making them the same thing, which put much more burden on the user

13:24 hamza: lein will allow your tasks to hook into other tasks, it is on technomancy's todo list but with a lower priority. for now you can use a custom task that calls the tasks in the correct order.

13:24 abrenk: ninjudd: take maven... ;-)

13:24 *duck*

13:26 ninjudd: hamza: can the custom task be called something that makes sense, like 'lein jar', or will it have to be something ridiculous, like 'lein myjar'

13:26 technomancy: ninjudd: there's going to be a hooks system in 1.3 to support that

13:27 ninjudd: technomancy: great!

13:27 technomancy: I'm waiting for a Clojure release candidate to release Lein 1.2

13:28 ninjudd: technomancy: what about jars you depend on. will there be a way to run tasks for them after they are installed?

13:30 giacecco: Hello all! Anybody has some time for a newbie question and some Eclipse background?

13:30 ninjudd: technomancy: or is there already through maven?

13:32 abrenk: giacecco: I use Eclipse for Clojure development at the moment...

13:33 giacecco: abrenk: I am struggling getting Eclipse to add a simple .class file to the build path

13:33 ninjudd: also, if i use lein-javac, there still doesn't seem to be a way to compile stuff in src/clj

13:33 * rsynnott always found the classpath business possibly the most annoying thing about java

13:33 giacecco: abrenk: I have a stupid package-less class in a .class file

13:34 abrenk: that I want to instanciate in my clojure code e.g. (def foo (LineRedirecter.))

13:35 abrenk: I tried everything but I can't get Clojure to recognise that the .class file is there and the class LineRedirecter is available

13:35 abrenk: giacecco: I vaguely remember that classes in the default package do not play well with Clojure...

13:35 giacecco: abrenk: what do you mean?

13:35 abrenk: giacecco: I don't think that it's an Eclipse problem.

13:36 Could somebody else answer how to import a class from the default package?

13:37 giacecco: did you try to (import 'LineRedirecter) ?

13:37 giacecco: y

13:37 at the moment LineRedirecter.class is in the 'classes' folder of the structure that Eclipse builds

13:38 but Eclipse does not list it under (default package) in the package explorer

13:38 alexyk: how can I destructure [1 2 3 4 5] to capture 1, [2 3], and [4 5]?

13:39 ninjudd: technomancy: should i just move all my clojure code out of src/clj and directly into src? isn't src/clj and src/jvm the accepted way to structure source code that is clojure and java

13:39 abrenk: giacecco: you don't have the source? just copied the .class file?

13:40 giacecco: abrenk: I also have the source

13:40 abrenk: but I wouldn't like to translate everything in Clojure

13:40 alexyk: ninjudd: lein should understand :source-path IIRC

13:41 abrenk: giacecco: is the source in the same eclipse project as your clojure code?

13:41 giacecco: alexyk: do you mean something like #((nth 0 %) [(nth 1 %) (nth 2 %)] [(nth 3 %) (nth 4 %)]] ?

13:42 ninjudd: alexyk: looks like it does, thanks!

13:42 giacecco: abrenk: y

13:42 abrenk: giacecco: then it should work using (import 'LineRedirecter) (LineRedirecter.)

13:42 alexyk: giacecco: no, [x & [y z : mid2] & [u v :as last2]] or something that actually works

13:46 giacecco: abrenk: when I added the .java file, package explorer showed a new (default package) folder under 'src', and the .java file is there: is that correct?

13:47 abrenk: giacecco: yes

13:48 giacecco: the target folder is normally hidden in the package explorer

13:49 ninjudd: alexyk: i think you're best off using subvec

13:50 giacecco: alexyk: (defn foo [x] [(nth x 0) [(nth x 1) (nth x 2)] [(nth x 3) (nth x 4)]])

13:50 alexyk: ninjudd: yeah

13:50 giacecco: alexyk: I know it's ugly but I'm a newbie

13:50 alexyk: giacecco: a determined newbie! :)

13:51 giacecco: alexyk: you have to start somewhere :-(

13:51 alexyk: true

13:51 Hodapp: sigh, if only when I was back in high school I had spent all that time during the summer actually learning Lisp instead of going to cross country practice and flirting with girls

13:51 I wouldn't be such a n00b now

13:52 giacecco: alexyk: you may also invent something using 'partition'

13:53 abrenk: still no joy here

13:55 abrenk: giacecco: could you paste your .classpath somewhere?

13:55 turbofail: Hodapp: the two are (were?) not mutually exclusive

13:56 alexyk: giacecco: well. it's ok, I simply restructured the params. One way to do it is to say:

13:56 ,(let [[x & xs] (range 5) [y z & lala] xs yz [y z]] (print x yz lala))

13:56 clojurebot: 0 [1 2] (3 4)

13:56 abrenk: giacecco: when doesn't Clojure find your class? in a ccw repl?

13:56 alexyk: I'd rather fetch yz at once with imaginary [y z :as yz & lala] but that seems to cut off lala, even though it parses

13:58 giacecco: abrenk: even before that, the editor already says "No matching ctor found"

13:58 abrenk: actually, the error has changed, the one I just told you about does not say that the class does not exist

13:58 clojurebot: hmm… sounds like your out of heap space

14:00 giacecco: abrenk: hold on...

14:00 abrenk: giacecco: does the class have a no-arg ctor?

14:01 giacecco: otherwise (LineRedirecter. :my :args :here) should work

14:02 giacecco: abrenk: so there were two problems, and one is fixed

14:03 abrenk: the first was putting the .class in the right place, and that should be solved

14:03 abrenk: the second is that I was calling the ctor in the wrong way, but that is still broken, I am working on it now

14:04 LauJensen: dumping a file with a Writer isnt atomic on the fs right? what is? shelling out to 'mv' perhaps?

14:07 stuartsierra: LauJensen: http://rcrowley.org/2010/01/06/things-unix-can-do-atomically.html

14:07 sexpbot: "Things UNIX can do atomically — Crowley Code!"

14:08 LauJensen: stuartsierra: Thanks!

14:09 stuartsierra: np

14:18 arohner: _ato: is there a way to grab the pom file for a jar on clojars?

14:19 giacecco: abrenk: update: whatever signature I use, I always get the "No matching ctor found for class LineRedirecter" error

14:20 abrenk: the ctor is actually very simple: LineRedirecter(InputStream in, OutputStream out)

14:20 abrenk: and I am invoking with something that looks like (LineRedirecter. (. my-proc getInputStream) writeTo)

14:27 abrenk: giacecco: and you're sure that those expressions evaluate to InputStream and OutputStream respectively?

14:28 giacecco: does (LineRedirecter. nil nil) work?

14:30 giacecco: (LineRedirecter. nil nil) does not work

14:30 abrenk: giacecco: same error?

14:30 giacecco: abrenk: I also tried explicitly casting the parameters to the expected types

14:30 same error

14:30 that's odd isn't it

14:31 abrenk: yeah

14:31 I fear I'm out of ideas

14:32 giacecco: abrenk: the source for LineRedirecter if you're curious is at http://bit.ly/bttA9N

14:32 sexpbot: "JMPlayer – Embedding MPlayer in Java « adrian's blog"

14:32 giacecco: abrenk: don't worry, you've helped me a lot already, and thank you!

14:36 dpritchett: I've just spent a few hours trying to get vimclojure + lein-nailgun to work with the latest labrepl to no avail. I'm not really sure where to go next.

14:36 I have lein-nailgun working fine with vimclojure in a sample clojure 1.1.0 project but since labrepl usees 1.2.0-snapshot it seems to be causing some issues

14:36 lancepantz: dpritchett: i've tried 3 times over the last 6 months with little success

14:36 abrenk: giacecco: as long as it's not just a typo regarding ...ter and ...tor

14:37 lancepantz: i was actually just trying lein ng + vimclojure

14:37 abrenk: ha!

14:37 giacecco: the ctor is not public!

14:37 dpritchett: I think I've gotten that much working at least, lancepantz

14:37 abrenk: giacecco: so I guess there's a problem as long as soons as you're in a namespace

14:37 lancepantz: dpritchett: i just decided it was time to learn emacs :)

14:38 dpritchett: I can start up the repl from within vim and *clojure-version* is showing 1.1.0

14:38 lancepantz: dpritchett: does omnicompletion work, that was always the problem i had

14:38 dpritchett: I had originally resolved to learn emacs along with clojure but I switched to vim when I grew tired of emacs and the 8 second start time

14:38 giacecco: abrenk yeah!!! :-)

14:39 dpritchett: Omnicomplete is bringing up a box full of suggestions and automatically picking the right one. I have never actually used omnicomplete in vim before so I don't know if that's the expected behavior.

14:39 lancepantz: i'm pretty impressed with viper and vimpulse in emacs

14:39 i'm not using them though inorder to learn though

14:39 dpritchett: C-x C-o in insert mode autocompletes the word at the cursor

14:39 giacecco: abrenk: thanks! I did not notice that!

14:39 lancepantz: dpritchett: it is, i would get a java exception from ng everytime

14:39 abrenk: giacecco: that's stuff you definately need a second pair of eyes

14:41 s450r1: I only start emacs once just after my computer starts. After that I just open files from within emacs or use emacsclient, which is very fast.

14:42 dpritchett: So how much am I missing working against 1.1.0? I mostly just want to explore Clojure but since labrepl is broken that's offputting.

14:43 I believe the next release of vimclojure will solve my problems but I don't know when to expect it.

14:43 mmarczyk: broken? how?

14:43 oh, and I'd say you're missing quite a lot

14:44 and if you're not (yet) using Clojure in production, why not explore *all* the cool stuff that's available

14:45 dpritchett: mmarczyk: Labrepl itself isn't broken I just can't get it to play well with the latest stable version of vimclojure and I haven't figured out how to make the dev version of vimclojure work at all.

14:45 mmarczyk: dpritchett: ah, I see

14:46 dpritchett: And I've just gotten comfortable with vim, was hoping to avoid having to learn emacs along with the latest clojure

14:46 mmarczyk: I regret to say that I can't bring myself to figure out how to start a Gradle build to try the latest vc :-(

14:47 you wouldn't want to become bieditorial?

14:47 I always thought it was fun to go both ways :-)

14:49 dpritchett: I suppose learning emacs will be more beneficial than learning how to resolve this particularly dependency problem

14:54 LauJensen: chouser: Why both shell.clj and shell_out.clj ?

14:57 stuartsierra: LauJensen: renaming for 1.2

14:57 LauJensen: renaming for 1.2

15:05 LauJensen: ok, thanks

15:05 btw stuartsierra, did you know that mv x y, where x and y are on the same fs, calls rename in stdio, which is atomic, but if they are not on the same fs, it calls cp, then rm :)

15:09 stuartsierra: LauJensen: I think I did know that

15:27 bsder: Newb question: I'm trying out the labrepl stuff in Enclojure on NetBeans in OS X.

15:27 After pulling the latest via git, it compiles and runs.

15:27 However, I get:

15:28 user=> (source "println")

15:28 #<CompilerException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.Symbol (NO_SOURCE_FILE:10)>

15:28 Presumably, somthing still needs to be installed. Any suggestions?

15:28 dakrone: bsder: try (source println)

15:29 bsder: *smacks forehead*

15:29 dakrone: :)

15:29 bsder: dakrone: Thanks.

15:30 dakrone: no problem :)

15:43 scode: Is there a more idiomatic way of converting a set of things to a map, than (apply conj {} (map (fn [p] [(:key p) p]) set-of-ps))?

15:49 ataggart: what's the element of the set look like?

15:49 iow, how does one element become a key/value tuple

15:50 (guessing form the code that the element has a :key property)

15:50 scode: ataggart: In this particular case, blog pages that will have an :fname key.

15:50 (I just used :key in my question to generalize)

15:50 chouser: (zipmap (map :key set-of-ps) ps)

15:50 ataggart: cool

15:50 dammit chris stop answering questions while I'm trying to understand them

15:51 chouser: (zipmap (map :key set-of-ps) set-of-ps)

15:51 :-) sorry

15:51 ataggart: lol

15:51 scode: chouser: Thanks! That's exactly as short and nice as I would have expected ;)

15:51 * ataggart never gets any love

15:51 * scode thanks ataggart too :)

15:51 dakrone: is there a way to get protocol methods to follow :use's :as option? http://gist.github.com/400369

15:52 ataggart: doesn't it just go into the ns around the defprotocol?

15:52 ah nvm

15:52 read the comment

15:53 dakrone: 2 completely different protocols

15:53 just same method names

15:53 ataggart: ya, you need to pick

15:53 though...

15:53 dakrone: yea, I just don't want to have to name everything <prefix>-score and <prefix>-rank

15:53 it'd be nicer to do (scs/score _) and (cs/score _)

15:54 ataggart: or they should be *one* protocol

15:54 a type can only implement one of them anyway

15:54 dakrone: I thought about that, but the 2 different protocols have differing other methods that I don't want them all to implement

15:55 ataggart: break up the protocls

15:55 have the type pick the n protocls it nees to implement

15:55 dakrone: they are broken up already?

15:55 ataggart: I mean, move score and rank to its own protocol

15:56 if score and rank are the "same" in both protocols

15:56 kotarak: this is normal use behaviour

15:56 dakrone: they aren't the same though, they have different arguments too

15:56 would that be a problem?

15:56 ataggart: ah very well then

15:56 kotarak: use (require '[name.space :as space] [space.name :as name])

15:56 ataggart: yes, so they are truly not the same fn

15:56 what kotarak said

15:57 kotarak: or (use [.. :as .. :only ()])

15:57 ataggart: require+as or use+only

15:57 good form

15:58 * dakrone experiments

15:58 kotarak: use should be used only with only, anyway. %)

15:58 dakrone: (:use [clomoios.contextsearcher :as cs] [cs.score :as cs-score]) doesn't seem to work

15:58 oh wait, you said require, not use

15:58 kotarak: dakrone: as I said: this is normal use behaviour

15:58 yup , exactly

15:59 dakrone: (:require [clomoios.contextsearcher :as cs] [cs.score :as cs-score]) doesn't work either though

15:59 kotarak: Did you reload your Repl?

16:00 If yes, what is the error. I would be surprised if it didn't work.

16:00 dakrone: not using a REPL, just running the file with clj to make sure it doesn't except like crazy when reading it

16:00 ah wait, fixed it

16:01 ataggart: science!

16:01 dakrone: me being silly, thanks kotarak

16:01 & ataggart

16:01 kotarak: dakrone: np :)

16:01 ataggart: yeah, I was approaching the problem from the protocol design side

16:02 dakrone: this highlights the need for Need

16:02 * ataggart wishes he was in NC at the clojure thing

16:03 * kotarak still remembers the time before use and require.

16:03 dakrone: did you just (load _) everything?

16:03 kotarak: basically, yes.

16:04 Then Stephen G. wrote things as a library in contrib.

16:05 * kotarak suggested :as . :)

16:05 dakrone: very helpful :)

16:19 mmarczyk: is there a readable literal for the null character?

16:19 ,\a

16:19 I mean \^@ doesn't work

16:19 clojurebot: \a

16:19 kotarak: ,\000

16:19 clojurebot: Unsupported character: \000

16:19 kotarak: ,\u000

16:19 clojurebot: Invalid unicode character: \u000

16:19 kotarak: ,(char 0)

16:19 clojurebot: \

16:20 kotarak: hmm, bug?

16:20 mmarczyk: ,\u0000

16:20 clojurebot: \

16:20 mmarczyk: thanks :-)

16:23 arkahn: ,conj \u0000 \u0000

16:23 clojurebot: #<core$conj__4242 clojure.core$conj__4242@996e4>

16:25 dpritchett: If I've completely boffed my clojure install (mostly leiningen) and I'd like to wipe it and start over using lein deps what should I delete?

16:26 tcrayford: lib

16:26 well are you installing lein?

16:26 * tcrayford hits head

16:26 mmarczyk: if you have lein-stable set up

16:26 lein-stable clean

16:26 tomoj: ~/.m2 ?

16:26 clojurebot: No entiendo

16:37 ataggart: yeah rm -rf ~/.m2 should do it

17:01 dpritchett: Finally got everything the way I need it with emacs+starterkit+lein swank and labrepl. Tomorrow I'll start relearning emacs!

17:15 mmarczyk: dpritchett: great, have fun :-)

17:53 ninjudd: this makes no sense: i have 3 projects, A, B, and C where A depends on B and B depends on C. when i do "lein deps" in A, it doesn't pull down C

17:56 am i crazy?

17:57 seems like that is the whole point of a dependency management system, right?

17:59 technomancy: ninjudd: somebody must not be declaring their dependencies correctly. either that, or one of the dependencies is a dev-dependency, and those are not transitive.

17:59 arohner: is there a place in lein to specify java options?

18:00 ninjudd: technomancy: does lein do something strange when one of those dependencies is clojure?

18:01 technomancy: ninjudd: the only special-case for clojure is allowing you to omit the "org.clojure" group-id.

18:02 ninjudd: technomancy: so if B depends on clojure 1.2 and A depends on 1.1, there should be an error, right?

18:03 technomancy: ninjudd: no, maven allows varying versions of the same dependency. the rules for determining which wins are very complicated though. you can use :exclusions to manually get rid of the one you don't want if it picks wrongly (in the faq in the readme)

18:06 ninjudd: technomancy: ok thanks. i just got transitive deps to work. it was a caching problem

18:09 hmm.. it chose clojure 1.1 though. seems like it would make more sense to choose 1.2 since it should be backwards-compatible

18:09 DuneMan: except its not backwards compatible

18:10 ninjudd: but it should be if it used semantive versioning

18:10 semantic

18:10 DuneMan: but its not, so.

18:10 (hash-map ...) in 1.1 accepts duplicate keys, and in 1.2 throws duplicatekeyerror

18:10 I'm sure there are others.

18:11 ninjudd: technomancy: does maven take advantage of semantic versioning? or do you just prefer that people use it?

18:12 technomancy: it's impossible to enforce semantic versioning.

18:12 savanni: At least, in a fully automated way.

18:12 ninjudd: not enforce

18:13 i mean, does maven infer semantic meaning from version numbers?

18:15 for example, it could assume that if i require 2.1.0, then 2.2.0 is ok since it should be backwards compatible, but 3.0.0 is not ok

18:16 boredomist: Hey, I was wondering how I could do some Java casting from Clojure. Specifically, Graphics => Graphics2D

18:16 Chousuke: boredomist: you shouldn't need to do any

18:16 boredomist: Graphics2D is a subclass of Graphics if you didn't know

18:16 savanni: That kind of casting should be automatic as part of the subclassing system.

18:17 boredomist: Okay, that's convenient. Thanks :)

18:17 kotarak: (doc cast)

18:17 clojurebot: "([c x]); Throws a ClassCastException if x is not a c, else returns x."

18:17 Chousuke: cast is useless :P

18:17 savanni: Well, sorta. Actually, I'm not sure what would happen if the system thinks you have a Graphics and you call a Graphics2D method on it.

18:17 Chousuke: you'd get an exception.

18:18 or hm, not in clojure

18:19 savanni: I know I'm probably getting confused in here, but I'm thinking that if an object gets instantiated as a Graphics2D, there's nothing that would ever cause it to get upcast to Graphics.

18:19 kotarak: Chousuke: cast is an assertion

18:19 Chousuke: If you need to differentiate between Graphics and Graphics2d when making a method call or something you might need to add a type hint (I don't know if it's possible to overload in such a way though)

18:19 lancepantz: technomancy: do you have any idea what's up with the execute call in deps?

18:20 Chousuke: kotarak: yeah, and it seems like no-one uses it ;P

18:20 lancepantz: technomancy: i noticed the comment about the rogue thread

18:20 kotarak: Chousuke: hehe, there several such functions, eg. sequence

18:20 boredomist: Chousuke: yeah I tried a type hint, and it seemed to do the trick

18:25 alexyk: say I need to have 4 defn's differing only in 2-3 lines of a deep inner guts. Each defn takes parameters a and b. How can I make a macro which will produce each function -- how should I package the 2-3 lines of the "body"?

18:27 * alexyk tries to squeak by macros on a need-to-know basis

18:28 savanni: What if those 2-3 lines that are different are themselves functions that your big functions called?

18:28 You could then pass the function you want into the single big function.

18:28 tomoj: deftemplate maybe?

18:29 do-template, rather

18:29 or whatever the hell it is

18:30 ninjudd: alexy:

18:30 (defmacro foo [name & body]

18:30 `(defn ~name [~'a ~'b]

18:30 (do ~@body)))

18:30 kotarak: alexyk: depends on your macro: (defmacro fasten-seatbelt [clean-up & body] `(try ~@body (~'finally ~clean-up)))

18:30 ninjudd: just throw your other logic around the do-body

18:31 kotarak: do is not necessary, since defn does an implicit do anyway

18:31 ivank: how do i get access to deftrace?

18:31 from a repl in emacs?

18:31 ninjudd: kotarak: it may be depending on what is around it

18:32 alexyk: kotarak: say my body looks like: (let [x (f blah)] (assoc stats user x)) ; where stats and user come from the macro, i.e. common for all defns. Can I just apss it in quoted, '(let ...) ?

18:32 pass

18:32 ninjudd: you don't have to quote it

18:33 kotarak: alexyk: just call it as (foo (let ...))

18:33 alexyk: ninjudd: do you mean I can avoid the macro with a do, saying do-body?

18:33 ninjudd: no

18:33 alexyk: ok :)

18:33 ivank: ah, got it (use ...

18:34 kotarak: alexyk: (foo my-fn (let [x (f blah)] (assoc stats user x))

18:34 alexyk: looks like macros are cheaper ways to stick varying guts into things inside of typed languages' generics, where you'd painfully typify the said guts

18:34 kotarak: yep, cool

18:34 kotarak: alexyk: with ninjudd's foo from above

18:34 alexyk: ninjudd's foos rock! :)

18:35 above: s/inside/instead/

18:35 kotarak: alexyk: the better design is probably putting your things into a driver function and expand into a macro, which calls the driver and passes it a function.

18:36 alexyk: kotarak: brainknot ^^! :)

18:36 kotarak: alexyk: (defn driver [guts] (.... (guts stats user) ...)) (defmacro foo [& guts] `(driver (fn [~'stats ~'user] ~@guts)))

18:37 alexyk: this has the added benefit, that you don't bar# all over the place and changing driver effects all callsites without recompilation.

18:37 alexyk: kotarak: how can driver be defined if stats and user are in foo?

18:37 guts only use them, not define them

18:38 that's why they're not self-contained, spilled guts

18:38 ninjudd: driver would be a function that takes stats and user

18:38 alexyk: or driver is teh new foo?

18:38 ninjudd: i mean, guts would be a function that takes stats and user

18:39 kotarak: alexyk: ok more explicit: (defn driver [guts] (let [user (get-user) stats (retrieve-stats)] (do-other-boilerplate) (guts stats user)))

18:39 alexyk: does this make sense?

18:39 alexyk: lemme think

18:40 so how do I declare one real defn from foo -- is the defn's name implicit first parameter?

18:41 kotarak: Oh, you need a defn? Then you need a macro and go with the first foo from ninjudd

18:41 alexyk: yeah, my macro takes guts, produces a defn which must have a name and takes args [a b]

18:42 so that then I can call it at will

18:42 ok, ninjudd's from above indeed

18:47 what's the difference between ~@x and ~'x?

18:48 turbofail: ,(let [x '(a b c)] `(foo ~'x bar ~@x baz ~x))

18:48 clojurebot: (sandbox/foo x sandbox/bar a b c sandbox/baz (a b c))

18:49 turbofail: ~'x is kind of a no-op

18:49 clojurebot: 'Sea, mhuise.

18:52 ninjudd: ~'x does symbol capture

18:52 clojurebot: examples is http://en.wikibooks.org/wiki/Clojure_Programming/Examples/API_Examples

18:52 kotarak: ~'x should be used only after very careful thought. Very, very careful thought.

18:52 clojurebot: 'x is kind of a no-op

18:53 ninjudd: quiet, clojurebot

18:53 turbofail: doh... i've miseducated it

18:54 alexyk: clojurebot: you will be reeducated in the rice fields

18:54 clojurebot: Huh?

18:54 alexyk: clojurebot: too late to ask why

18:54 ninjudd: http://blog.danieljanus.pl/clojure/symbol-capture.html

18:54 sexpbot: "musings of a Lispnik — Daniel Janus's blog"

18:54 clojurebot: Huh?

18:54 ninjudd: more explanation on symbol-capture: http://blog.danieljanus.pl/clojure/symbol-capture.html

18:54 sexpbot: "musings of a Lispnik — Daniel Janus's blog"

18:55 alexyk: thx

18:57 ninjudd: there's a section in stuart's book about it too

18:58 ivank: since '() evals true, how should i do (or '() '(something else)) in closure?

18:58 *clojure?

19:00 i want to avoid doing a (reduce max '())

19:00 wlangstroth: ivank: do you just want a test for emptiness?

19:00 ,(empty? '())

19:00 clojurebot: true

19:00 wlangstroth: oh, I misunderstood

19:01 ivank: wlangstroth: test for emptiness but return the list if not empty

19:01 actually hacked around it

19:01 somnium: like (when (seq xs) (reduce max xs))

19:01 ivank: (reduce max (cons 0 '()))

19:01 Raynes: "A group of us from the office went to see the movie Iron Man 2 (it just debuted in the United States), and it reminded us of Java, the Java community, and JavaOne." - Oracle

19:02 savanni: ... eh?

19:02 wlangstroth: Raynes: ba-what?

19:02 Raynes: Indeed.

19:02 ivank: somnium: i don't want to have to assign it to anything

19:02 (let [x 999] (reduce max (cons 0 (filter is-palindromic (map (fn [y] (* x y)) (range x 100 -1))))))

19:04 somnium: ivank: ah, thats not really possible pointfree afaik, a common idiom is (when-let [x (seq ...)] (... x))

19:05 well, you could make a (fn [x] (when (seq x) x ...)) and use it point-free I guess

19:07 ivank: i don't quite understand

19:07 would you replace the (let with that?

19:07 somnium: wow, they werent kidding

19:07 http://www.oracle.com/marvel/index.html

19:07 sexpbot: "Oracle is co-promoting Ironman | Oracle, The World's Largest Enterprise Software Company"

19:08 MadWombat: the damn clj-gae-datastore is missing a file :(

19:08 wlangstroth: Raynes: maybe they mean Java is a huge, barely-controlled explosion of mechanized teenage fantasy

19:11 DuneMan: Teenage fantasy wouldn't have chosen such a repressive and unimpressive type system

19:13 although the fixation on OO as the sole design paradigm does remind of certain young male obsessions gone awry.

19:13 wlangstroth: DuneMan: My point exactly.

19:13 somnium: ivank: my half-baked idea was (let [decide (fn [xs full-> empty->] (when (seq xs) (full-> xs) (empty-> xs)))] (decide (filter f (map g ...)) (partial reduce max) 0))

19:17 ,(let [decide (fn [xs a b] (if (seq xs) (a xs) b))] [(decide (range 1 6) (partial apply *) 42) (decide '() (partial apply *) 42)])

19:17 clojurebot: [120 42]

19:18 somnium: half-baked was probably too kind...

19:42 _ato: arohner: sure http://clojars.org/repo/autodoc/autodoc/0.7.1/autodoc-0.7.1.pom browse from http://clojars.org/repo/

19:43 arohner: _ato: thanks, found it

19:50 rsh: does anyone have a recommendation for an html parser?

19:51 tcrayford: enlive

19:55 rsh: thanks

19:55 cemerick: enlive isn't an html parser, but OK :-)

20:23 StartsWithK: http://is.gd/c84Zu <- you have to load clojure in your own class loader (i can't post to -dev) or extract the native libs in tmp dir from jar (jline style)

20:32 dysinger: I heard there was an emacs vs ??? war going on in here

20:32 can I get in a punch ?

20:32 Raynes: WHERE?

20:32 clojurebot: where is log

20:33 dysinger: :)

20:33 oh it was on twitter nm

20:33 * dysinger starts one anyway

20:33 dysinger: and punches the nearest vim and/or IDE user

20:33 hiredman: ouch

20:35 DuneMan: your punches don't hurt me


20:35 technomancy: he must have forgotten to enable M-x punch-through-vim-protection-mode

20:35 DuneMan: *holds a a shield with the Bram Molenjaar crest on it*

20:35 technomancy: I have it activated in an erc hook.

20:40 tomoj: technomancy: keyboard pants... awesome

20:40 technomancy: tomoj: wearable computing is the future!

20:41 tomoj: then I'll never have an excuse not to be working :/

20:45 cemerick: dysinger: you'd be after me, probably :-P

20:46 though "war" is surely overstating it

20:47 turbofail: yes... this is more of a "polite expenditure of munitions"

20:48 trptcolin: whoa looks like i picked a good evening for irc :)

20:52 turbofail: speaking of which, clojure-on-cruise-missiles sounds like a great name for a framework of sorts

20:54 chouser: dysinger: you're involved in ClojureConj 2010, right? What's up with that?

20:55 dysinger: Amit and I both got too busy

20:55 both of us are working insane hours

20:55 at the moment

20:56 I want to see it happen though

20:56 Oh BTW speaking of crazy hours - I have room for 3 more on my team

20:56 chouser: heh

20:56 That's good to hear, but I'm afraid I'm not qualified.

20:56 dysinger: halp

20:56 tomoj: if it happened, it would surely be the first conference I didn't have to pay to attend

21:16 hiredman: anyone know how to .property stuff in scriptjure?

21:39 hugod: anyone interested in maven plugins written in clojure?

21:42 drewr: hugod: of course

21:43 hugod: drewr: so how does this look http://github.com/hugoduncan/clojure-mojo-example/blob/master/src/main/clojure/maven/clojure/example/plugin.clj

21:44 drewr: it's certainly terse

21:45 I haven't written a mvn plugin before, so I'll take your word on the correctness

21:45 hugod: well, it looks pretty similar to the corresponding java

21:46 wlangstroth: anyone know if there's a haskell *words* equivalent in clojure? It's not like it would be hard to do, but it doesn't seem to exist in contrib.

21:48 drewr: wlangstroth: what does *words* do?

21:49 wlangstroth: drewr: tokenizes words. Super simple, I just didn't want to make my own if one was already there.

21:49 tokenizes words, throws them into a collection, I should say

21:50 drewr: *googles* you mean tokenizes a string of words into a list?

21:51 ,(split #"\s+" "the quick brown fox yada yada")

21:51 clojurebot: java.lang.Exception: Unable to resolve symbol: split in this context

21:51 drewr: ,(clojure.contrib.string/split #"\s+" "the quick brown fox yada yada")

21:51 clojurebot: java.lang.ClassNotFoundException: clojure.contrib.string

21:51 drewr: ,(require 'clojure.contrib.string)

21:51 clojurebot: java.io.FileNotFoundException: Could not locate clojure/contrib/string__init.class or clojure/contrib/string.clj on classpath:

21:51 drewr: grrr

21:51 anyway, try that

21:51 TheBusby: ,(use '[clojure.contrib.str-utils :only (re-split)])

21:51 clojurebot: nil

21:51 rhudson: ,(.split #"\s+" "a b cdd e")

21:51 clojurebot: #<String[] [Ljava.lang.String;@1906e1d>

21:54 TheBusby: ,(re-split #"\s+" "the quick brown fox yada yada")

21:54 clojurebot: ("the" "quick" "brown" "fox" "yada" "yada")

21:54 wlangstroth: okay, re-split works. It seems like overkill when I know I'm always splitting on whitespace

21:55 but I'll check out the code - thanks

22:01 wahz: how do you send an expression to the repl window in emacs using slime?

22:02 dnolen: wahz: C-x C-e from the last paren of the sexpr you want to send

22:03 wahz: thanks, but the result of the evaluation is shown in the minibuffer, but the expression itself is not sent to the repl

22:04 i.e. I would like it to be in the repl input history

22:23 I guess copy and paste will have to do for now :)

22:50 vIkSiT: hm, (defn qsort [[pivot & xs]] .. ) - exactly what are the arguments to this function?

22:50 qbg: A sequence

22:50 vIkSiT: a vector of vectors?

22:50 qbg: It does destructuring

22:50 vIkSiT: qbg, hmm, so a sequence how exactly? a pivot sequence, and an xs sequence?

22:50 qbg: No, the first item becomes pivot, and the rest becomes xs

22:50 vIkSiT: qbg, could you explain a bit about th destructuring process (and how it works/gets invoked)?

22:51 aah

22:51 so basically, its like the head and tail

22:51 qbg: Yes

22:52 See http://clojure.org/special_forms#Special%20Forms--%28let%20[bindings*%20]%20exprs*%29

22:52 vIkSiT: so, if I were to declare a function like (defn myfn [[v1 v2 v3 & restelem]] ..)

22:52 then the first 3 elements of the seq are v1, v2 and v3..

22:52 and restelem is the remaining sequence.

22:52 qbg: Correct

22:52 vIkSiT: ah great. thanks for the link as well

22:54 * ninjudd wishes leiningen was called cake.

22:56 tomoj: that would be bad for google, I think

22:56 though maybe "clojure cake" would be enough

22:56 TheBusby: have fun googling "clojure ->"

22:58 ninjudd: rake gets by ok

22:58 though there are not as many search results for rake

22:59 first result for "clojure cake": You are what makes Clojure great - find some cake and celebrate! ...

23:02 TheBusby: that's google's fault, they need advanced options for searching for symbols

23:02 TheBusby: that's certainly true, but it doesn't make it less frustrating

23:03 ninjudd: "clojure threading operator" returns some results

23:04 TheBusby: I just wish we could add a few simple examples in the doc strings, and hence eliminate the need to google for examples

23:05 tomoj: seen cljex?

23:05 and/or walton?

23:05 I think both of those are trying to address your concern

23:06 TheBusby: not yet, but I'm excited to hear that and am googling them now

23:07 tomoj: both by defn

23:07 TheBusby: great work, I still wish the examples could be appended to the current doc strings though.

23:08 tomoj: I think I like them outside the source where people can contribute/modify/interact without needing to commit into clojure

23:09 TheBusby: how much updating do you image would happen though for things like "concat" ?

23:10 wlangstroth: TheBusby: I'm working on it (more examples) but it's slow going

23:11 TheBusby: understandably and I commend you for it.

23:11 I'd volunteer my time as well but not until we finally decide upon where they fit in clojure

23:12 not two months ago I expressed similars concerns and the consensus was to add examples to the wiki

23:13 wlangstroth: I'm just collecting them myself - sometimes off walton, but usually just doing the simplest thing possible with the function

23:13 eventually, I'll get people to tell me which ones aren't helpful

23:13 TheBusby: yeah, I have my own little cheat buffer I keep with examples for various calls

23:14 I just wish the doc string looked more like a man page and less like a javadoc

23:14 ninjudd: wow! checking out walton. what a great idea

23:15 lancepantz: i use walton all the time

23:15 thought i had told you about it

23:15 ninjudd: be nice if each example had the result too

23:15 lancepantz: maybe

23:16 i've never seen it in action though

23:16 lancepantz: that would enforce all of them to be independently valid though

23:16 he just scrapes the logs for inputs to the repl bot

23:16 ninjudd: seems invalid examples wouldn't be very useful

23:17 oh, you mean they may depend on other commands

23:17 lancepantz: yeah

23:17 i guess the repl bot would have the same problem though

23:17 ninjudd: does it keep state?

23:17 clojurebot: mutable state is bad

23:18 lancepantz: hahaha

23:18 ninjudd: ,(def foo 1)

23:18 clojurebot: DENIED

23:18 ninjudd: i see

23:19 Raynes: I'm fairly certain that walton scrapes the examples and runs each one of them to see if they are valid.

23:20 lancepantz: i thought he also had the book example in there

23:20 but maybe thats just a planned thing

23:21 wlangstroth: TheBusby: are you keeping any of those examples in a public place?

23:21 TheBusby: wlangstroth: unfortunately not yet

23:21 I'd be happy to give them out after I've cleaned them up a bit

23:24 wlangstroth: cool, thanks

23:28 TheBusby: I've actually had the best luck so far just grepping through contrib

23:29 I created a simple bash script that just does the following, "find ${CLOJURE_HOME}/clojure-contrib/src/clojure/contrib/ | grep clj$ | xargs -i grep --color=auto -inH $1 {}"

23:29 for more complex items like zipmap though, I've relied on google

23:37 arohner: clojure needs a *warn-on-slow-math*

Logging service provided by n01se.net