#clojure log - Aug 22 2009

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

0:08 JAS415: ok

0:09 so you call java with a -cp argument

0:09 so if you are a unix like environment that means you make a shell script

0:09 ah you left the room

0:09 darn

0:17 ,(dorun 3 (range 0 100))

0:17 clojurebot: nil

0:18 maxthimus: suppose i have a list '('(1 2) '(3 4))

0:18 JAS415: (dorun 3 (map println (range 0 100)))

0:18 maxthimus: how will i invoke (map + list) so that i get (4 6)

0:18 JAS415: err

0:19 maxthimus: basically i want the list to be expanded as list of arguments. i know apply can be used.

0:19 but couldn't figure out how.

0:19 JAS415: ,(let [x '('(1 2) '(3 4))] (map #(+ %1 %2) (first x ) (second x)))

0:19 clojurebot: java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to java.lang.Number

0:20 maxthimus: yup. but i want it for a variable length list

0:20 Knekk: try apply

0:20 JAS415: ,(let [x (list '(1 2) '(3 4))] (map #(apply + %&) (first x ) (second x)))

0:20 Knekk: ,(doc apply)

0:20 clojurebot: (4 6)

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

0:21 JAS415: liek that

0:21 and you can apply the map too

0:22 ,(dorun 3 (map println (range 0 100)))

0:22 clojurebot: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

0:22 JAS415: hmm

0:22 is dorun broken?

0:22 ,(dorun 8 (map println (range 0 100)))

0:22 clojurebot: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

0:23 JAS415: i would expect it to give me 3 or 8 and then quit

0:23 Knekk: ,(doc dorun)

0:23 clojurebot: "([coll] [n coll]); When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. dorun can be used to force any effects. Walks through the successive nexts of the seq, does not retain the head and returns nil."

0:24 maxthimus: i know i'm missing something simple. i couldn't extend this to work for var length list.

0:24 JAS415: oh

0:27 maxthimus: thanks guys. got it.

0:28 silly me. should have apply-ed +.

0:28 JAS415: yup

0:28 apply +

0:28 you can apply the map too I think

0:28 i had a version like that somewhere

0:29 maxthimus: yup. thanks @JAS415.

0:36 JAS415: so is there any way to selectively consume a lazy sequence

0:37 lets say i want to consume the first 4 and then leave the rest of the seq lazy?

0:40 tomoj: ,(take 4 (iterate inc 1))

0:40 clojurebot: (1 2 3 4)

0:41 tomoj: "selectively consume" sounds like exactly what "laziness" means, to me

0:42 _mst: and to grab a hold of the rest: (let [[first-four lazy-bit] (split-at 4 (iterate inc 1))] ...)

0:42 JAS415: okay

0:43 that is fine

0:43 but lets say i do ,(dorun (take 4 (iterate inc 1)))

0:43 ,(dorun (take 4 (iterate inc 1)))

0:43 clojurebot: nil

0:43 JAS415: or actually

0:43 tomoj: (reduce + ...) appears to be consistently faster than

0:43 JAS415: i have the example above

0:43 tomoj: ...(apply + ...)

0:44 JAS415: ,(dorun 3 (take 3 (map println (range 0 100))))

0:44 clojurebot: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

0:45 JAS415: see that is what I don't understand

0:47 _mst: yeah, I can't explain that either. That's not what it prints in my repl

0:47 tomoj: perhaps it's chunked?

0:47 32 can't be coincidental..

0:47 I get 32 as well here

0:47 JAS415: i get the feeling it is something weird about the latest version

0:47 _mst: ah, I'm still on 1.0 so that might be it, yeah

0:47 tomoj: I think that's a bad way of printing stuff from a seq anyway

0:48 JAS415: yeah that's just an example

0:48 i was actually doing something with a GUI and generating frames

0:48 tomoj: (doseq [x (take 3 (range 0 100))] (println x))

0:48 ,(doseq [x (take 3 (range 0 100))] (println x))

0:48 clojurebot: 0 1 2

0:48 JAS415: ah

0:48 i'll try that version

0:48 tomoj: you don't want to map a side-effect function over the seq

0:52 JAS415: why is that?

0:52 does it always evaluate side effect functions?

0:54 tomoj: no, it doesn't know the difference

0:55 but (as you've seen) it might apply the function more than necessary

0:56 it appears to go in increments of 32

0:56 JAS415: that's unfortunate

0:56 tomoj: you can get your original example to work if you change the order

0:57 ,(dorun (map println (take 3 (range 0 100))))

0:57 clojurebot: 0 1 2

0:57 JAS415: hmm

0:57 tomoj: but I think doseq is better

0:57 JAS415: unfortunately the situation isn't analogous to either of those

0:58 this all has to do with the chunking stuff?

0:58 tomoj: I'm guessing

0:58 check this out

0:59 JAS415: too bad as i was going to have a 'more' button that just evaluates more of the sequence to add frames to the window

0:59 would have made it fairly simple :-/

0:59 tomoj: you can still do that

0:59 I don't see how it's any less simple when you're not using (map println ...)

1:00 JAS415: ah i see what you are saying

1:00 tomoj: hrmm

1:00 JAS415: yeah maybe that would work

1:01 tomoj: ,(dorun (take 3 (map println (iterate inc 0))))

1:01 clojurebot: 0 1 2

1:01 tomoj: strange

1:01 JAS415: i'll just pass the function and the list of frames then apply

1:01 huh

1:01 tomoj: you can still use lazy seqs

1:01 JAS415: 0 1 2?

1:02 tomoj: e.g. with split-at like _mst showed

1:02 draw the first however many and hold onto the rest with split-at, then when you want more repeat

1:03 I have this feeling that it's just a bad idea to have a lazy-seq consumption of which causes side-effects, not sure if that's really true

1:05 JAS415: yeah i mean

1:05 generally it is because you can kill yourself with memory overhead

1:06 but i would guess it would be okay if the whole point is to cause the side effect

1:06 but i can change my thinking about it and get an answer that is what I want without doing the lazy sequence stuff I think

1:06 just have to pass the function as well as the seq of information

1:23 tomoj: it's obviously not ok if the whole point is to cause the side effect

1:23 as in your previous example which printed out way too much

1:23 doseq is better

1:25 clojure: given (def d {:employees '(david richard)}), is this idomatic to add another employee: (assoc d :employees (conj (d :employees) 'william))

1:26 kotarak: clojure: (update-in d [:employees] conj 'william)

1:27 And while we are about idiomatic: (def d {:employes [:david :richard])

1:28 clojure: ah, thank you. so prefer vectors of things instead of lists if they change?

1:29 kotarak: clojure: prefer vectors instead of quoted lists and keywords instead of quoted symbols

1:29 clojure: whether to use vectors or lists for changing things depends on the desired characteristics

1:30 clojure: aesthetically, i like quoted lists and symbols

1:33 that worked nicely; whenever i see ugly clojure code, i know i've much to improve

1:35 kotarak: clojure: my code starts looking ugly like hell, after three refactorings and two re-writes it then suddenly shrinks in size by 80%, becomes more functional and easier extendable. This happens quite often for me. I came to the conclusion: "If your code looks ugly, it is wrong."

1:35 YMMV of course.

1:37 clojure: just started coding clojure today, but same observation. and, i have to rid myself of perl, python, and java habits

1:38 kotarak: clojure: ah, that's easier than you think. And then there are cool Java libraries also. I have good experiences with eg. mxGraph. It allows a very functional, cojurey (ie. immutable) style. Very nice actually.

1:49 clojure: all clojure noobs should take notes, collectively edit a "clojure do and don't" wiki

1:50 tomoj: I'd hope the non-noobs would chime in once in a while too :)

1:50 in case a noobs "do" is really a "don't"

1:52 clojure: bet combing through the #clojure irc logs will be great starter material

1:53 hiredman: ~logs

1:53 clojurebot: logs is http://clojure-log.n01se.net/

1:53 hiredman: ~delicous

1:53 clojurebot: Excuse me?

1:54 hiredman: bah

1:54 ~delicious

1:54 clojurebot: delicious is http://delicious.com/clojurebot

1:54 hiredman: ~brain

1:54 clojurebot: brain dump is http://clj.thelastcitadel.com/clojurebot

1:55 tomoj: it posts every link it hears to delicious?

1:55 hiredman: yep

1:55 kotarak: Well. I was told, that noobs don't read wikis anyway...

1:56 tomoj: jees

1:56 hiredman: pastebin links tagged with pastbin, all links tagged with the nick that pasted it

1:56 tomoj: it has 18 bookmarks tagged as me

2:01 does clojurebot have a gender?

2:11 JAS415: ~gender

2:11 clojurebot: Huh?

2:11 JAS415: ~sex?

2:11 clojurebot: I don't understand.

2:19 bitbckt: clojurebot: gender is irrelevant

2:19 clojurebot: You don't have to tell me twice.

2:23 JAS415: ~gender

2:23 clojurebot: gender is irrelevant

2:23 JAS415: clojurebot: sex? is yes please!

2:24 clojurebot: In Ordnung

2:24 JAS415: ~sex?

2:24 clojurebot: sex? is yes please!

2:24 JAS415: ~gender

2:24 clojurebot: gender is irrelevant

4:16 lowlycoder: how do you deal without continutaions? or is this the wrong channel, since those that really love continuations aren't here

4:16 tomoj: I've never used a language with real continuations :(

4:18 lowlycoder: scheme

4:20 tomoj: do you have some example code where you want to use continuations?

4:43 Chousuke: I suppose continuations are a feature you don't miss until you've used them.

4:58 tomoj: yeah

4:58 I'm a blub programmer

4:59 Chousuke: Well, I did read about continuations when I looked a scheme, but I never quite figured them out.

4:59 at*

5:00 tomoj: I remember seeing a port of cl-cont to clojure

5:00 for faking continuations

8:08 Chouser: I think concat needs to chunk for a chunked 'for' to do any good.

8:13 Chousuke: hmm.

8:13 rhickey: Chouser: quite likely

8:14 Chousuke: what would chunk do if you concat a chunked seq with a non-chunked one?

8:14 er.

8:14 s/chunk/concat/

8:15 rhickey: Chousuke: the chunk-rest of a chunked seq need not itself be chunked

8:15 chunked-ness is tested at each step

8:16 Chousuke: okay.

8:19 rhickey: Chouser: you had asked about #() in into, it's there in order to prevent holding onto from during the loop, but won't quite work because it closes over from. This was a quickie attempt because the original, not having a branch, recurred to itself and thus was fine

8:20 needs to be ((fn [ret items] ...

8:20 interestingly I couldn't get any version to hang onto from when testing this

8:21 so sometimes I guess hotspots liveness analysis obviates the need for clear-on-tail-call

8:22 I wish I could rely on that, and it would be nice if it worked for non-tail calls - i.e. on stack, not used after this call is a dead reference during the call

8:24 Chouser: rhickey: avoiding holding something was my first thought but yead it didn't seem like it would work.

8:24 I'd missed this somehow: http://www.brool.com/index.php/pattern-matching-in-clojure

8:36 concat is defined before chunk and the math stuff.

8:57 grosours: plop

9:09 lisppaste8: raphinou_ pasted "adding jwt listener" at http://paste.lisp.org/display/85858

9:10 raphinou: I have a problem with the second listener I want to define in my jwt exploration (see paste)

9:10 I have the same problem as yesterday for the first listener, when I proxied Signal1 rather than Signal1$Listener

9:11 but here I don't make the same mistake (I think!), though I get the same error

9:11 if anyone has a suggestion, I'm a taker :-)

9:12 kotarak: I had once trouble with inner classes and had to fully qualify the classname. (But just guessing...)

9:12 cark: like yesterday it looks ok at first glance =/

9:14 raphinou: kotarak: yesterday we confirmed you have to import innerclasses with a Signal$Listener syntax

9:15 kotarak: raphinou: I can't remember what I did, the only thing worked for me was (proxy [foo.bar.baz.Frobnicator$FlogistonReactor] ...). Everything with import failed. But I can't remember exactly. (As I said: just guessing)

9:17 cark: enterListener takes a JSlot

9:17 i mean enterpressed.addListener

9:20 this framework is quite strange

9:21 raphinou: cark, I think I try to use this method: http://www.webtoolkit.eu/jwt/latest/doc/javadoc/eu/webtoolkit/jwt/EventSignal.html#addListener(eu.webtoolkit.jwt.WObject,%20eu.webtoolkit.jwt.AbstractEventSignal.LearningListener)

9:22 cark: why do you feel it's strange?

9:23 cark: ah sorry, i'm not used to the .. notation

9:23 you are correct

9:23 raphinou: yes, I had tried with -> but got an error and then copied the working listener :-)

9:27 cark: but this abstracteventsignal.learninglistener thing ... iit doesn't look like it's implementing Signal.Listener

9:28 kotarak: raphinou: you have to .method notation for ->, instead of (.. a foo bar) do (-> a .foo .bar)

9:29 -> is more general. it also allows clojure functions and macros

9:29 cark: if you want a trigger method, you might need to proxy AbstractEventSignal.JavaScriptListener

9:30 ah but there is an add-listener with the proper parameters too =/

9:31 raphinou: cark, I really don't see the error here either

9:31 kotarak, thx for the tip

9:34 cark: you have this error at run time ?

9:34 raphinou: yes

9:34 cark: what's the value of wapp ?

9:34 its class mean

9:35 +I

9:35 raphinou: WApplication

9:36 cark: well i'm at a loss =P

9:36 i give up !

9:36 raphinou: cark: you're right :-)

9:36 thx for the help. I'll contact the jwt author

9:37 I'll post something about the solution

9:37 cark: i wonder why you're not using one of our nice web frameworks

9:38 this thing looks like it is intended to shield you from the web

9:38 raphinou: well, I'm also using compojure

9:39 and I'm curious about jwt to see how it can help me develop some web apps

9:39 cark: i've been doing a few gigs with web applications, and in the end i prefer being in control

9:41 raphinou: cark: I could very well come to the same conclusion, but I have an app where this widget approach could be very helpful.

9:41 cark: did you have a look to extjs ?

9:41 raphinou: yes, the app I'm talking about is done with extjs :-)

9:42 cark: it also shield you from the web stuff, but i like the client-side only approach

9:42 though i didn't do anything worthy of mentioning yet with it =)

9:43 raphinou: well, extjs is fine, but you also have to code the server side, and you have 2 different code bases in 2 languages

9:43 I want to see how/if jwt can help me

9:43 cark: a typical web application has you coding in 4 languages, so i can live with 2 =)

9:44 it would be nice to have a clojure to javascript compiler tho !

9:44 raphinou: yes, but if you follow that logic you can code in cobol too :-D

9:44 yes, that could be very nice

9:45 cark: well you have means of abstraction on the client side and on the server side too

9:45 raphinou: take a look at this: http://wiki.github.com/rdale/wtruby/tutorial

9:45 I found it interesting to read

9:46 not that I want to convince you, but I want to see how this can be used in real world apps (likethe one I wrote with extjs)

9:49 cark: i can see how this is tempting

9:50 raphinou: I need to go now.... Bye!

9:50 cark: byebye

12:08 alrex021: can someone explain to me what the benefits of destructuring? I've seen a few examples in Rich's but can't see practical use of it.

12:08 worth noting I'm new to FP style programming

12:10 **typos: .... can someone explain to me what the benefits of destructuring are? I've seen a few examples in Rich's screencasts but can't see practical use of it.

12:11 Chousuke: alrex021: you can do things like (let [[x y z] coordinate] ...) instead of (let [x (coordinate 0) y (coordinate 1) z (coordinate 2)] ...)

12:12 or if you want to separate the head of a sequence from its tail: (let [[head & tail] aseq] ...)

12:12 alrex021: ohh so give it a vector of bindings and bind to seq which in this case is coordinates?

12:13 Chousuke: map destructuring is less common but still nice.

12:14 it's mostly a convenience thing. saves a lot of manual undoing of data structures.

12:15 alrex021: ok thanks Chousuke, now I understand it better

12:16 Chousuke: for example, if you have a map and you want to extract values from it, you'd just do (let [{:keys [the keys here]} {:the 3 :keys 5 :here 'bar}] ...) and within the let you'd have variables called the, keys and here corresponding to the values from the map.

12:17 ,(let [{a :foo b :bar} {:foo 5 :extra 6}] [a b])

12:17 clojurebot: [5 nil]

12:18 alrex021: oh cool, thats pretty neat

12:18 Chousuke: :keys is a shortcut for the case when you have {key :key otherkey :otherkey morekeys :morekeys}

12:19 actuall I think map destructuring works with anything associative.

12:19 let's see...

12:19 alrex021: can destructuring be applied using binding macro function like using let?

12:20 Chousuke: pretty much anything that uses bindings uses let so destructuring is everywhere.

12:20 and in function arglists

12:20 ,(let [{a 3 b 0 c 5} [1 2 3 4 5 6]] [a b c])

12:20 clojurebot: [4 1 6]

12:22 Chousuke: ,(let [swap (fn [[a b]] [b a])] (swap [1 2]))

12:22 clojurebot: [2 1]

12:23 alrex021: sweet

12:26 now destructuring makes a lot more sense and I see its convenience and power

12:26 now just to use it in some real code :)

12:27 Chouser: also you can provide defaults for map destructuring using :or

12:27 and you can nest structures

12:28 alrex021: yup, I've seen the nested struct examples

12:28 however never new about :or

14:19 cupertinochad: I have a quick newbie question

14:19 JAS415: ok

14:19 cupertinochad: I am reading the book Programming Clojure and I pasted in the following example:

14:19 user> (def foo 10)

14:19 #'user/foo

14:19 user> (.start (Thread. (fn [] (println foo))))

14:19 nil

14:19 user>

14:20 The book says it should print out 10 after the nil, but my REPL doesn't print the 10, just the nil.

14:21 JAS415: hm

14:21 woodz: cupertinochad: are you running it from a terminal or within Emacs/SLIME?

14:22 cupertinochad: I am running in Emacs/SLIME

14:22 woodz: Check the *inferior-lisp* buffer.

14:22 cupertinochad: And there it is!!!

14:22 woodz: :-)

14:22 cupertinochad: Thank you. I will keep that bufffer visible, too.

14:23 woodz: That's where all your printlns from the REPL go.

14:23 rottcodd: or add this to your .emacs (add-hook 'slime-connected-hook 'slime-redirect-inferior-output)

14:24 woodz: Awesome. Didn't know that particular tip, rottcodd

14:24 cupertinochad: Cool. I will add the hook. It will be easier for me to track things

14:26 I installed the hook; works great. Thanks rottcodd!

14:27 woodz: Likewise :-)

14:54 hamza: hey guys, today i recompiled clojure, i started getting java.io.NotSerializableException: clojure.lang.PersistentVector$Node when i try to write a vector to file?

15:11 hey guys, today i recompiled clojure, i started getting

15:11 java.io.NotSerializableException: clojure.lang.PersistentVector$Node

15:11 when i try to write a vector to file?

15:12 Chouser: I've not tried to use binary serialization at all

15:13 I know a couple others have. Do you have a little snippet that would reproduce the problem?

15:13 Licenser_: hello everyone

15:15 hamza: function uses alot of extra jars for encryption but it used to work 5 mins ago until i rebuild my clojure and clojure-contrib jar.

15:16 if i switch to old jars i get no errors.

15:16 i was wondering if anything got changed?

15:16 rhickey: hamza: there is a new implementation of vector and the nodes might not be serializable

15:19 hamza: is there a work around for this? or should i create java vector before writing it?

15:20 rhickey: hamza: is there a reason you are using the latest?

15:20 Licenser_: latest is always shiny!

15:21 rhickey: serializability is not yet a 'feature', certainly there needs to be an audit and a set of tests written, then patches to make sure all the collections work

15:21 hamza: no particular reason, i just updated it because it has been a while since i build the jars should i switch back?

15:22 rhickey: https://www.assembla.com/spaces/clojure/tickets/64

15:23 hamza: yes, you should switch back, then maybe make some small test cases so anyone trying to patch this for you has something to target

15:31 hamza: just curious, clojure vectors are java vectors right? what makes them not serializable?

15:31 wtetzner_: i don't think they're java vectors

15:32 kotarak: hamza: I don't think so. They just implement the vector interface.

15:32 cark: they are not java array

15:32 wtetzner_: they have all of the fancy immutable persistence stuff

15:32 rhickey: hamza: no they're not java.util.Vectors. The is no vector interface either

15:36 kotarak: Oh. I thought there was an interface. Isn't java.util.Map an interface?

15:36 rhickey: the vector nodes just started using j.u.c.AtomicReference, but that's Serializable

15:37 kotarak: the relevant interface is j.u.List

15:37 kotarak: ah. Ok.

15:37 rhickey: ,(instance? java.util.List [1 2 3])

15:37 clojurebot: true

15:38 rhickey: j.u.Vector is a concrete class

15:38 ,(instance? java.util.RandomAccess [1 2 3])

15:38 clojurebot: true

15:39 kotarak: Indeed, and j.u.Vector implements j.u.List.

15:39 cemerick: we've been binary-serializing clojure vectors for some time

15:39 we're still on v1.0, so maybe something's changed, though

15:40 kotarak: I have a hacky xml-o-matic translating everything to xml for use in one the required Java libs. Works quite well so far.

15:41 cemerick: kotarak: xstream is the best in that department, last I knew

15:41 we use it heavily in our ground-truthing test process

15:42 or, in our "legacy" process, I should say

15:43 kotarak: cemerick: xstream looked promising but it has a serious flaw: I cannot name the containing xml element. So I can't say <vector> because xstream already does a <c.l.LazilyPersistentVector> or so.. But maybe I should just go with whatever xstream.

15:43 * rhickey needs small test case please

15:43 kotarak: cemerick: Now I use very hacky org.w3c.Element translation, but mxGraph leaves that alone and provides persistence for free. Works quite well.

15:43 rhickey: I think the only problem is that pv.Node has no default ctor

15:47 cemerick: rhickey: Java Serialization doesn't depend upon having a default ctor.

15:48 if a class has a non-Serializable superclass without a default ctor, that's is a problem

15:48 but I think that's the only ctor-related restriction on Serialization

15:48 The bean pattern, on the other hand, does require default ctors everywhere, which can get *very* annoying.

16:16 hamza: is it possible to use the java task in ant to run a clojure file? i am trying to set up a build file to allow non programmers to get my compujure app running without messing with class paths. Like clojure.lang.Compile but to run instead?

16:17 cark: make an executable jar so your user only needs to click it

16:19 hamza: i'll pass it to the guy who edits the html&css stuff i would like to create a easy way to get him up and running so he does not have to maintain jars and classpath's..

16:20 cark: and make him install ant ?

16:21 cemerick: hamza: an executable jar is the simplest way for end-users. Short of that, clojure.main can be used as the main class in a java ant task.

16:22 Licenser_: Hmm I've a very general and likely stupid question. From what I got by now storing states is evil in Clojure (or any other Lisp derivate) So what is the 'good' way of handling like a board of chess figures? updating the board with a function call and chain them for every move?

16:23 hamza: cark: he is using osx ant is installed by default cemerick: it is not for end user's it is for the html guy to edit stuff if i use clojure.main how can i tell it to load .clj file?

16:23 Chousuke: Licenser_: You can use refs for state

16:24 Licenser_: *nods* I know it's more a style question. I am not that versed in functional programming yet and I'd not want to get into the habit writing my usual iterative (or object oriented) code just with a different syntax, I think that is bad karma

16:25 So I wonder how that would be handled in a functional manner

16:25 Chousuke: Licenser_: represent the board as an immutable data structure however you want, and every transition as a function. then, you can just put the initial position in a ref, write code to ask for the next move and update the ref accordingly, and repeat

16:26 Licenser_: okay so for things like that it wouldn't be frowed upon to use a changing reference to things, good to know :) thanks Chousuke

16:27 Chousuke: that way all your actual logic is going to be purely functional (just a transformation taking the current board and the move as a parameter and producing a new board)

16:27 Licenser_: real programs need state. it's just a question of how it's handled.

16:28 Licenser_: That is the feeling I got from reading more about clojure and functional programming, that I can do a lot niftly things with it but if things go over hello world or some pure data processing state is required

16:28 Chousuke: the ref is an "identity". it's the game board. the value of the game board can vary with time, but the values themselves never mutate.

16:29 Licenser_: I just change what 'board' the ref points to right=

16:29 Chousuke: yeah

16:29 Licenser_: ^^

16:29 Chousuke: if you read the state of the game board at one point that value is not going to change suddenly.

16:29 unlike in languages where you'd have a mutable "Board" that could suddenly get changed.

16:30 Licenser_: Ah I see that is where the whole stuff remains sane for matters of paralelism

16:30 yes in every iterative language I had written some kind of variable that gets changed for every move

16:31 this starts to make more and more sense ^^ :D

16:31 Chousuke: yeah. in clojure you'll have a single "variable" that points to whatever value of the board is current

16:32 Licenser_: So it's like updating a pointer instead of changing the data behind it

16:32 Chousuke: yeah.

16:32 with well-defined concurrency semantics :)

