#clojure log - Sep 02 2009

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

0:05 technomancy: wow, I just got bit by lisp-1-ness for the first time ever.

0:08 lisppaste8: technomancy pasted "crazy proxy macro" at http://paste.lisp.org/display/86410

0:08 technomancy: so my methods map isn't working with init-proxy; not sure why

0:08 guess I should try it with a map that doesn't need tweaking first

0:18 lisppaste8: technomancy annotated #86410 "almost works" at http://paste.lisp.org/display/86410#1

0:19 technomancy: so this works if I remove IMeta from the proxy definition

0:21 the meta method just needs to return a map and take zero args, right?

0:21 why would it be raising an UnsupportedOperationException?

0:22 hiredman: someing is trying to mutate something

0:22 the clojure collections all throw that exception if you call a mutable part of the collections interface

0:23 possibly something else of course

0:25 technomancy: http://p.hagelb.org/meta-exception.html <= it looks like the repl is actually raising the exception by trying to look up the type in the meta map

0:26 oh... init-proxy _replaces_ a proxy's methods.

0:26 I want update-proxy

0:26 hiredman: oh

0:27 do you have a fn implementing that method in the map?

0:27 proxy throws that for unimplemented interface methods too

0:27 technomancy: nope, just in the original proxy

0:27 clojurebot: proxy is <Chouser> proxy teases with its ease of use, then suddenly betrays.

0:27 technomancy: so true!

0:27 ,botsnack

0:27 clojurebot: java.lang.Exception: Unable to resolve symbol: botsnack in this context

0:27 hiredman: pashaw

0:27 technomancy: ~botsnack

0:27 clojurebot: thanks; that was delicious. (nom nom nom)

0:33 technomancy: well that's enough Macro Madness for tonight.

0:33 thanks.

2:07 LauJensen: Doesnt 'if' abort evaluation if the first item or can 'or' body evalutes to false?

2:08 hiredman:

2:09 brool: LauJensen: not sure I understand the question

2:09 "or" short circuits if any item is true

2:09 hiredman: not the most readable thing

2:09 LauJensen: ,(if (or (= 2 1) (= 3 (+ 1 2))) (prn "foo") (prn "bar"))

2:10 clojurebot: "foo"

2:10 LauJensen: Is (+1 2) ever evaluated?

2:10 Answer then is no, thanks :)

2:10 hiredman: uh

2:10 brool: ( + 1 2 ) is evaluated there

2:10 because first condition is false

2:10 hiredman:

2:11 (= 2 1) is false so (= 3 (+ 1 2)) is evaluated

2:11 and is true, so the if expression evaluates to the result of evaluating (prn "foo")

2:12 which prints out "foo" as a side effect

2:12 brool: ,(or (do (println "did first clause... ") (= 2 1)) (do (println "did second clause... ") (= 3 (+ 1 2))))

2:12 clojurebot: true

2:12 did first clause... did second clause...

2:14 LauJensen: Yes yes I got it, thanks :) I wrongfully put in a false first clause

4:06 alinp: hi

4:06 I have a function like this:

4:06 (defn my-f [fn] (fn))

4:06 (def x (fn [a b] (+ a b)))

4:07 (my-f (x 2 3))

4:07 how can I make this work ?

4:07 I mean .. calling fn inside my-f

4:07 hiredman:

4:07 you need to pass my-f a function

4:08 (x 2 3) is not a function

4:08 rathore: hiredman: just curious... what timezone are u in?

4:08 hiredman: west coast of america

4:09 rathore: hiredman: ok... just wondering, cause you're always here helping folks... very grateful to you :)

4:09 hiredman: :P

4:12 alinp: hiredman: but I need also to pass the argumens

4:12 arguments

4:12 I need to call apply inside my-f ?

4:13 hiredman: no

4:13 alinp: (defn my-f [fn & args] (apply fn args))

4:13 (my-f x 1 2)

4:13 this works

4:13 hiredman: sure that'll work too

4:14 alinp: can you please tell me how can I do that beside of apply ?

4:14 hiredman: pass in a functio to my-f

4:14 my-f takes one arg fn

4:14 alinp: yeah

4:14 hiredman: the body of my-f is (fn) which is a function call

4:14 alinp: (def x (fn [a b] (+ a b)))

4:15 x is a function

4:15 hiredman: sure

4:15 alinp: so

4:15 hiredman: but (x 2 3) is not

4:15 alinp: ok ...

4:15 hiredman: (x 2 3) is function application

4:15 alinp: ok ...

4:15 hiredman: so what happens is (x 2 3) evaluates to 5

4:15 alinp: so, 5 is sent instead of fn

4:15 true

4:16 hiredman: so my-f attempts to call 5 as a function

4:16 which, well, doesn't work

4:16 alinp: (my-f (fn [] (x 1 2)))

4:17 should do the trick

4:17 right ?

4:17 hiredman: yes

4:17 there is also a handy bit of syntactic sugar for this

4:17 #(x 1 2)

4:17 alinp: oh, yeah :)

4:17 I knew that

4:17 I like to be more verbose when comes to lambda functions ;)

4:18 but, thanks for reminding me

4:18 hiredman: sure

4:20 nsel: when clicking on stack trace frames in swank-clojure, I get "Synchronous Lisp Evaluation aborted." just want to check before filing a bug report, does anyone here get something different when they click on a stacktrace frame?

4:20 I've been seeing this behavior for months, and have latest git version

4:21 wouldn't be surprised if that's just how it's supposed to be, not yet implemented, as well

