#clojure log - Dec 25 2008

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

2:10 Lau_of_DK: Good morning gents

3:51 Hey heey :)

4:56 bOR_: merry christmas everyone. I've a design question:

4:58 I've a model in which human hosts are refs in a vector. One of the key/vals in these host-refs should contain information about the infections that the host carries.

4:59 each infection has some properties: a sequence, a mutation rate etc.. so I've made a struct for infections.

4:59 what is a convenient way to collect a number of infections inside the :inf value of the host?

4:59 let :inf contain a vector of refs?

5:31 hoeck: bOR_: mhh, maybe a set wrapped in a ref?

5:33 bOR_: set would be somewhat useless though. ah.

5:34 good point. I need to give an identifier to each type of virus, so that you don't get infected with 10 different clones of hiv.

5:35 I've now just made th e host a ref, and have :infections be a [], in which ts.

5:35 ts = structs

5:35 don't seem to need a ref in ref there.

5:36 although I wonder how easy it is to ' change' to swap in/out elements of the vector.

5:37 I'll try some things and see what problems I run into.

10:38 Lau_of_DK: Good afternoon gents

12:28 Chousuke: hmm

12:28 my clojurebotv2 seems to be working (at least somehow)

13:44 Lau_of_DK: Good evening gents

14:13 gnuvince: Are Java arrays arranged contiguously in memory?

14:15 Lau_of_DK: yes

14:15 gnuvince: Thank you

14:15 Lau_of_DK: nps

14:15 gnuvince: Merry Christmas (if it applies) by the way :)

14:16 Lau_of_DK: It doesnt, but I appreciate the thought

14:33 gnuvince: Im sorry about the confusion. The Java standard actually leaves it up to the host to arrange it in memory, although TYPICALLY it will be in consecutive blocks

14:35 gnuvince: ok

14:36 Lau_of_DK: http://www.brpreiss.com/books/opus5/html/page82.html

14:37 chrisn: I have a java swing threading question

14:37 Is there a thread pool set up for you?

14:38 Basically I want file loading to happen offline

14:38 in my swing app.

14:38 It doesn't seem that agents are a good fit...

14:44 Lau_of_DK: chrisn: I dont really understand your question. Regarding a pool, Java itself has some type of Queue system, dont know why agents wouldnt do that trick though

14:44 chrisn: Its ok, I don't understand it either :).

14:44 Lau_of_DK: :)

14:45 chrisn: OK, I have a graphics system. I want to load files offline and put up dummy objects, images, shaders, etc while loading the data from the fs.

14:45 1. GL calls can't happen from arbitrary threads, so the result has to be applied to gl state in the render thread

14:45 While a file is loading, more entities may request actions take with the result of the file loading process

14:46 I did this in C using a thread pool and continuations.

14:46 I am trying to figure out where agents make sense.

14:46 The thing is, the result of the load isn't a change to a datastructure.

14:46 It is just a chain of more function calls

14:47 That have to happen in the rendering thread

14:47 Lau_of_DK: You could dispatch agents to fetch the info from the files and have them feed their state back to some global ref, which you clear out like a log and then update GL with the progress?

14:47 chrisn: Yep, something like that

14:47 It seems a bit of a perversion of the agent model somehow

14:47 Lau_of_DK: I wouldnt say so

14:47 chrisn: But I don't want to create my own thread pool...

14:48 Well, here is another thing. Where in the clojure documentation does it state how many threads are in the agent thread pool?

14:48 These actions are going to be IO-blocked, not CPU blocked and thus I want more threads than processors.

14:49 probably 2x or more

14:49 Lau_of_DK: Agents can automatically find out when it doesnt make sense to launch anymore, as I understand them

14:49 Chouser: chrisn: that's exactly the purpose of 'send-off' (vs. 'send')

14:49 chrisn: How many threads are in the clojure thread pool?

14:50 Chouser: chrisn: there are two send pools for agents, one for 'send' and one for 'send-off'

14:50 chrisn: sh

14:50 ah

14:50 that helps, thanks Chouser.

14:50 Chouser: 'send' currently uses 2+cpus, I think. 'send-off's pool grows as needed.