16:33 Licenser_: Does clojure have a GC that handles the unrefferenced data properly, because I kind of remember that Java's GC was kind of a myst sometimes

16:33 then again perhaps they have cleaned that up as well as the + opperator since I lased was tortured with it

16:33 duck1123: clojure uses java's gc

16:34 and it's pretty good now a days

16:34 Licenser_: Chousuke: the concurrency is what got me interested in clojure in the first place. I mostly write ruby and that is really horrible when it comes to doing two things at once.

16:34 Chousuke: the important point is that your code won't mess with this variable directly. instead you'll be writing pure functions of value to another value and then tell the "variable" to apply a function to its current value and change itself to point to the new value returned

16:34 Licenser_: *nods*

16:35 Chousuke: the nice thing is that until you can pretty much not worry about the ref until you're done writing the purely functional logic.

16:37 Licenser_: sounds good

16:37 well clojure has one thing that is worth gold, a helpful community =)

16:42 But I see what peopel like about Lisp, the structure of the code is surprisingly clear.

16:51 Chousuke: Licenser_: lisp code is very dense.

16:51 there's so little syntax.

16:51 Licenser_: clear in the sense of what actually happens

16:52 Chousuke: well, I guess.

16:52 * Licenser_ is writing a VM and compilers in a project of his and he can see that lisp is quite close to what happens behind the cortains there