4:22 (test case: trigger any error which brings up a slime backtrace and click on a frame).

4:26 incase this wasn't clear, normally you'd expect it to jump to a source location.

5:03 AWizzArd: when I included a .txt file into my .jar, how can I then slurp the contents of that .txt file?

5:04 Chousuke: hmm

5:04 I think you can use @ in a path to mean "classpath-relative"

5:05 AWizzArd: I would like to include it in the .jar instead of putting it outside

5:05 I already tried (slurp "@/com/company/file.txt")

5:05 hiredman: (.getResourceAsStream (clojure.lang.RT/baseLoader) "version") where version is the name of a textfile

5:06 that gets you an inputstream

5:08 AWizzArd: maybe I can use duck-streams reader function with that

5:10 hiredman: ,(doc reader)

5:10 clojurebot: "clojure.contrib.duck-streams/reader;[[x]]; Attempts to coerce its argument into an open java.io.BufferedReader. Argument may be an instance of Reader, BufferedReader, InputStream, File, URI, URL, or String. If argument is a String, it tries to resolve it first as a URI, then as a local file name. URIs with a 'file' protocol are converted to local file names. Uses *default-encoding* as the text encoding. Should be used in

5:10 hiredman: says it takes an input stream

8:48 lisppaste8: raphinou pasted "help for translating from OO to clojure" at http://paste.lisp.org/display/86427

8:48 raphinou_: if someone has the time to look at this paste, I can use some help

8:49 trying to translate OO code in clojure, and I don't see how to keep funtionality without the instance variables that are used in the OO example

8:54 noidi: raphinou_, you could create check-credentials inside make-login-widget

8:54 then it could access all the variables in a closure

8:55 raphinou_: yes, seems obvious now you say it :-)

8:55 Chouser: I keep losing the link to that blog post that walks through a few different ways to do "objects" in Clojure.

8:56 but generally, closing over the "instance" data is one way. Another is to put that data in a vector or map and pass it around.

8:56 raphinou_: ok

8:57 I was afraid my function would grow horribly, but in a sense it's fine to have it defined in there, as it only makes sense to use it there

8:58 noidi: i thought about this myself a few days ago, and here's the toy code i worked with: http://pastebin.com/d44188f91

8:58 AWizzArd: raphinou_: you can use defstruct to define the fields of your "class" and define multimethods on it. One example, pretty much what Chouser said.

8:59 Chouser: no point in multimethods unless you expect to override them.

8:59 noidi: this macro even gets rid of the duplication in the clojure version http://groups.google.com/group/clojure/msg/5ef807214247472d

9:01 rhickey: raphinou_: just pass the data in a map

9:01 then you get a nice function you can test without a gui

9:01 triyo: Anyone know of any native HTML parser for clojure?

9:02 Chouser: triyo: what do you mean by "native"? tagsoup has worked well for me.

9:02 raphinou_: thx all for your answers!

9:03 triyo: Chouser: by native I mean non-java introp way

9:04 Chouser: triyo: nope, don't know of such a thing. What would be the benefit of avoiding interop?

9:05 noidi: Chouser, is this the blog post you mentioned? http://blog.thinkrelevance.com/2009/8/12/rifle-oriented-programming-with-clojure-2

9:05 Chouser: noidi: no, though that's good too.

9:06 triyo: Chouser: no real benefit I guess except that it will perhaps be more lispy. I'll give tagsoup a try.

9:06 noidi: I love the analogy :) "Its a little like saying that a rifle is not arrow-oriented."

9:18 * cgrand loves to deeply nest -> and doto forms...

9:20 ole3: test

9:29 ambient: hmm, to me OO is mainly about hiding the complexity that arises from mutability. clojure doesnt really have a lot of that so therefore clojure doesn't need OO that much

9:29 also, OO is more about messages than it is about objects imo

10:23 LauJensen: Gents, what would be the most elegant way to scramble a sequence randomly? ie (scramble [1 2 3 4 5]) => [4 1 5 3 2], (scramble [1 2 3 4 5]) => [1 3 4 2 5] ?

10:25 Chousuke: LauJensen: probably best to use java for that.

10:25 convert to array, scramble, convert back to vector.

10:28 raphinou___: is it normal that drop-fruit is displayed at http://richhickey.github.com/clojure-contrib/sql-api.html ?

10:29 and in general the functions from the sql.test ns ?

10:35 Chouser: hm.. does seem likely that's a mistake.

11:15 LauJensen: Chousuke: When I said 'the most elegant way', what on earth got you thinking Java?

11:16 Fossi: LauJensen: i think there's a function for that in some util in contrib

11:16 seq-util prolly

11:20 liwp: ,(let [l (java.util.ArrayList. [1 2 3])] (do (java.util.Collections/shuffle l) l))

11:20 clojurebot: #<ArrayList [1, 3, 2]>

11:20 liwp: so how do you make a vector / list out of the ArrayList again?

11:20 Chousuke: LauJensen: because java probably has a method for scrambling arrays :P

11:21 liwp: and no, that's not particularly elegant, especially with the inplace shuffle, but it's quite short

11:21 Chousuke: LauJensen: and it's going to be faster than anything you can do with immutable vectors :)

11:21 liwp: Chousuke: yep, java.util.Collections/shuffle which takes a List

11:22 stuartsierra: c.c.seq-utils/shuffle just calls ArrayList/shuffle.

11:22 Chousuke: ,(vec (ArrayList. [1 2 3]))

11:22 clojurebot: [1 2 3]

