#clojure log - Jun 05 2008

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

0:00 Chouser: btw, I don't think I'd like suffix chars for primitive literal numbers.

0:01 JamesIry: Chouser: They borrowed some syntactical structures from Java where they didn't have a strong reason to do otherwise

0:01 rhickey: Still no substitute for a truly immutable data structure, just has much better memory and concurrency characteristics in the end

0:02 Chouser: meaning you're opposed, or just wouldn't use them?

0:03 Chouser: rhickey: well, that's a good question. I guess my current opinion is that I'd rather not read them. :-)

0:04 rhickey: I ripped out all of my effectively-but-not-really-immutable data structures once I got the hash tries working. They're plenty fast.

0:04 Chouser: hm, I dunno. That's a gut feeling -- I don't know if I can back it up with anything. You should probably ignore me. ;-)

0:05 rhickey: gotta run, thanks all for a nice conversation

0:05 JamesIry: rhickey: thanks for the pointers on STM

0:05 Hopefully you and Martin Odersky can talk some time

0:05 rhickey: yes

0:06 JamesIry: Chouser: on my wishlist for Scala would be some equivilant of reader macros so I could create my own literal forms for things like regexs or BigInts

0:08 Chouser: JamesIry: Yeah, I asked about regular (non-reader) macros. Nobody seemed opposed...

0:08 JamesIry: I'm all for them. The natural model wouldn't be Lisp style macros though - it would be something more like Template Haskell or Nemerle templates.

0:09 Or the Ocaml one whose name I can never remember

0:09 caml4p

0:10 Chouser: but in most of those syntax-ical languages that have "macros", you can't call host language functions from within an macro.

0:10 ...which gets m4 or CPP-level functionality. Not impressive.

0:13 JamesIry: Chouser: CPP is a poor comparison. And I'm not sure what you mean. A template can't call host language at expansion time, but it certainly can at runtime. Isn't that roughly similar to many lisps?

0:14 Chouser: no, lisp macros can call any function they want at expansion time.

0:14 JamesIry: Not talking about CL. Thinking more like Scheme

0:14 Chouser: oh. well.

0:15 It makes a huge difference in how powerful the macros can be.

0:16 JamesIry: Of course!

0:17 Chouser: Have you read On Lisp by Paul Graham?

0:17 JamesIry: Yup

0:17 Good book

0:17 I also read his "Ansi Common Lisp" which was as dry as a 3 week old tortilla

0:17 :)

0:17 Chouser: I didn't "get" what the big deal was with macros until I read it. Now I'm a believer. ;-)

0:22 JamesIry: Practical CL is also a good book which conveys the power of macros. It's not quite as tight as On Lisp, but does give a better feel for the rest of the language. When people ask me about lisp I usually recommend SICP, Practical CL, and On Lisp in that order. Unfortunately, I also now have to recommend them to Clojure but there aren't any books on it just yet.

0:28 Well, I gotta run... thanks for the chat

0:48 Leafw: is there any way to create a string in a macro, and make it become a keyword, not a string, in the expanded code?