14:51 chrisn: oh, spectacular

14:51 Chouser: (doc send-off)

14:51 chrisn: Dispatch a potentially blocking action to an agent. Returns the

14:51 agent immediately. Subsequently, in a separate thread, the state of

14:51 the agent will be set to the value of:

14:51 It doesn't state anything about grows as needed

14:51 I was looking at the docs, Chouser.

14:52 Chouser: I was referring to the "potentially blocking" phrase.

14:54 chrisn: Hell of a lot to infer from one phrase.

14:55 Chouser: well, the "grows as needed" detail is from reading the code. No offense intended.

15:00 chrisn: yeah, I decided to read the code because that detail is an odd one and I have the time... Merry Christmas! Thanks for you help.

15:00 Lau_of_DK: Hey Chris

15:00 chrisn: yo

15:00 Lau_of_DK: :)

15:00 chrisn: do I know you?

15:00 Lau_of_DK: I dont think so

15:00 chrisn: k

15:00 Chouser: I'm also Chris to some.

15:01 chrisn: oh, that will make things easier... :).

15:01 Lau_of_DK: hehe

15:02 Chris is an old Nordic name which means "Dumb as a rock"

15:03 * Chouser goes to pack.

15:03 chrisn: haha!

15:03 final public static ExecutorService pooledExecutor =

15:03 28 Executors.newFixedThreadPool(2 + Runtime.getRuntime().availableProcessors());

15:03 the pooled executor is one of those

15:03 Lau_of_DK: Chouser: come on, give me a break, that was a joke :)

16:26 I have this file, where if I load it using load-file, I get an error "Unable to resolve symbol: g in line 0

16:26 If I manually evaluate line 0, it works fine

16:27 w00t?

16:34 hoeck: Lau_of_DK: then there is somewhere a "g" on a single line somewhere in the file

16:34 line numbering somehow doesn't work in this case

16:37 Lau_of_DK: I didnt check the whole file to be honest, just the first 50 lines or so

16:37 And no G's

16:38 hoeck: i just inserted an "f" on a blank line in some clj file and tried to load-file it

16:38 and i got the same error

16:38 Lau_of_DK: k

16:38 That might have been it

16:38 I git-reverted out of it

16:43 hoeck: Almost too funny, at line 51 there was a little g hiding behind closing ))))))))

16:43 :) Is this line-counting bug reported?

16:47 hoeck: don't know, guess not

16:48 eg.: a (g) on an empty line is reported correctly

16:51 Lau_of_DK: But it says (filename:0) which leads me to believe that the error is on line 0

16:53 Chousuke: line numbering should start with 1

16:55 hoeck: Chousuke: Dijkstra would not like that :)

16:56 Lau_of_DK: I agree

16:56 Chousuke: hmm.

16:56 hoeck: but it starts at 1 in clojure zero just means no-line

16:56 Chousuke: I don't see a reason to start line-numbering from 0

16:56 Lau_of_DK: 0 isnt anything, its void

16:56 Chousuke: 0 lines means no lines.

16:56 hoeck: mee neither

16:56 me

16:57 Lau_of_DK: hoeck: do you mean: me me me ?

16:57 hoeck: funny, columns start at zero (at least in emacs) but lines at 1

16:57 Chousuke: and I finally got my restructured version of clojurebot working as well as the old one

16:57 Lau_of_DK: thats true

16:58 hoeck: but if you dont like it, you can always customize

16:59 hoeck: I just stumbled over this anomaly, and I don't really care, it doesn't make sense though

17:15 Chousuke: hm

17:17 hiredman: I got my reworked version of clojurebot working... I think

17:17 hoeck: clojurebot: botsnack

17:17 clojurebot: thanks; that was delicious. (nom nom nom)

17:17 Chousuke: I didn't test with the security manager enabled yet

17:17 hiredman: with a permissive policy file the security manager should not make a difference

17:17 Chousuke: but most of my work didn't touch the sandbox code

17:18 I pushed v2 into my master branch: http://github.com/Chousuke/clojurebot/tree/master

17:18 hiredman: hmmm