11:22 liwp: stuartsierra: heh, I didn't look that far :)

11:23 ,(let [l (java.util.ArrayList. [1 2 3])] (do (java.util.Collections/shuffle l) (vec l)))

11:23 clojurebot: [2 1 3]

11:23 Chousuke: that's going to be as elegant as you can get I suppose.

11:23 stuartsierra: Others have written shuffle fns using, e.g., Knuth's algorithm for arrays of unknown length, but ArrayList/shuffle is much efficient.

11:23 *more efficient.

11:24 liwp: stuartsierra: I'm not seeing a shuffle in ArrayList

11:24 Chousuke: hm

11:24 stuartsierra: It's part of the Collections interface, I think.

11:24 Chousuke: ,(instance? List [])

11:24 clojurebot: java.lang.Exception: Unable to resolve symbol: List in this context

11:24 Chousuke: ,(instance? java.util.List [])

11:24 clojurebot: true

11:25 stuartsierra: ,(java.util.Collection/shuffle [1 2 3 4 5])

11:25 clojurebot: java.lang.IllegalArgumentException: No matching method: shuffle

11:25 stuartsierra: ,(.shuffle [1 2 3 4 5])

11:25 clojurebot: java.lang.IllegalArgumentException: No matching field found: shuffle for class clojure.lang.LazilyPersistentVector

11:25 Chousuke: ,(java.util.Collections/shuffle [1 2 3 4 5])

11:25 clojurebot: java.lang.UnsupportedOperationException

11:25 Chousuke: ,(java.util.Collections/shuffle (transient [1 2 3 4 5]))

11:25 clojurebot: java.lang.Exception: Unable to resolve symbol: transient in this context

11:25 Chousuke: damn :P

11:26 I guess there is no getting around the mutability.

11:26 ambient: back to netbeans from emacs, enclojure seems to have developed nicely last time i tried it. with emacs it's a bit hard to add external libraries

11:26 Chousuke: but if it's only an implementation detail it doesn't exist :)

11:26 stuartsierra: Nope. seq-utils/shuffle copies to an ArrayList and calls shuffle on that.

11:26 clojurebot: shuffle is http://groups.google.com/group/clojure/msg/a2816f1b51d99b79

11:27 stuartsierra: there you go

11:27 liwp: thank you clojurebot!

11:28 Chousuke: for once the autocomment feature triggered at the right time :)

11:39 LauJensen: Sweet :)

11:40 Thanks for taking up the discussions guys :)

11:46 Chouser: I've got a question about the finger-tree paper. I don't suppose anyone here has read it enough to help me come up with an answer?

11:47 Licenser: 42!

11:47 rhickey: not necessarily an impediment :)

11:47 shoot

11:47 Licenser: rhickey: you're the clojure guy right?

11:47 Chouser: it looks to me like the measure function is applied at all levels of the tree

11:48 rhickey: Licenser: yes

11:48 Licenser: then good work! Keep it going :D

11:49 Chouser: that is, if the measure function is the domain of all measure functions has to include type a (the basic element type), type Node a, type Node Node a, etc.

11:49 slyrus_: hmm.. wasn't sure if there was going to be a #clojure, much less one with 142 users. :)

11:49 Chouser: s/if the/the/

11:49 Chousuke: heh

11:50 this channel is often better for getting in touch with the right people than the group is :P

11:50 slyrus_: group?

11:50 Chousuke: the google group

11:50 slyrus_: ah, ok

11:51 Chouser: bleh, I messed that up too much. I'll try again.

11:51 the domain of all measure functions has to include type a (the basic element type), type Node a, type Node Node a, etc.

11:53 but that doesn't seem very nice to me. surely the measure fn ought to only have to understand type a

11:55 rhickey: doesn't || pluck out the v?

11:56 Chouser: || on a node simply returns the cached v, yes.

11:56 rhickey: doesn't that happen always before the measure is applied?

11:57 Chouser: But when constructing the node with the "smart constructors" at the top of section 4.2, they just do ||a|| (+) ||b||, where a and b could be of any nested Node depth

11:57 djpowell: Hmm, whilst the 'recur' examples on the transients page work well, I'm finding that doing something like: (reduce (fn [m [k v]] (assoc! m k v)) (transient m1) mymap) - doesn't perform much differently than the persistent version - is that to be expected?

11:57 Chouser: oh

11:58 right. ok, if a is a Node, || on it will return the cached.

11:58 only if a is a Digit will it try to apply the user-supplied measure fn

11:59 somehow I lost this in the conversion from vectors-with-metadata to reify'd objects, and then got too muddled to put it back together.

12:00 rhickey: Chouser: I know you've been planning on exposing the measure system generically, just want to point out the utility of a version with it hardwired: http://hackage.haskell.org/packages/archive/containers/

12:01 Chouser: rhickey: yes, I have vague plans to do both.

12:01 rhickey: It all starts with vague plans :)

12:02 Chouser: that is, a generic underlying thing with no built-in measure (perfect for simple queues)

12:02 then something built on top that implements Indexed by measuring size

12:03 perhaps some nicely packaged priority queue. etc.

12:26 djpowell: I think my problem is probably that even the persistent collections perform so well that the calculations I am doing dominate the time taken to build the collection

12:26 which is good

12:39 ole3: hello, is there a way to stop and resume processes in clojure?

12:44 leafw: ole3: process are java Threads. So yes.

12:46 ole3: leafw: really? I thought a process lives in its own address space.