16:53 Chousuke: . is one of Clojure's operators that always forces me to stop when reading code though :/

16:54 Licenser_: because people ask silly questions like mine and you feel obligated to answer?

16:54 Chousuke: nah.

16:54 I don't like . because it steals the list head position from the actual operation

16:55 Licenser_: Ohhh okay, I thought . is a odd for for saying me :P

16:55 Chousuke: and it's even worse if you have (. (. (. ...)))

16:55 :P

16:55 Licenser_: And I thought you're a channel opperator which foces you to stop reading code o.o

16:55 narf okay my brain is fried I think

16:56 Chousuke: I always try to get people to use .foo and Foo/bar syntax instead of . directly.

16:56 because I hate reading code that uses it :)

16:56 Licenser_: That only applies wen working with Java classes right?

16:56 Chousuke: well, . is the java interop operator, so yeah.

16:56 but I'm not discouraging the use of java interop. it's okay. just don't use . :P

16:57 technomancy: Chousuke: glad I'm not the only one who thinks that

16:57 Licenser_: ^^

16:57 but I see what you mean, it makes the code less clean, even if . happens you acutally want the function behind it

16:59 Chousuke: . may have a place in macros though. but that's acceptable.

16:59 macros should be read carefully anyway :P

17:00 Licenser_: ^^

