#clojure log - Sep 27 2009

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

2:58 ngoc: It seems a variable must be of one of the 4 reference types: Var, Atom, Agent and Ref. Is there a type other than these types?

3:02 jwhitlark: I'm trying to compile and run a jar via ant using instructions from: http://www.lithinos.com/Compiling-Clojure-applications-using-Ant.html

3:03 I keep getting "Could not find the main class"

3:04 Are there any other recommended resources? My google-fu seems to be failing me tonight.

3:13 ngoc: jwhitlark: Don't you want to use Maven? I use Maven to compile Clojure programs, it is very easy, just follow instructions on the Google group of Clojure.

3:14 jwhitlark: hmmm. is that the preferred way?

3:14 ngoc: I'll take a look at maven then.

3:15 The interesting thing is the class file is compiled properly, and I can run it that way, but it can't find it from the manifest file in the jar.

3:16 I'm just trying to jar up the example on the clojure site, nothing fancy.

3:18 ngoc: Sorry I don't use Ant. But in my experience compiling Clojure with Maven is very easy because there is a convention, you can't be wrong.

3:21 fullets: Is there an easier way to distinguish a valid hash map from e.g. the result of (read-string "{:a 1 :b}") than trying to print it and seeing if an exception is thrown?

3:21 jwhitlark: ngoc: thanks for your help. I'll go read up on maven

3:27 _mst: jwhitlark: Just a tiny example of doing it manually if it helps: http://dishevelled.net/compile.txt

3:27 nice to know what ant/maven are doing behind the scenes I think :)

3:27 jwhitlark: thanks!

3:28 I'll give it a spin.

3:33 _mst: Thanks so much! I got it working with you instructions, now I can compare the two jars and see where it's going wrong.

3:34 _mst: excellent :)

3:50 hoeck1: fullets: you could just read the hashmap elements into a list and see if they are even

5:26 LauJensen: Notice #45 :) http://botd.wordpress.com/2009/09/26/top-posts-1247/

5:27 crios: jwhitlark: regarding maven, check stuartsierra's blog: http://stuartsierra.com/

5:28 konr: Guys, what could be wrong with my macro? It seems that the if in the anonymous function is always returning true: http://clojure.pastebin.com/m3bfea741

5:28 *false

5:29 LauJensen: konr: No backquote

5:30 konr: Untested, by have a look at how I control the evaluation and use gensym http://clojure.pastebin.com/m75cb5358

5:42 spuz: How do I create a function that returns a sequence?

5:43 all the functions I've seen seem to rely on existing sequence funtions to do that

5:48 hoeck1: spuz: thats what lazy-seq and rest for

5:50 spuz: you may want to look at the definitions of repeat, drop-while etc. of core.clj

5:52 spuz: actually, for returns a sequence, so I don't think I need to create one myself

5:53 hoeck1: sorry, typo, I meant 'lazy-seq' and 'rest' are used to build lazy sequences

5:54 and yes, often you use only the helper functions like repeat, iterate or map to create lazy sequences

5:56 spuz: hoeck1: yeah, I understood what you meant. I'm just trying to figure out how to filter the sequence returned by 'for'. Is it possible to add a filter within the for expression, or do I need to wrap it around a call to 'filter'?

5:58 hoeck1: for has a :when clause

5:58 ,(for [x (range 1 5) :when (even? x)] x)

5:58 clojurebot: (2 4)

6:09 spuz: hoeck1: is there any benefit in using the :when clause over a filter apart from concision?

6:10 it would seem to me to be potentially less efficient as you are evaluating x twice

6:12 for example: (for [x (range 1 5) :when (> 2 (Math/sqrt x))] (Math/sqrt x))

6:12 Is the square root not be calculated twice?

6:13 hoeck1: spuz: yes, but then a surrounding filter would be better

6:13 spuz: ok