17:18 Chousuke: you can't directly merge your master with that, since they're not really related

17:24 also you can't really run two completely separate bot instances at the same time as they share the same brain.

17:26 kind of like a hivemind :P

17:27 hiredman: I dislike using binding there at the bottom for *bot* and what not, because it makes those variables unavailble at the repl

17:27 er

17:28 those vars

17:28 Chousuke: where?

17:29 hiredman: clojurebot core?

17:29 I am not looking at it right now, this is just what I remember from looking at it last night

17:29 Chousuke: ah, well

17:30 the new stuff looks *completely* different

17:30 here's how you boot it up http://github.com/Chousuke/clojurebot/tree/master/hiredman/clojurebot.clj

17:32 the run-clojurebot macro could probably do without the & body argument; that's a remnant from some earlier stuff :/

17:34 you could just (def mybot (start-clojurebot bot-attrs)) and then just call the functions with mybot as the argument.

17:34 run-clojurebot*

17:35 hiredman: nice

17:35 I have a clojurebotv2 branch, but how do I pull stuff from your v2 branch?

17:37 Chousuke: git checkout clojurebotv2; git pull chousuke master

17:40 if you try the pull in your master branch you will get errors. git reset --hard will get you back where you started :)

18:01 dthomas: When using Clojure from SLIME, is it normal to have exceptions like RuntimeException: RuntimeException: RuntimeException: TheRealException? I find I have to keep hitting "Throw cause of this exception" until I get to TheRealException (and then work my way back out to the REPL).

18:01 This is the first time I remember seeing this behavior. I wonder if it's something new that's been introduced, or if it's due to hitting an exception down within a nested lazy seq or something.

18:02 hiredman: I've seen it a few times on the vanilla repl

18:02 dthomas: OK, so not a SLIME thing. That makes me feel a little better.

18:02 hiredman: don't remember the details

19:29 ,(pow 10 14)

19:29 clojurebot: java.lang.Exception: Unable to resolve symbol: pow in this context (NO_SOURCE_FILE:0)

19:29 hiredman: ,(.pow 10 14)

19:29 clojurebot: java.lang.IllegalArgumentException: No matching method found: pow for class java.lang.Integer (NO_SOURCE_FILE:0)

19:34 nagnals: how would clojure be for scientific computing? like fft, big matrix manipulation etc?

19:34 i want osmething that is good for both rapid prototyping and execution speed :)

19:35 Chouser: nagnals: I think those are broadly the same desires as Clojure's author.

19:36 ,(.pow 10M 14)

19:36 clojurebot: 100000000000000

19:37 Chouser: ,(Math/pow 10 14)

19:37 clojurebot: 1.0E14

19:38 hiredman: heh

19:38 duh

19:39 clojurebot: hiredman?

19:39 clojurebot: hiredman is slightly retarded

19:39 chrisn: (def testvar 5)

19:40 ,(def testvar 5)

19:40 clojurebot: DENIED

19:40 chrisn: ,(println "screw off")

19:40 clojurebot: screw off

19:41 chrisn: ,(name *ns*)

19:41 clojurebot: java.lang.IncompatibleClassChangeError (NO_SOURCE_FILE:0)

19:41 hiredman: ,(identity *ns*)

19:41 clojurebot: foo

19:42 chrisn: ,::bar

19:42 ,(keyword "foo" "bar")

19:42 clojurebot: :foo/bar

19:43 chrisn: (author "clojurebot")

19:43 ,(authot "clojurebot")

19:43 clojurebot: java.lang.Exception: Unable to resolve symbol: authot in this context (NO_SOURCE_FILE:0)

19:44 chrisn: ,(author "clojurebot")

19:44 clojurebot: java.lang.Exception: Unable to resolve symbol: author in this context (NO_SOURCE_FILE:0)

19:44 chrisn: (range 100)

19:44 ,(range 100)

19: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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99)

19:44 chrisn: hmmm

19:44 that could get ugle

19:44 like my typing

19:45 ,(let [a 5] a)

19:45 clojurebot: 5

19:45 chrisn: ,(agent {})

19:45 clojurebot: clojure.lang.Agent@4be2cc