17:20 lowlycoder: are there any java gui kits not based on top of AWT?

17:23 rsynnott: is SWT?

17:23 sorry, I mean is Swing?

17:23 pretty sure SWT isn't

18:08 lowlycoder: I wnt to know what namespace/package SWT.NONE belongs in; is there an easy way to 'grep' through jar files?

18:10 drewr: perhaps, jar tvf foo.jar | fgrep 'SWT$NONE'

18:10 not an inner class though is it

18:11 could start looking for SWT alone

18:14 lowlycoder: crap, how do I convert these two lines into clojure?

18:14 GLData data = new GLData (); data.doubleBuffer = true;

18:14 doubleBuffer is just a java var, NOT a ref

18:14 clojurebot:

18:17 drewr: (def data (doto (GLData.) doubleBuffer))

18:17 er, sorry

18:17 lowlycoder: yeah, that seems to read from it

18:18 rather than write to it

18:18 technomancy: lowlycoder: just extract the jar file into a directory, then rgrep it

18:19 drewr: would this work? (def data (GLData.)) (set! (. data doubleBuffer) true)

18:23 lowlycoder: drewr: that worked; thanks

18:24 pschorf: does anyone know of a non-messy way to xor chars? bit-xor throws a cast exception

18:32 drewr: pschorf: what does your call to it look like?