6:15 hoeck1: spuz: or just a chain of map and filter: (filter #(> 2 %) (map #(Math/sqrt x) (range 1 5)))

6:16 spuz: hoeck1: yeah map makes more sense in this case. In my case I have two variables, x and y and two ranges.

6:16 hoeck1: spuz: :when in filter is like filtering the sequence before mapping a function over it

6:16 spuz: (for [x (range n m) y (range x m)] [x y])

6:27 vy: What is the alternative to "map" ignoring the results, just doing the job with side effects.

6:30 hoeck1: vy: look at doseq

6:30 vy: or use (dorun (map ...))

6:32 vy: dotimes and while are also useful sometimes

9:04 abbe: hi everyone

9:51 rhickey: abbe: hi

9:53 lisppaste8: rhickey pasted "more functional Ikeda" at http://paste.lisp.org/display/87799

9:54 abbe: rhickey: checking out your presentation :)

9:54 rhickey: i liked when you said: love jvm, not java :)

9:55 rhickey: abbe: in which talk?

9:55 abbe: rhickey: Part 1 of a presentation by Rich Hickey at the Boston Lisp meeting.

9:56 rhickey: ah

11:03 LauJensen: rhickey: Great contribution on my blog, thank you very much for showing the way :)

11:06 rhickey: LauJensen: np

11:13 hamza: hey guys, i have the following situation, i start at x=0 y=1 suplly these coordinates to a (point x y) function i get a new point. each call takes its prev. generated point as its argument. is it possible to get a sequence of it so that i can use (take 10 (repeate call)) like structure?

11:29 LauJensen: hamza: did you read my last blog post? that gives you the solution in 4 different flavors :)

11:31 Chousuke: Chouser: I have the sq-macro at http://github.com/Chousuke/clojure/tree/sq-macro in core.clj

11:31 though I think it doesn't handle namespace alias resolution yet

11:32 LauJensen: hamza: short version, see (iterate ...)

11:33 hamza: laujensen can give url to blog post?

11:34 LauJensen: hamza: http://bestinclass.wordpress.com/2009/09/24/chaos-theory-vs-clojure/

11:34 that's the one you want

11:37 hamza: thank you,

11:38 LauJensen: np

11:38 raek: question: do vars used inside agents live inside the agents or the in executing thread?

11:42 serp_: zomg :o

11:42 raek: two serps?

11:47 anyway, serp_ and I was discussing whether one could hide java gui objects from other threads (since they're not thread safe) by keeping them in var

11:47 you have any ideas, #clojure?

13:33 drhodes: found this neat introspection function @ http://travis-whitton.blogspot.com/2009/06/method-introspection.html#comment-form

14:04 hiredman: clojurebot: ping?

14:04 clojurebot: PONG!

14:15 Chouser: drhodes: that looks about like how repl-utils/show started

14:44 drhodes: Chouser: oh, thanks for the heads up, I'll check it out.

14:46 emacsen: when should I use (in-ns) and when should I make a new namespace and import the sub-namespaces?

14:59 hamza: hey guys, i have a function that returns a file from disk, i call (memoize serve-file) in order not to hit the disk each time, serve-file is called from compojure but output is not cached. if i change the file to check i get changes reflected on the browser output?

15:05 lisppaste8: hamza pasted "memoize" at http://paste.lisp.org/display/87806

15:05 hamza: i also wrote a simple test case it always executes the function.

15:06 Chousuke: hamza: memoize doesn't change the function, it returns a new one

15:06 hamza: so you need (def mem-atest (memoize atest))

15:07 hamza: kk now i get it :P.

15:09 if i want to reset the cache, is there a better way to do it besides calling def.

15:11 again

15:11 hiredman: if you want control over the cache, I would take the source to memoize, paste it into your app, and add the ability to clear the catch

15:11 hamza: kk

15:21 wasn't there a set! function for re deffing a var or am i mistaken?

15:24 hiredman: you might have my-memoize return a proxy of AFn, and keep the cache in under the :cache key in the metadata, so you could flush the cache by mucking with the metadata

15:25 emacsen: Chousuke: any opinion on in-ns vs importing? I am just looking for general guidelines

15:26 hiredman: in-ns has nothing to do with importing

15:26 it does no importing or namespace loading

15:26 emacsen: hiredman: erm, I meant use

15:27 hiredman: right the guideline is when to make a new sub-namespace

15:28 hamza: hiredman: can you explain it a little further?

15:31 hiredman: hmmm

15:33 ,(alter-meta! (proxy [clojure.lang.AFn] []) assoc :cache {})

15:33 clojurebot: java.lang.RuntimeException: java.lang.IllegalStateException: Var null/null is unbound.

15:33 hiredman: ~def alter-meta!

15:35 hamza: ok thanks,

15:39 emma: Hi.

15:39 I am forming a study group which will meet here on Freenode to work through SICP (the canonical text on CS)

15:39 If anyone is interested our first meeting is beginning now. It's a text available online.

15:43 emacsen: SICP redone with clj or just SICP?

15:43 emma: emacsen: it's SICP.

15:44 kwertii: I thought Knuth was the canonical text ;)