12:48 leafw: er, a virtual machine is just that, virtual.

12:49 ole3: leafw: ok, can you tell me how?

12:50 leafw: something like SIGSTOP?

12:51 leafw: ole3: are you talking about OS process, which are just the JVM ?

12:54 ole3: leafw: I'm talking about an OS process started via (.exec (Runtime/getRuntime) ...)

12:54 leafw: ole3: ah! Then, catch the returned object

12:54 ole3: leafw: ok got it, stored in *process* :)

12:55 leafw: yes

12:55 ole3: leafw: Here it is: #<UNIXProcess java.lang.UNIXProcess@16917ee>

12:55 leafw: unfortunately, the http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Process.html seems not to have anything else to do other than destroy(), so you have to cast blindly

12:56 to the subclass.

12:56 i.e. inspect its methods, it may have what you want :)

12:56 ole3: hm, to what subclass?

12:57 It has exitValue, destroy, waitFor, but not stop

12:57 leafw: java.lang.UNIXProcess is likely a subclass of java.lang.Process

12:58 dave[csc]: Is there an issue with defining an empty vector? a la (def myvec vec)

12:58 ole3: yes, it is one

12:58 leafw: ole3: then the UNIXProcess maybe has other methods. If not, then ... you are stuck.

12:59 ole3: leafw: oh my god

13:01 leafw: does this mean i have to use jni or jna for stopping processes

13:01 Chousuke: can't you send a suspend signal to the process?

13:02 ole3: i don't know the pid

13:13 Chouser: dave[csc]: vec is not an empty vector, it's a function to create vectors. [] is an empty vector

13:22 ole3: ok, i will use jna, thanks for your help

13:28 ambient: im wondering if i can just use arrays & stuff for mutable data structures and not really care

13:28 i really love the lispiness but the immutability is seriously giving me a headache

13:30 Chouser: ambient: sure you can, but it'll be better for you in the long run if you push through on the immutability front.

13:31 ambient: well i find it really hard to vision games done mostly with immutable data

13:33 Chouser: performance issues are one thing. headaches another.

13:41 ericthorsen: I see there is a logging namespace in clojure.contrib but it does not appear that anyone is using it (in the contrib lib I mean)

13:42 Is there a preferred way to handle this in the contrib code? or is logging frowned upon?

13:42 technomancy: ericthorsen: I just started using it

13:42 planning on backporting it to the 1.0-compat branch, actually

13:43 Chouser: oh, I see -- if a contrib lib needs to log something?

13:43 ankou: hi, is it possible (and advised) to split one namespace over several files?

13:43 ericthorsen: Chouser: exactly

13:44 Chouser: ankou: certainly possible. proxy and genclass are in clojure.core namespace but live in their own .clj files.

13:44 ericthorsen: dunno, haven't needed it. For me it's seemed best so far to leave error handling up to the app -- it can log or abort or whatever as needed.

13:45 ericthorsen: technomancy: it is omitted from the build and does not appear to load unless it can see all the libs (log4j, apache.commons.logging, etc.) which I assume defeats the purpose. Perhaps I do not know how to use it?

13:45 technomancy: ericthorsen: it works with java.util.logging if the others are not found

13:45 ankou: Chouser: is it recommended to split it in several files and load these?

13:46 Chouser: better question: is this errorprone or something like that?

13:46 Chouser: ankou: Not sure when it's recommended but it's definitely supported.

13:47 ericthorsen: Chouser: You do not see utility in library code providing any logging?

13:47 Chouser: ankou: note how the top of core_proxy.clj differs from most .clj lib files. It's a "secondary" file, so it doesn't define the namespace with an 'ns' macro call. instead it uses in-ns and import.

13:48 ericthorsen: I haven't written a libarary where it felt like the right choice. I'm making no claims about the general case. :-)

13:49 ericthorsen: Chouser: ok

13:49 technomancy: ericthorsen: the logging library is quite new.

13:49 ericthorsen: technomancy: I see.

13:51 Chouser: I find having the ability to enable logging in APIs I am not the author of useful in troubleshooting problems. It has been a life saver working in the behemoth Netbeans framework for example.

13:52 Chouser: I can do what I need to in contrib without it for sure...just curious as to what the current thinking was there

13:52 ankou: Chouser: so it is convention to use a namespace for each file even in normal non-library programs?

13:52 Chouser: or do they normally use the User namespace ?

13:53 Chouser: ankou: Most namespaces are defined by a single file.

13:54 ankou: I'd not recommend using the 'user' namespace except for repl, work-in-progress, toy code, etc. It won't AOT compile, might clash with others code, etc.

13:55 any lib or releasable app ought to use its own namespace

13:55 ankou: Chouser: with several minor namespaces? because I think it would somewhat confusing to have several thousand lines in one file

13:56 opqdonut: sure

13:56 i use subnamespaces all the time

13:57 Chouser: sure, if your code gets to be more than you want for a file, you can add more files, either in the same namespace or in new namespaces.

13:57 I guess I would generally add a new namespace when I add a new file, unless I had a specific reason to extend an existing namespace.

13:58 hiredman: calling them subnamespaces is some what confusing

13:59 ankou: but you know what I mean

13:59 or opqdonut xD

13:59 okay thanks

13:59 hiredman: as far as I can tell there is no hierarchy of namespaces just like there is no hierarchy of java packages

13:59 opqdonut: yeh

13:59 Chouser: right, just a hierarchy of names. :-/

14:17 mibu: I have a peculiar bug with for. The first binding form is always binding to the first element of a sequence. Can someone shed some light on this behavior? http://codepad.org/8BY0KlQi