0:48 for example: (defmacro pra [T] `(println ~(str "#^" T "s")))

0:49 that generates a string with str, but, is there anyway to make it become cleanly #^doubles , for example, with (pra "double") ?

0:50 Chouser: Leafw: yeah, just a sec...

0:50 Leafw: ok!

0:52 the idea being, I want to write generic functions, that can be automatically type-decoreated for int, float , etc.

0:52 with macros, of course

0:52 Chouser: try (symbol (str ... ))

0:52 but I think you have other problems with that macro

0:52 Leafw: thank you

0:53 that is just an example

0:53 Chouser: ok

0:54 Leafw: wow this is nice.

0:54 thank you Chouse

0:56 Chouser: :-) np

0:56 Leafw: this is awsome

0:57 :)

0:59 Ycros: mmm, macro enlightenment

1:00 Leafw: yes.

1:00 good night all.

2:19 clojure's pastebin ?

2:21 lisppaste8: leafw pasted "macro primitives" at http://paste.lisp.org/display/61746

2:21 Leafw: I'd appreciate help with that macro

2:22 it macroexpand-1 ok, and the code alone urns ok, but when called from a macro it fails with ArrayIndexOutOfBoundsException, which puzzles me

2:23 if it makes you scream, this is just a test ......

5:22 cgrand: Leafw: did you make your sum<T> macro work?

8:32 Lau_of_DK: Is (lambda () (...)) directed swapped with (fn [_] (...)) in Clojure?

8:34 jteo: yup.

8:34 Lau_of_DK: k, thx

8:38 user=> (def white (. (new Color 255 255 255 255) (getRGB)))

8:38 #'user/white

8:38 user=> white

8:38 -1

8:39 Should this return an object ?

9:00 Noone knows? :)

9:00 rhickey: knows what?

9:00 Lau_of_DK: why white is -1 instead of a Color object

9:06 tomhickey: i believe it's because that's the result from calling getRGB (which returns an int)

9:07 Lau_of_DK: okay, thanks tom

9:07 Not having worked with Java can trigger some dumb questions and Netbeans seems to have some flaws in its "intellisense"

9:36 Leafw: cgrand : no, I didn't

9:36 new day, will try again

9:37 should be using gensym instead of a __ in front of a var name, will fix that too ...

9:37 cgrand: leafw: you problem is with #^

9:37 Leafw: it's still here http://paste.lisp.org/display/61746

9:38 the #^doubles type declaration?

9:39 if I use it separately no problem

9:39 rhickey_: there are simple function casts for int/long/double/float and ints/longs/doubles/floats/ so you don't need to emit metadata

9:39 Leafw: will get to it in an hour or so

9:40 rhickey_: (let [arr (doubles a)] ...

9:40 Leafw: function casts? That's new to me

9:40 rhickey_: cast functions

9:40 Leafw: ok

9:40 rhickey_: they were always there for int/long etc, ints/longs are new

9:41 Leafw: yes, I know

9:41 I'm Albert by the way.

9:41 brb

10:20 lisppaste8: Lau_of_DK pasted "Ants-modified" at http://paste.lisp.org/display/61761

10:21 Lau_of_DK: Gents - Im trying to modified Rich's Ants example to simulate Langdons ant. So the first step was pretty simple, just modify the world to a checkerboard with alternating black/white squares. setup does this correctly, but I've hit a problem: Now it doesnt render anything at all. It wont render the checkers, and I tried just setting a random color to see if it would paint anything, but nothing happends - Am I overlooking something?

10:39 no takers? :)

10:49 Chouser: Is there way to create a proxy with a method that returns "this"?

10:50 Lau_of_DK: what you pasted doesn't run because of missing earlier bits (import, etc.) I'm too lazy to figure out what needs to be added. ;-)

10:50 Lau_of_DK: No that was on purpose, so you guys knew where the problem was :)

10:50 But I can paste the whole thing

10:50 rhickey_: Chouser: is the this-returning method a method of one of the superclasses?

10:51 lisppaste8: Lau_of_DK pasted "Ants-modded" at http://paste.lisp.org/display/61762

10:51 Chouser: (let [myobj (proxy ... (mymethod [] myobj))]) ... doesn't work because myobj isn't bound correctly yet, right?

10:51 rhickey_: yes. has to be for proxy, right?

10:52 rhickey_: yes, 'this is bound to this in all proxy fns

10:52 (mymethod [] this) should work

10:52 Chouser: rhickey_: oh! great.

10:52 Lau_of_DK: are you not getting java.lang.ClassCastException: java.lang.Integer cannot be cast to java.awt.Color

10:53 Lau_of_DK: (getRGB) always returns an int, even in Rich's example

10:56 Chouser, if I compile the whole thing, I get "IllegalArgument xception ISeq from: Symbol) but its pretty unclear whats firing it

10:57 Chouser: Lau_of_DK: I think I'm seeing the same exception

10:59 anyone know how to get java to print the full stack trace instead of ending with "... 18 more" ?

11:00 Lau_of_DK: In SBCL you can set *break-on-signals* t

11:00 If you want to break on signals that is

11:01 Chouser, the exception comes when (go) tries to map the send-off, so setup might not be returning something that you can Iseq

11:01 but this should affect the painting at this stage?

11:08 Chouser: Lau_of_DK: you need a [] after (defn go

11:11 Lau_of_DK: I don't think you need (getRGB) at all -- just create the color object and pass that.

11:12 Lau_of_DK: And can test it, but can you see why it doesnt update the panel at all ?

11:12 Chouser: ...and did you change setup? It looks like it used to return a seq of agents (as created by spawn-ant), but is now returning a seq of StructMaps (as returned by alter)

11:13 Lau_of_DK: yea, that was my mistake. I had to modify some of it. Now Ive simply moved the for loop to the bottom, which should return the ants, but instead it throws an error ala "No transaction running"

11:14 And thats an illegal state exception

11:16 Chouser: I'm not seeing that.

11:17 lisppaste8: Lau_of_DK annotated #61762 with "setup-modded" at http://paste.lisp.org/display/61762#1

11:17 Lau_of_DK: Are you running it like that annotation ?

11:18 Chouser: nope. You had two separate loops before, and now have them nested?

11:18 Lau_of_DK: yea

11:19 (doall is a nest, and (dosync is another

11:20 But was does "no transaction running" mean? I was under the impression that dosync started a transaction

11:20 Chouser: to fit with the rest of the code, setup need to return a seq of agents.

11:21 Lau_of_DK: Yes - And I suppose it will do that, if I get past that exception, right?

11:21 Chouser: with your annotation, you've got an "alter coordiante" outside any sync

11:21 and I think setup is returning a seq of alternating structmaps and agent-seqs.

11:22 Lau_of_DK: ok, well I guess thats just a matter of applying a sequences structure to them, but I really dont get that exception, where does it come from? Even if I wrap the top-nest in a dosync, it still fires

11:24 ok, merged the loops, now it looks like its working

11:24 Chouser: great

11:25 Lau_of_DK: Yea - btw, thanks alot for helping out - I really hate these first few days with a new language, can feel abit like slamming your head against a wall :)

11:25 * Chouser nods

11:33 lisppaste8: Lau_of_DK annotated #61762 with "setup-working" at http://paste.lisp.org/display/61762#2

11:34 Lau_of_DK: That works. It alternates all the colors in a transaction and creates a sequence of ants on locked start-positions. But it does not motivate the program to render anything on the panel

12:04 lisppaste8: Lau_of_DK pasted "Ants-mod" at http://paste.lisp.org/display/61767

12:04 Lau_of_DK: Could somebody please have a look at this. It somewhat works. Setup initializes the board and creates ants. The frame is setup the way it should be, the only thing thats wrong is that I cannot get it to paint the panel

12:05 Also, it doesnt throw any color exceptions

12:22 Any ideas are welcome, Ive got nothing to go on

12:22 cgrand: Lau_of_DK: move (. g (drawImage img 0 0 nil)) in render after (dorun ...)

12:23 (you have to first draw on the image, then draw the image)

12:23 Lau_of_DK: haah

12:23 okay cgrand , thanks alot :(

12:23 * Lau_of_DK pouts

12:34 Lau_of_DK: man this STM approach is awesome

12:36 Chouser: cgrand: is your js* up anywhere I can peek at it?

12:38 cgrand: chouser: http://code.google.com/p/clj-stuff/source/browse/trunk/clj-stuff/template/js.clj#85

12:42 Chouser: cgrand: thanks

12:42 cgrand: chouser: "process-form" is where the action tooks place

12:43 (some examples: http://code.google.com/p/clj-stuff/wiki/TemplatingExamples#Javascript_HTML_templating_examples)

12:48 Chouser: cgrand: cool.

12:48 the destructering is fantastic. ;-)

12:49 cgrand: thanks to macroexpand-1 :-)

12:50 Chouser: keywords in function position are automatically evaluted instead of translated?

12:55 cgrand: Hmm... a keyword in function position is handled by the default case of process-form: translating to a function call (and :kw becomes the identifier kw in js)

12:56 so (:kw {:kw 1}) doesn't produce anything useful

13:33 lisppaste8: cgrand pasted "for chouser" at http://paste.lisp.org/display/61773

13:40 Chouser: hm. So what does (:id item) do in the wiki example?

13:47 cgrand: chouser: dynamically inserting the value of (:id item) (I was using an awkward special symbol named "jstr" but I changed that to support quote instead, I updated the wiki example)

13:55 Chouser: ah, I see. great.

13:55 cgrand: (jstr "#" (:id item) " a") meant at *runtime* evaluate (str "#" (:id item) " a") -- keep in mind that's a templating lib so some parts are static (and serialized once for all) and some are dynamic (and jstr (now quote) is delimiting dynamic parts)

13:56 Chouser: yup.

13:58 it's very interesting. I'm not sure, but I think it's slightly different than what I was imagining.

13:58 Or maybe you're just using it differently than I had in mind.

14:00 of the 38k lines of JS I mentioned yesterday, none of it is generated dynamically. It's all static .js files.

14:01 rsynnott: yargh

14:06 cgrand: a simple use case is passing values computed by the server to the client-code eg generating something like: init({some: "js", data: structure}) (init being defined in an external js file)

14:09 Chouser: sure. we do that, but the json is converted from C++ data structures instead of clojure ones.

14:09 What intruiges me would be the possibility of replacing the 38k lines of JS with some smaller amount of clojure.

14:10 cgrand: a complex use case is generating client-side templating functions from their server-side counterparts

14:10 rsynnott: common lisp has a very nice js generator thing; wonder has anyone done anything similar for clojure?

14:12 cgrand: chouser: by "some smaller amount of clojure", do you really mean Clojure or some notation for JS code?

14:13 Chouser: well... that's a good question. I mean something very very close to clojure.

14:14 ...as was discussed here yesterday.

14:14 No sync or agents, but probably PersistentHashMaps and Vectors.

14:16 I want to be able to use some (most?) of the Clojure idoims, instead of some new idioms required by a goofy offspring of JS and Clojure.

14:16 * cgrand is re-reading last night logs

14:29 Lau_of_DK: Can somebody explain some of the syntax from Rich's ant simulator? In (behave) he sometimes has this action (-> loc drop-food (turn 4)) what is that?

14:34 Chouser: -> is a macro that pass each expression as the first argument of the next expression

14:34 it turns it turns it inside-out, so that becomes: (turn (drop-food loc) 4)

14:38 man, I can't type. sorry.

14:40 Lau_of_DK: man thats a weird macro, is that widely used in your programs?

14:42 Chouser: It's nice in limited context where it's easier to read the other way around.

14:42 ...and it saves parens, which is great in this economy with the high paren prices and all.

14:42 Lau_of_DK: ok, well thanks alot for the explanation, Im glad I didn't go with my intuition

14:51 rapido: rich, have you considered using treaps for set operations?

14:52 here's the paper: http://www.cs.cmu.edu/afs/cs.cmu.edu/project/scandal/public/papers/treaps-spaa98.pdf

14:52 a nice property of a treap is that they always turn into the same structure, independent of insertion order

14:53 i think clojure has the right default: immutability will save the world ;)

14:54 with persistents treaps the set operations, such as union, difference, etc can be made optimal

15:14 lisppaste8: Lau_of_DK pasted "Almost-Ants" at http://paste.lisp.org/display/61777

15:14 Lau_of_DK: Chouser, - or anybody really - Can somebody tell me why behave looks like its executing once, and then returns nil and the program "halts"

15:14 ?

15:35 Good question huh? :)

15:38 Chouser: why does it "#'behave" instead of just "behave". Rich's original does too.

15:38 Lau_of_DK: Im not sure

15:43 Chouser: well, that code's still throwing an exception for me, regarding color.

15:44 Lau_of_DK: really?

15:44 Thats "impossible", I've removed all those

15:44 Sure you loaded a fresh file in a fresh repl ?

15:45 Chouser: yeah, it's the 0 on line 25

15:46 Lau_of_DK: argh, you've got sharp eyes

15:46 Or do you have some type of debugging tool that told you ?

15:47 Chouser: no, I'm running the thing and it crashes.

15:47 java gives me a stack trace.

15:48 the reason you only get one cycle appears to be because of a crash in the agent function as well.

15:49 java.lang.NullPointerException at clojure.fns.user.behave__1888.invoke(ant.clj:99)

15:49 Lau_of_DK: by "the agent function" you mean (behave) ?

15:51 Chouser: looks like it. I just meant that because the crash is from inside an agent, it doesn't get reported as conveniently.

15:52 I don't really know this code at all, so I'm learning as I go here.

15:56 Lau_DK: Sorry Chouser , Gnome just crashed, last thing I got was you said some invoke error on line 99

15:57 Chouser: ok. Yes, I guess I meant (behave). But the reason I didn't say that is I wasn't sure which function the agent was running when the exception was thrown.

15:57 I don't really know this code at all, so I'm learning as I go here.

15:58 Lau_DK: ah ok. Well I really appreciate you taking the time, just let me know if its too much. But before you say stop - What could cause that error in behave? Basically its just (move loc) loc) - thats it

15:59 Chouser: somehow the locs are getting set to nil.

16:02 Lau_DK: For some odd reason I'm not getting the debug information that you are

16:03 To me it just runs, then stops

16:05 Chouser: oh, nevermind. it's still running, just the ants aren't going anywhere.

16:05 Lau_DK: Oh - So it just returns nil after having sent off every ant?

16:05 Chouser: no, I was wrong about nit

16:06 nil

16:06 (cond (not (:ant @ahead))

16:07 (move loc))

16:08 (:ant @ahead) seems to always return a hash, which is true, so (move loc) never gets called

16:09 Lau_DK: I just removed the whole cond, so its only (move loc) loc)

16:09 Chouser: ...and I wasn't completely wrong about nil. (behave) used to return loc from inside the sync, but your version it's outside the sync. That seems to matter.

16:09 Lau_DK: still just stays in the middle... but move seems to work when I test it in repl

16:10 Chouser: Lau_DK: I think you've made more changes than you realize or something.

16:10 we've found several of these functions are returning different types of objects than they used to.

16:10 Lau_DK: Ive made quite a few - But there's quite a gab in the purpose of the applications, they just share the name and the need for drawing a JPanel :)

16:10 Chouser: you might want to back out your changes and make them more incrementally, testing as you go.

16:10 Lau_DK: I'll right, I'll run through the whole thing

16:11 Chouser: oh. well, in that case you might try starting from scratch and writing just what you need.

16:11 It's hard to change a program correctly without understanding what's already there.

16:11 Lau_DK: Yea, maybe I should. I just figured I'd be an easy way to learn som basic clojure

16:11 Considering I've heard Rich explain most of it on a video

16:11 Chouser: I'm not sure that demo counts as "basic clojure" ;-)

16:11 Lau_DK: hehe - I would actually agree

16:12 Chouser: anyway, I'm done for now. good luck.

16:12 Lau_DK: Thank you so much for your help

16:13 Chouser: if you want to tell me why I can't get my jtable to use a monospace font, that'd be great.

16:13 actually, I think I need to punt on that problem as well.

16:13 Lau_DK: Did you set the font in the cell renderer?

16:14 perhaps you should check out the API doc for this table.setDefaultRenderer(Object.class, new TableCellRenderer());

16:16 Chouser: yeah, I've got all that. And I can create and set the font, but only the size and style seem to actually get applied. The font family is ignored.

16:48 Lau_DK: Since progn is removed from clojure, what do we use instead?

16:50 Chouser: do

16:51 Lau_DK: thanks, btw. Chouser , ants are moving now :)

16:51 Chouser: nice

16:51 Lau_DK: Yea, when you can change the code while the GUI is running, you really have an advantage

18:54 Chouser, you still up ?

Logging service provided by n01se.net