19:46 chrisn: ,(fn [] 5)

19:46 clojurebot: foo$eval__439$fn__441@1697b67

19:46 chrisn: ,(*1)

19:46 clojurebot: java.lang.IllegalStateException: Var clojure.core/*1 is unbound. (NO_SOURCE_FILE:0)

20:27 zakwilson: clojurebot: svn?

20:27 clojurebot: svn is https://clojure.svn.sourceforge.net/svnroot/clojure/

20:29 hiredman: erm

20:29 that is not right

20:29 svn is http://clojure.googlecode.com/svn/trunk/

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

20:29 clojurebot: Ok.

20:32 zakwilson: I think I told it that once.

21:14 RadioApeShot: Anyone want to rap about lazy lists with a newb?

21:14 sequences, really

21:15 Chouser: we could try

21:15 RadioApeShot: Well

21:15 Here is the thing.

21:16 I have a non-lazy function called, perhaps unclearly, square-zip

21:16 square-zip takes two sequences and returns all possible pairs of elements

21:16 Chouser: ok

21:16 RadioApeShot: I'd like to implement this so that it returns a lazy sequence of all possible pairs

21:16 But I am not sure the best way to go about doing so with clojure

21:17 Chouser: do you want to approach this as a learning experience, or should I tell you the built-in macro that'll do it for you?

21:17 RadioApeShot: Learning experience

21:18 I just opened boot.clj to look at the iterate implementation

21:18 Chouser: usually the easiest way to build a lazy seq is to use combinations of functions that already produce lazy seqs.

21:18 chief among them is 'map'

21:18 RadioApeShot: Hm

21:19 So I could use a pair of maps in this case

21:19 And I would get a lazy seq for free.

21:19 But the sequence would not be flat

21:19 I have a flatten but I am not sure if it preserves laziness

21:20 Chouser: take a look at 'mapcat'

21:20 RadioApeShot: Ok

21:20 Chouser: hm, its docs don't make claims of laziness

21:21 but looking at the source, it appears to produce a (at least mostly) lazy seq.

21:22 RadioApeShot: Laziness

21:22 I am also poking around with Haskell these days

21:22 Chouser: ah

21:22 RadioApeShot: But I don't seem to have a feel for using it idiomatically

21:22 But at least there things are (maybe?) less ambiguous.

21:23 mapcat should flatten my list for me, though, it looks like.

21:23 I guess the thing to do is implement square-zip and apply it to two lazy sequences

21:23 If it does not preserve the laziness, then it will go on forever.

21:24 Chouser: well, there are levels of laziness.

21:24 RadioApeShot: How do you mean

21:24 Chouser: I'm certain mapcat will not eagerly consume the entire sequence.

21:24 but I'm not 100% it will never take any more of the input sequence than theoretically necessary.

21:26 RadioApeShot: That should be sufficient for my purposes... I think.

21:27 Chouser: (take 1 foo), for example (if I recall correctly), used to call 'rest' on 'foo' even though it shouldn't have to do that unless you took 2 instead of 1.

21:28 RadioApeShot: The idea I have is that a lazy sequence can let you use a map to do a calculation on a list of things without iterating 2*n times.

21:28 Does that make any sense?

21:28 if you (map f (f-that-produces-lazy-seq data)) then you only pass once, rather than twice

21:29 Because the work of calculating the sequence is delayed until it is used in f

21:31 chrisn: Does that assume that f doesn't need the entire sequence?

21:32 Chouser: (map f sq) does indeed only traverse sq once

21:32 I'm quite sure what else you're saying

21:33 chrisn: No matter what, the lazy was is going to use a lot less memory and thus probably be a lot faster for large values of n

21:34 RadioApeShot: I guess reverse cannot be lazy

21:34 At least not in a sane way?

21:35 Chouser: reverse is not lazy

21:35 but it's very rarely needed in Clojure

21:35 RadioApeShot: Yes

21:35 I don't really need it here.

21:45 chrisn: What is the macro, btw?

21:46 Chouser: 'for'

22:28 chrisn: oh man for is a lot more powerful than I thought

22:30 Chouser: :-)

Logging service provided by n01se.net