14:17 I'm using 1.1

14:20 stuartsierra: for iterates over all bindings, last-fastest

14:20 if the last binding is to an infinite sequence, the first binding will never advance

14:21 mibu: what do you mean?

14:21 Chouser: it's like a nested loop.

14:21 stuartsierra: ,(for [i (range 5) j (range 5)] [i j])

14:21 clojurebot: ([0 0] [0 1] [0 2] [0 3] [0 4] [1 0] [1 1] [1 2] [1 3] [1 4] [2 0] [2 1] [2 2] [2 3] [2 4] [3 0] [3 1] [3 2] [3 3] [3 4] [4 0] [4 1] [4 2] [4 3] [4 4])

14:21 mibu: oh, I see.

14:21 so, you can't bind to infinite sequences in for?

14:22 stuartsierra: Not if they're nested.

14:22 Chousuke: you can, but it makes no sense :)

14:22 mibu: what's a better elegant way to create pairs from a single sequence?

14:22 Chousuke: at least, not without :while

14:22 Chouser: sure you can, but if any level is infinite and not terminated by a :while, then you'll just never get to the next iteration of the outer level

14:22 Chousuke: partition?

14:23 mibu: chousuke: yes! thank you.

14:23 I hate it when I forget simple useful functions.

14:24 Chousuke: note that partition may require padding if you have an uneven sequence

14:24 mibu: I have an infinite sequence.

14:24 Chousuke: oh, okay :)

14:26 mibu: There ought to be a place with all those little gotchas for every function. I haven't coded in clojure for two months and I already forgot plenty of those gotchas.

14:27 Chousuke: start a blog series.

14:27 :)

14:28 ambient: reverse of partition seems to be for

14:28 mibu: I was thinking maybe an add-on to the internal documentation (doc). you know, with examples, gotchas, guidelines, and other cookbook stuff.

14:28 * angerman just figured you can earn quite some karma points on hackernews for posting clojure related articles :)

14:28 Chousuke: heh

14:28 ambient: [[2 4] [3 5]] (for [x coll] (first x)) seems to be shortest way ot generating seq from the first items

14:29 Chouser: (map first coll)