15:46 metvop: #j /sicp

15:49 emma: We are having our first meeting in ##club-classroom

16:37 kmurph79: i'm going through this http://bestinclass.wordpress.com/2009/09/24/chaos-theory-vs-clojure/ can someone explain exactly what (iterate #(* 2 %) 1)) does?

16:42 arbscht: kmurph79: it returns a lazy sequence of the powers of 2

16:42 ,(take 10 (iterate #(* 2 %) 1))

16:42 clojurebot: (1 2 4 8 16 32 64 128 256 512)

16:43 kmurph79: arbscht: thanks. what does the # and % do ?

16:44 arbscht: #(* 2 %) is effectively identical to (fn [x] (* 2 x))

16:45 it's shorthand for anonymous functions

16:45 Chousuke: you can also have more parameters with %n where n can be anything from 1 to 20, or %& for the "rest" arg

16:46 just % is equal to %1

16:47 kmurph79: interesting. thank you.

16:49 arbscht: ,(take 10 (iterate (partial * 2) 1))

16:49 clojurebot: (1 2 4 8 16 32 64 128 256 512)

16:58 somnium``: how would you write a macro to create a number of seperate function calls, like (mymac fun & args) -> (fun arg0) ... (fun argn)

16:58 trying to do it recursively but not getting it

16:59 LauJensen: ~@(for [a# ~args] (~fun a#)) - something like that I believe

16:59 clojurebot: for is a loop...in Java

16:59 Chousuke: hmm

16:59 arbscht: somnium``: what are you really trying to do?

17:00 Chousuke: (doseq [a args] (f a))

17:00 :P

17:00 somnium``: in an xml builder, I have helper functions that return vectors, but splicing sequences adds complications

17:01 they work as expected as individual calls, but kind of repetitive to write (fun a) (fun b) (fun c) ...

17:05 with side effects?

17:05 hadn't considered that

17:05 Chousuke: well, hm

17:06 somnium``: its wrapped around html lib in compojure, so in something like [:tag1 [:tag2 (myhelper "foo")]] -> [:tag1 [:tag2 [:sometag "foo"]]]

17:07 Chousuke: (defmacro foo [f argv] `(do ~@(for [a argv] (list f a))) or something?

17:07 somnium``: want to be able to do [:tag1 [:tag2 (myhelpers "foo" "bar" "baz")]] -> [:tag1 [:tag2 (myhelper "foo") (myhelper "bar") etc...

17:08 will try that

17:10 Chousuke: remember though that you can only return one expression from a macro

17:10 somnium``: yeah...

17:10 Chousuke: perhaps you could do `[:tag2 ~@(myhelpers whatever)]?

17:11 somnium``: may have to wrap the whole builder in a macro

17:12 why only one expression form a macro? seems like a non-first class special form

17:13 Chousuke: you can only return one thing from ANY function :)

17:14 somnium``: maybe I should just teach the builder to auto-splice sequences...

17:14 Chouser: you're sure it doesn't do that already?

17:14 Chousuke: I mean, sure you can return multiple things wrapped in a (do ...) but then the (do ...) makes it a single expression :P

17:14 somnium``: not in my tests

17:15 Chouser: this is compojure?

17:15 somnium``: yeah

17:15 Im wrapping it with some stuff that operates on the vectors before html gets called

17:19 I was working out a way to do layouts and partials with one context, so I came up (defview [& args] [some content]) -> (fn [context] (let [arg1 (context :arg1) ... argn (context :argn)]), so now they compose with (render {:initial bindings} :views.foo :views.bar views.zonk)

17:19 but my helpers broke :(

17:20 Chouser: somnium``: use a seq instead of a vector. it works

17:20 (html-tree [:html 1 (list 2 3 4) 5]) ==> "<html>12345</html>"

17:21 somnium``: ah

17:21 clojurebot: Paul Graham is the creator of the other new lisp

17:21 somnium``: strings are ok

17:21 that may make things much easier

17:21 thanks

17:21 seqs of strings

17:21 Chouser: I think seqs of anything should work

17:22 somnium``: hmm

17:22 Chouser: user=> (html-tree [:html [:p 1] (list [:p 2] 3 4) [:p 5]])

17:22 "<html><p>1</p><p>2</p>34<p>5</p></html>"

17:23 that's the most I've ever used Compojure. :-D

17:27 somnium``: .. I found a simple solution, just have the helpers evaluate the tag and return a string .. thanks all

17:48 is there a pred like string? for functions? or an idiomatic way to test?

17:54 LauJensen: ,(string? "is there?")

17:54 clojurebot: true

17:55 LauJensen: ,(ifn? #(println "foo"))

17:55 clojurebot: true

17:55 LauJensen: ,(ifn? (println "foo"))

17:55 clojurebot: foo

18:06 LauJensen: somnium``: You got that? :)

18:07 rafsoaken: ,(ifn? ifn?)

18:07 clojurebot: true

18:17 somnium``: got it

18:17 thanks

18:18 still finding the names of some core functions to be rather obscure

18:35 Makoryu: ,(ifn? defn)

18:35 clojurebot: java.lang.Exception: Can't take value of a macro: #'clojure.core/defn

18:44 Chouser: ,(fn? fn?)

18:44 clojurebot: true

18:45 Chouser: ,(fn? fn*)

18:45 clojurebot: java.lang.Exception: Unable to resolve symbol: fn* in this context

18:50 Chouser: ,(fn? (fn* []))

18:50 clojurebot: true

18:50 Makoryu: ,(bound? 'foo)

18:50 clojurebot: java.lang.Exception: Unable to resolve symbol: bound? in this context

18:51 Makoryu: Whoops

19:04 hamza: hey guys, i have two sets such as the following #{{:tag "key" , :url "test"}} #{{:tag "key" , :url "test"}} how can i create a set that has the same item twice?

19:05 Makoryu: "how can i create a set that has the same item twice?" <- Think about this for a moment.

19:06 I don't think what you want is a set.

19:06 , #{"pizza" "pizza"}

19:06 clojurebot: #{"pizza"}

19:07 Makoryu: , ["pizza" "pizza"]

19:07 clojurebot: ["pizza" "pizza"]

19:08 hamza: well my plan was to create a set of :tag :url values then select url's based on tags..

19:10 Makoryu: , #{{:tag 'foo :url "slashdot"} {:tag 'foo :url "reddit"}}

19:10 clojurebot: #{{:tag foo, :url "slashdot"} {:tag foo, :url "reddit"}}

19:11 Makoryu: hamza: As long as the URLs are different, you're all set

19:11 hamza: I'm really curious why you're using a set if you actually want them to be identical, though

19:11 hamza: If you need duplicate elements, use another container! Like, say, a vector....

19:11 hamza: my bad, i should get some sleep. i thouth about it wrong url's are different so there should not be any problems.

19:16 question, is it possible to get a list of distinct tags?

19:18 licoresse: (reduce ...) = inject:into: in Smalltalk?

19:42 jwhitlark: I have a swing application where I want a pop up menu to update according to the value of a ref (or atom, not sure which to use). Any suggestions? Perhaps someway to setup a callback for when a value changes? Or do I need to go further and implement some sort of hooks/advice system?

19:47 hmmm. doseq with fill-queue looks like it might have potential..

19:49 Chouser: hm, that doesn't sound quite right.

19:49 licoresse: ,(doc proxy)

19:49 clojurebot: "([class-and-interfaces args & fs]); class-and-interfaces - a vector of class names args - a (possibly empty) vector of arguments to the superclass constructor. f => (name [params*] body) or (name ([params*] body) ([params+] body) ...) Expands to code which creates a instance of a proxy class that implements the named class/interface(s) by calling the supplied fns. A single class, if provided, must be first. If not provid

19:51 jwhitlark: Chouser: no?

19:51 I was looking at http://infolace.blogspot.com/2009/08/simple-webhooks-with-clojure-and-ring.html, but it was just off the top of my head.

19:58 Do I need to go read up on java events? Would that be a reasonable way to do it?

20:05 I guess what I'm really asking is if the java event model extends (is extendable?) beyond GUIs.

20:15 ambient: it's a bit troubling to me that i have to have such an intimate knowledge with java also if i want to use clojure :\

20:15 hamza: why is this not working {:t 'v {:u 'u :m 't}}

20:15 ,{:t 'v {:u 'u :m 't}}

20:15 clojurebot: java.lang.ArrayIndexOutOfBoundsException: 3

20:16 hiredman: hamza: maps need pairs of elements

20:17 you have three things there

20:17 hamza: what i am trying to do is a map of map's

20:17 hiredman: entirely possible

20:17 hamza: {:t 'v :y {:u 'u :m 't}}

20:18 licoresse: you still need a key

20:18 hiredman: that will work fine

20:18 hamza: ,{:t 'v :y {:u 'u :m 't}}

20:18 clojurebot: {:t v, :y {:u u, :m t}}

20:28 Makoryu: That should really throw a more useful error than ArrayIndexOutOfBoundsException

20:30 icey: So... for you guys on osx- how are you managing your classpath / dependencies? just putting everything in a jar folder? something else

20:30 ?

20:31 Makoryu: icey: Well, on OS X, the default classpath is something like .:/Library/Java/Extensions

20:31 I keep all my libraries in the latter location

20:31 icey: hmmm, thanks Makoryu!

20:42 lisppaste8: hiredman annotated #87611 "infinite seq of swing events" at http://paste.lisp.org/display/87611#2

21:26 licoresse: how can I pretty-print automatically the output of lists in the repl?

21:26 I am using slime

21:27 ,pretty print

21:27 clojurebot: java.lang.Exception: Unable to resolve symbol: pretty in this context

21:27 licoresse: ,prettyprint

21:27 clojurebot: java.lang.Exception: Unable to resolve symbol: prettyprint in this context

21:27 licoresse: clojurebot: pretty print

21:27 clojurebot: Huh?

21:28 licoresse: right...

21:33 Chouser: licoresse: there's a pretty printer in contrib, but I don't know how to hook it into slime

21:34 kylesmith: is there any equivalent to update-in but with functions? something like (update-with m [fn & fns] f & args)

21:36 Chouser: yes, I just can't think of the name.

21:36 licoresse: Chouser: ok

21:37 kylesmith: I could replace fns with (apply comp fns) of course.

21:37 Chouser: oh, wait.

21:38 sorry, I misread

21:38 you want to provide a list of fns?

21:39 kylesmith: yes. I'm trying to incrementally build up an arbitrarily nested structure. When I recur, I can either keep a list of fns or compose them.

21:40 Chouser: ok, you'll have to do (apply comp fns) or equiv.

21:40 kylesmith: I could probably restrict myself to nested vectors, then I could just use update-in with a list of ints, but fns would be more convenient.

21:44 I'm basically composing first's and last's, which won't have a fixed index on each iteration, hence the problem.

21:56 licoresse: pprint was the pretty printer I was looking for

22:06 kylesmith: I can't access paste. is it down?

22:29 Makoryu: kylesmith: There's always another paste.

22:29 http://gist.github.com/

22:31 kylesmith: http://gist.github.com/195087

22:36 Raynes: snipt.org is a pretty neat pastebin.

22:37 hiredman: kylesmith: saying update-with works on an associative structure seems like a misnomer

22:38 kylesmith: ahh, I didn't change the docstring

22:38 hiredman: ,(update-in [1 2 [[3 4 5]]] [2] (comp #(conj % 6) first))

22:38 clojurebot: [1 2 [3 4 5 6]]

22:38 hiredman: ,(update-in [1 2 [[3 4 5]]] [2 1] conj 6)

22:38 clojurebot: [1 2 [[3 4 5] (6)]]

22:39 hiredman: anyway

22:39 kylesmith: hmm

22:39 hiredman: it seems like you want to apply a function to the nth item in something

22:40 what happens if a collection contains multiple copies of [[3 4 5]]

22:41 kylesmith: probably bad things. I'm still thinking through this.

23:53 hamza: is there any documantation on how to use the complex numbers lib in contrib?

Logging service provided by n01se.net