18:32 ,(bit-xor 1 1)

18:32 clojurebot: 0

18:32 drewr: ,(bit-xor 0 1)

18:32 clojurebot: 1

18:33 pschorf: ,(bit-xor \a \b)

18:33 clojurebot: java.lang.ClassCastException: java.lang.Character cannot be cast to java.lang.Number

18:33 drewr: ,(bit-xor (int \a) (int \b))

18:33 clojurebot: 3

18:33 drewr: ,(int \a)

18:33 clojurebot: 97

18:33 pschorf: drewr, thanks

18:34 didn't realize you could explicitly coerce

18:42 lowlycoder: hmm, I actually can't figure out how to conver tthis to clojure:

18:42 while (!shell.isDisposed()) { if (!display.readAndDispatch())

18:42 display.sleep();

18:43 }

18:43 the best idea I have in mind involves using recur

18:44 Chousuke: clojure has a while loop

18:44 (doc while)

18:44 clojurebot: "([test & body]); Repeatedly executes body while test expression is true. Presumes some side-effect will cause test to become false/nil. Returns nil"

18:45 Chousuke: (while (not (.isDisposed shell)) (when-not (.readAndDispatch display) (.sleep display)))

18:46 Licenser_: Again the ugly question, is that functional programming wise Ok?

18:47 Chousuke: well, it relies on side-effects so it's not functional, but it's not like you need to avoid non-functional programming all the time.