14:29 ambient: :( *dohh*

14:29 Chousuke: and the reverse of partition is concat

14:29 ,(apply concat (partition 2 [1 2 3 4])

14:29 clojurebot: EOF while reading

14:29 Chousuke: whoops

14:29 ,(apply concat (partition 2 [1 2 3 4]))

14:29 clojurebot: (1 2 3 4)

14:34 ambient: (map #(play-note chan %1 %2) (map first phr) (map second phr)) im sure there's more elegant way to put this

14:37 Chousuke: hm

14:38 play-note looks like it should have a side-effect :P

14:38 ambient: it has

14:38 Chousuke: (doseq [[x y] phr] (play-note chan x y)) then

14:40 you should avoid mapping functions with side-effects

14:41 ,(do (map println ["foo" "bar"]) "foiled")

14:41 clojurebot: "foiled"

14:41 ambient: because map doesn't guarantee sequential access?

14:41 Chousuke: ,(do (doall (map println ["foo" "bar"])) "not foiled")

14:41 clojurebot: "not foiled"

14:41 foo bar

14:41 Chousuke: because map is lazy :)

14:41 doall forces eagerness

14:42 or dorun, if you don't care about the results.

14:43 ambient: this is going to be absolutely horrible..

14:43 im generating a thread for each channel and each pattern

14:43 Chousuke: hm.

14:43 you might have problems keeping them in sync :P

14:46 ambient: or alternatively i could convert these: (def phr-melod-1 [[60 250] [64 250] [60 250] [65 250]]) into event model

14:47 so i need to convert from note duration to its position in time

14:57 damn.. its surprisingly complex to build accumulating value over seq and make a new seq out of it

14:58 Chouser: :-)

14:58 ambient: or perhaps i could use reduce

14:58 Chouser: ,(reduce (fn [[acc time] [dur freq]] [(conj acc [time freq]) (+ time dur)]) [[] 0] [[1 :a] [4 :b] [3 :c] [1 :d]])

14:58 clojurebot: [[[0 :a] [1 :b] [5 :c] [8 :d]] 9]

14:58 rhickey: ,(reductions + (range 5))

14:58 clojurebot: java.lang.Exception: Unable to resolve symbol: reductions in this context

14:58 rhickey: (clojure.controb.seq-utils/reductions + (range 5))

14:58 ,(clojure.controb.seq-utils/reductions + (range 5))

14:58 clojurebot: java.lang.ClassNotFoundException: clojure.controb.seq-utils

14:59 rhickey: ,(clojure.contrib.seq-utils/reductions + (range 5))

14:59 clojurebot: java.lang.ClassNotFoundException: clojure.contrib.seq-utils

14:59 Chouser: ,(use 'clojure.contrib.seq-utils)

14:59 clojurebot: nil

14:59 rhickey: ,(reductions + (range 5))

14:59 clojurebot: (0 1 3 6 10)

14:59 ambient: nifty :)

15:00 Chouser: the problem in this case is you're off by one

15:00 ,(reductions (fn [[p v] [d v]] [(+ p d) v]) [[1 :a] [4 :b] [3 :c] [1 :d]])

15:00 clojurebot: ([1 :a] [5 :b] [8 :c] [9 :d])

15:01 Chouser: :b should start at time 1, not 5. 5 is when :b should end and :c should start.

15:05 ,(map (fn [[[t] [_ v]]] [t v]) (partition-all 2 1 (concat [[0]] (reductions (fn [[p] [d v]] [(+ p d) v]) [[1 :a] [4 :b] [3 :c] [1 :d]]))))

15:05 clojurebot: ([0 :a] [1 :b] [5 :c] [8 :d] [9 nil])

15:05 Chouser: destructuring ftw!

15:07 LauJensen: ftw?

15:08 Chouser: For The Win!

15:08 LauJensen: ah okay

15:09 ambient: (map #(- % (second (first phr))) (reductions + (map second phr))) seems to work ok :)

15:10 Chouser: ambient: heh. well, that's better.

15:10 ambient: but thats not the best way to do it i think

15:14 (all-but-the-last (reductions + (map second (cons [0 0] phr-melod-1))

15:15 no.. (all-but-the-last (cons 0 (reductions + (map second phr))))

15:16 Chousuke: all-but-the-last is called butlast :P

15:16 ambient: ok, good to know

15:16 Chouser: or drop-last

15:17 drop-last is lazy, butlast is not.

15:23 ankou: hi again, is there a possibility to use string manipulation with symbols or how are the .javaShortFunctionCalls created?

15:24 hiredman: huh?

15:25 Chouser: ,(str 'foo) ; like this?

15:25 clojurebot: "foo"

15:25 hiredman: ,(name 'foo)

15:25 clojurebot: "foo"

15:25 Chouser: ,(symbol (str "." "foo" "Bar")) ; or like that?

15:25 clojurebot: .fooBar

15:26 ankou: oh great :D

15:27 * hiredman doubts

15:28 Chousuke: ankou: if you need it in a macro you can just use . directly

15:34 ambient: (partition 2 (interleave (map first phr)

15:34 (drop-last (cons 0 (reductions + (map second phr)))))))

15:34 isnt very pretty :/

15:34 but gets the job done

15:35 LauJensen: ambient: thats kinda funny because I've heard Chouser described that exact way by his employer

15:35 ambient: hehe

15:38 in an imaginary language the problem would be about: new second element = accumulate old from 0

15:39 how that could be expressed in sexps is beyond me

15:40 hiredman: (-> phr ((partial map second)) ((partial reductions +)) ((partial cons 0)) drop-last)

15:41 Chousuke: :P

15:42 that's just ugly.

15:42 hiredman: (comp drop-last (partial cons 0) (partial reductions +) (partial map second))

15:42 Chousuke: hardly

15:42 Chousuke: the latter is much better.

15:43 the first one is just abuse of ->

15:43 * hiredman is hurt that you would claim he abused ->

15:43 Chousuke: it happens :)

15:44 ambient: comp/partial, seems useful

15:44 Chousuke: mostly the weird double parentheses offend me.

15:44 hiredman: whenever I play around try to work out a function in a repl it always turns into a big long -> expression

15:44 you get used to the double parens

15:45 Chousuke: I don't use partial that much either

15:45 LauJensen: Chousuke: Did you catch this anonymous contribution?

15:45 ,(reduce #(let [i (rand-int %2) j (dec %2)] (-> %1 (assoc i (%1 j)) (assoc j (%1 i)))) [1 2 3 4 5] (range 5 1 -1))

15:45 clojurebot: [2 1 3 5 4]

15:46 hiredman: gnarly

15:46 Chousuke: it's better in haskell because of autocurrying

15:46 but I like being explicit.

16:16 angerman: how would I nuke all lines from a string that start with %.... ?

16:17 e.g. I have a file that uses % as comment indicator

16:18 tomoj: angerman: you read the entire file into a string? or a seq of lines?

16:18 ankou: is there a function to expand inner lists? something which makes ((1 2) (3 4)) to (1 2 3 4)?

16:18 angerman: tomoj: I read the whole file it's not that large

16:19 tomoj: but I guess it's like (split on \n resp \r\n)

16:19 filter the lines and glue it back together.

16:19 hiredman: ,(doc line-seq)

16:19 clojurebot: "([rdr]); Returns the lines of text from rdr as a lazy sequence of strings. rdr must implement java.io.BufferedReader."

16:20 hiredman: ,(remove #(re-find #"^%.*$" %) ["foo bar baz" "%foo" "bar"])

16:20 clojurebot: ("foo bar baz" "bar")

16:21 angerman: hiredman: thanks. that looks not too bad :)

16:21 tomoj: eh

16:22 angerman: well I guess I screwed up :...

16:22 tomoj: why use a regular expression to do .startsWith?

16:23 angerman: hm line-seq really wants a BufferedReader... slurp's so nice

16:23 tomoj: I guess if whitespace is allowed before the % then a regular expression becomes more useful

16:23 hiredman: tomoj: *shurg*

16:23 tomoj: #"^\s*%" ?

16:26 angerman: hmm.

16:26 maybe I should tackle the problem from a differnt side

16:26 my file consists of blocks separated by two new lines.

16:26 and there may be lines in there that start with %. so all I need at first is just the blocks as a sequence.

16:27 my first thought was: break file into lines, remove all those that startwith %, glue back together and split on \n\n

16:31 hiredman: ,(doc partition)

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

16:31 hiredman: (comp (partial partition 2) line-seq)

16:31 or something

16:49 * angerman is making progress

16:49 angerman: what would be a lisp way to scan a list and when one finds a symbol takes all that has been scanned a turns it into a list, from there on starts with a second list and so on

16:50 e.g. (... "a" ... ... "a" ... ... "a" ... ...) -> (( ... ) (... ...) (... ...))

16:51 ambient: split?

16:51 angerman: would still have to scan the last (... ...)

16:51 ambient: that oddly reminds me of cartman

16:51 hiredman: reduce

16:51 angerman: ambient: well the symbol is actually two in a row. so I though about using peek

16:52 hiredman: if you are parsing stuff, you could just, you know, using a parsing library like fnparse

16:52 of course fnparse apears to be under "heavy developement" at the moment

16:52 :/

16:53 ~fnparse

16:53 clojurebot: Pardon?

16:53 hiredman: ~parse

16:53 clojurebot: parser is http://github.com/joshua-choi/fnparse/tree/master

16:59 angerman: so basically I can use fnparse to construct me a tree like structure?

17:01 ambient: anyone know how i can easily manage additional java libraries in emacs?

17:01 or must i always change .emacs by hand

17:01 hiredman: angerman: you can use it to parse things

17:03 angerman: hiredman: ok. I guess I'll look a lot deeper into that.

17:06 powr-toc: ambient: if you use a script to start clojure, you can have that script consult a .clojurerc file which contains a classpath decleration

17:08 nsinghal: (let [{:keys [a b & ss]} {:a 1 :b 2 :c 3 :d 4}] ss)

17:08 I am trying to capture rest of map in "ss" (other than a & b). How can i do that?

17:09 Chousuke: hm, you can't do that, but you can have access to the whole map.

17:09 hiredman: ,(dissoc {:a 1 :b 2 :c 3 :d 4} :a :b)

17:09 clojurebot: {:c 3, :d 4}

17:09 ambient: i got (0 250 500 750 1000), how do i get (250 250 250 250)?

17:10 Chousuke: ,(let [{:keys [a b c] :as m} {:a 1 :b 2 :c 3 :d 4}] [a b c m])

17:10 clojurebot: [1 2 3 {:a 1, :b 2, :c 3, :d 4}]

17:10 hiredman: ,(repeat 4 (second '(0 250 500 750 1000)))

17:10 clojurebot: (250 250 250 250)

17:11 ambient: :p yeah.. im actually looking for the differences

17:11 but i think it will come to me after a while, i shall save my "points" for asking actually difficult questions

17:12 nsinghal: i thought it wont work - but still was worth a try to ask

17:13 tomoj: ,(map (fn [[a b]] (- b a)) (partition 2 1 '(0 250 500 750 1000)))

17:13 clojurebot: (250 250 250 250)

17:13 nsinghal: it will be nice to have that - validating map input might become easy. (defn [{:keys [a b & ss]}] (when-not ss ...)

17:14 hiredman: ,(map #(- %1 (* %2 250)) '(0 250 500 750 1000) (iterate inc -1))

17:14 clojurebot: (250 250 250 250 250)

17:17 bostwick: Hi

17:18 Does anyone have experience with the clojure plugin for eclipse?

17:19 I'm writing a program to do some xml processing, and when I attempt to print a hash representation of my xml from the repl, eclipse freezes

17:24 tomoj: seems like a "mapply" might be useful sometimes

17:25 like, map, but instead of calling the function on each element, apply the function to each element (where each element is a seq itself)

17:26 replaca: you mean like (map (partial apply f) ...)?

17:27 tomoj: guess so

17:27 replaca: I agree with whoever said earlier (Chosuke?) that they missed "auto-currying from Haskell

17:27 tomoj: ,(map (partial apply #(- b a)) (partition 2 1 '(0 250 500 750 1000)))

17:27 clojurebot: java.lang.Exception: Unable to resolve symbol: b in this context

17:27 replaca: it would be nice to have comp and partial be a little more natural

17:27 tomoj: err

17:28 ,(map (partial apply #(- %2 %1)) (partition 2 1 '(0 250 500 750 1000)))

17:28 clojurebot: (250 250 250 250)

17:28 tomoj: yup

17:28 Chousuke: partial apply?

17:28 brool: replaca: yah, i would like that as well

17:29 replaca: (defn mapply [f & rest] (map (partial apply f) rest))

17:29 I think

17:30 tomoj: but then all the seqs are in a seq

17:32 Chousuke: some reader syntax for comp or partial might be nice... but is there anything left? :P

17:35 ambient: i need to separate items in a list like [4 4 4 3 3 1 1 1 1] -> [ [4 4 4] [3 3] [1 1 1 1] ] any easy way to do this?

17:35 ive been browsing the API but my eyes start to water

17:37 Chousuke: (doc group-by)

17:37 clojurebot: "([f coll]); Returns a sorted map of the elements of coll keyed by the result of f on each element. The value at each key will be a vector of the corresponding elements, in the order they appeared in coll."

17:38 Chousuke: hm not that.

17:43 tomoj: ambient: my attempt: http://paste.lisp.org/display/86466

17:44 ambient: tomoj, well that was my backup plan if there weren't any short combination of existing functions :)

17:46 tomoj: seems like a weird thing to do

17:46 ambient: not so weird when its part of a larger thingie

17:46 ((9 35 0) (4 60 0) (4 0 250) (4 64 250) (9 0 500) (9 38 500) (4 0 500) (4 60 500) (4 0 750) (4 65 750) (9 0 1000) (4 0 1000)) i need to group this by the last items

17:47 tomoj: oh

17:47 that's different

17:47 :)

17:47 I was thinking it was weird because having [1 1 1 1] seems silly if you know that they're all the same anyway

17:48 ambient: but i can just (map #(weird-thingie (last %)) myseq)

17:48 hmm wait

17:49 tomoj: you can just use my split-groups except pass a function in to use instead of just doing plain =

17:49 ambient: im still trying to come up with a higher level solution

17:50 tomoj: group by works but it gives you something different

17:50 ambient: but i got your version saved for future reference

17:50 tomoj: depends on if order matters

17:50 ambient: order matters

17:50 tomoj: within a group only? or you need the groups in the right order too?

17:50 hiredman: ,x

17:50 clojurebot: ((9 35 0) (4 60 0) (4 0 250) (4 64 250) (9 0 500) (9 38 500) (4 0 500) (4 60 500) (4 0 750) (4 65 750) (9 0 1000) (4 0 1000))

17:50 hiredman: vals (reduce (fn [map group] (update-in map [(last group)] conj group)) {} x))

17:50 er

17:51 ,(vals (reduce (fn [map group] (update-in map [(last group)] conj group)) {} x))

17:51 clojurebot: (((4 0 1000) (9 0 1000)) ((4 65 750) (4 0 750)) ((4 60 500) (4 0 500) (9 38 500) (9 0 500)) ((4 64 250) (4 0 250)) ((4 60 0) (9 35 0)))

17:51 tomoj: wat

17:51 oh, that's just like group by though, right?

17:51 ambient: well those are instrument events (channel note time-location)

17:51 when note = 0 its note off

17:51 tomoj: I mean, wrong order

17:52 hiredman: by grouping you are changing the order

17:52 I don't see how you can expect to keep an order

17:52 ambient: main thing is that note-offs dont come after the note-ons in the same time-slot

17:52 tomoj: uhh

17:53 hiredman: ,(vals (reduce (fn [map group] (update-in map [(last group)] conj group)) (sorted-map) x))

17:53 clojurebot: (((4 60 0) (9 35 0)) ((4 64 250) (4 0 250)) ((4 60 500) (4 0 500) (9 38 500) (9 0 500)) ((4 65 750) (4 0 750)) ((4 0 1000) (9 0 1000)))

17:53 ambient: it can be explicitly defined though

17:53 tomoj: [4 4 4 4 3 3 3 1 1 1] -> [[4 4 4 4] [3 3 3] [1 1 1]] ?

17:53 ah, that works

17:53 hiredman: tomoj: his sample is not ordered that way though

17:53 ,x

17:53 clojurebot: ((9 35 0) (4 60 0) (4 0 250) (4 64 250) (9 0 500) (9 38 500) (4 0 500) (4 60 500) (4 0 750) (4 65 750) (9 0 1000) (4 0 1000))

17:54 hiredman: oh, it is, anyway

17:54 ambient: note-on note-off only matters in the same channel, which is the first val

17:54 hiredman: you would map a sort function over each group

18:14 lisppaste8: ambient pasted "split-groups" at http://paste.lisp.org/display/86467

18:14 ambient: i did scheme-y version of it that maintains order

18:14 it's pretty simple, but i dont know what patterns can be extracted from that

18:21 nvm.. i need to sleep

18:21 slyrus_: I get a bunch of errors like this: [java] java.io.FileNotFoundException: Could not locate clojure/stacktrace__init.class or clojure/stacktrace.clj on classpath: (jmx.clj:10)

18:21 when trying to build clojure-contrib

18:21 should I worry?

18:22 ambient: i usually have to tell clojure.jar path manually to ant: ant -Dclojure.jar=../clojure/clojure.jar

18:37 slyrus_: ambient: yeah, I did that... it fails earlier if I don't do that

19:35 rhickey: put Clojure data directly into RDF triple store: (store-root #^{:woo :hoo} {:a 1 :b 2 :c #{3 4 5} :d {:e 6 :f [7 8 9]} :g [1 2 3] :h "ten" :i 10.42})

19:37 reload and recover full structure in a single call

19:37 org.clojure.rdfm=> (reload (::id ^*1))

19:37 {:i 10.42, :h "ten", :g [1 2 3], :d {:f [7 8 9], :e 6}, :c #{3 4 5}, :b 2, :a 1}

19:38 org.clojure.rdfm=> ^*1

19:38 {:org.clojure.rdfm/id #<URI urn:uuid:13e52fec-ce9b-4060-bc64-5d02792495fa>, :woo :hoo}

22:10 tomoj: what's the "triple" there?

22:15 hiredman: http://www.thelastcitadel.com/images/prolog.jpg <-- $2 at goodwill

22:25 tomoj: is there a "clojure monads for dummies" out there?

22:26 I am tremendously confused by both of the intros I've tried to read

22:26 hiredman: monads are confusing

22:27 * hiredman doesn't get them

22:38 tomoj: maybe I should just finally learn haskell

23:33 technomancy: so I'm trying to use update-proxy to provide a proxy with a map of methods.

23:33 I'm using zipmap to turn the keyword keys into strings, and that works fine

23:34 I also want to wrap the fn values in the map in another map, but I get a strange ClassNotFoundException when I try it.

23:34 http://p.hagelb.org/applet.clj.html

23:34 ^ if I replace the bind-applet with identity in the zipmap, it works fine

23:39 it looks like if bind-applet returns a named function it works, but returning an anonymous function breaks

23:41 even stranger: returning a named function from clojure.core or clojure.xml works, but returning a named function from my own namespace or from contrib breaks.

23:44 hiredman: sounds like a classloader issue

Logging service provided by n01se.net