18:47 usually, sticking to functional idioms just makes things easier for you.

18:47 and with java interop, you often can't avoid side-effects

18:48 Licenser_: *nods* True

18:48 lowlycoder: Chousuke: worked; thanks!

18:53 Licenser_: well night everyone!

22:54 lowlycoder: how do I convert the following to clojure? I get lost after: "(Listener. ..... " given java code of: Listener listener = new Listener() { public void handleEvent(Event event) {

22:57 Chouser: that's a anonymous inner class (or whatever it's called). Currently Clojure's most similar construct is 'proxy'

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

22:58 Chouser: (let [listener (proxy [Listener] [] (handleEvent [event] ... ))] ...)

22:58 in a future version 'new' will do this for you.

23:02 lowlycoder: cool; thanks :-)

23:07 Chouser: you can try it now in the 'new' branch

23:22 the amount of work done for each clause of a 'for' form is quite stunning, both at compile time by the macro, and then at runtime by the generated code...

23:23 ,(macroexpand-1 '(for [a [1 2] b [3 4] c [5 6]] (+ a b c)))

23:23 clojurebot: (clojure.core/let [iter__5244__auto__ (clojure.core/fn iter__2550 [s__2551] (clojure.core/lazy-seq (clojure.core/loop [s__2551 s__2551] (clojure.core/when-first [a s__2551] (clojure.core/let [iterys__5242__auto__ (clojure.core/fn iter__2552 [s__2553] (clojure.core/lazy-seq (clojure.core/loop [s__2553 s__2553] (clojure.core/when-first [b s__2553] (clojure.core/let [iterys__5242__auto__ (clojure.core/fn iter__2554 [s__2555]

23:24 tomoj: how do you generally make custom swing components (e.g. that draw graphs or whatever)?

23:24 seems the standard way of doing this in java is by subclassing and overriding paint

23:24 so, gen-class?

23:24 Chouser: nah

23:25 not unless you need it to look like "normal" widget class to Java code that uses it

23:25 tomoj: I don't care about java code using it.. what's the alternative?

23:25 Chouser: the normal proxy pattern

23:26 a clojure fn that uses proxy to create an object

23:26 tomoj: hmm

23:27 proxy methods can't call super, though, right?

23:28 Chouser: actually, you might not even need proxy...

23:28 I wrote this a while ago: http://gist.github.com/40012

23:28 trying to figure out how it works

23:29 ah, that doesn't hook the paint method -- it just draws onto a Frame when it feels like it. maybe not a good example.

23:30 tomoj: I tried that at first

23:30 but on resize everything gets cleared

23:30 Chouser: yeah, you want a paint method. I thought I did that too, just have to find it...

23:31 oh, the ants example does this

23:32 tomoj: ah, great

23:32 I'll take a look at it

23:32 thanks

23:32 Chouser: you don't need to call the superclass' paint method.

23:32 tomoj: oh, that looks a lot simpler than I expected

23:33 Chouser: "Subclasses of Component that override this method need not call super.paint(g)."

23:33 straight from the Java doc

23:33 tomoj: :)

23:33 been a long time since I did anything with java

23:34 Chouser: :-) np.

23:39 elben: I'm trying to get vimclojure to work, but my syntax isn't looking right: http://yfrog.com/0ggvimp

23:39 For ex, the keyword "def" isn't highlighted. But it seems that it's using my /.vim/syntax/clojure.vim file. any ideas?

23:40 lowlycoder: i want to have a varaible whose value lasts between a "(use :reload-all 'module-name)" session ... how do I do that?

23:41 Chouser: lowlycoder: maybe defonce

23:43 lowlycoder: that looks useful thanks

23:48 I don't get the point of 'transient' ... so it's a hint to the gc to say "this piece of data can be thrown away soon?" ?

23:48 Chouser: The Java keyword, or the Clojure term?

23:49 they mean rather different things.

23:49 lowlycoder: http://clojure.org/transients

23:50 Not persistent, so you can't hang onto interim values or alias

23:50 so I can't capture intermediate calculations?

23:50 this is weird

23:50 Chouser: right, it's just a performance feature of Clojures persistent vectors and maps

23:50 lowlycoder: hmm, my clojure doesn't even support it

23:51 Chouser: yeah, it's pretty new

23:52 if you're building a large vector inside a function which you will then return, it would be perfectly safe to build it using a mutable collection and then convert it to persistent before returning it.

23:52 lowlycoder: why would i want to use transients instead of a vector of refs ?

23:53 Chouser: a mutable collection would be faster for that kind of building up, but then converting it to persistent would generally be too expensive to be worth while

23:53 lowlycoder: converting is something like (map #(deref %) ...)

23:54 i guess what I really should do, instead of debating

23:54 is checkout latest clojure and time it :-D

23:54 Chouser: Clojure triansients give you most of the speed benefit of a mutable collection, but then the 'persistent' call is O(1)

23:54 lowlycoder: ah

Logging service provided by n01se.net