#clojure log - Nov 15 2008

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

2:50 bradbev: is SVN for Clojure down right now?

2:56 johnwayner: I'm not having any problems with it

2:59 bradbev: hmm

3:00 apparently something to do with https

4:01 Lau_of_DK: Top of the morning gents

4:24 Asking as a Java-noob, how difficult is it to load a .c/.h and drive it from my clojure code ??

7:27 Chouser: rhickey: what are the chances of getting duck-streams or something like it into core for 1.0?

7:30 AWizzArd: Duck streams? As in: "we stream everything for you"?

7:31 Chouser: clojure.contrib.duck-streams -- I'm not sure about the origin of the name, since it doesn't really use duck typing

9:27 Lau_of_DK: Does Java search /usr/lib/* for .so files ?

9:28 StartsWithK: Lau_of_DK: no

9:29 Lau_of_DK: Where can I count on it StartsWithK , do you know?

9:29 StartsWithK: you have to add -Djava.library.path

9:30 maybe it will search for .so files under java main installation tree, but i dont know that

9:31 so if you use say jogl (opengl) and all gluegen and jogl files are under lib/ dir you will have to start clojure something like

9:31 java -Djava.library.path=lib -cp lib/jars-you-want clojure.lang.Repl

9:33 Lau_of_DK: It was exactly jogl I was trying to install

9:34 It seems it autloads /usr/lib/jvm/java-6-sun-

9:34 StartsWithK: unzip jogl in your lib dir, you should have gluegen jar and .so files too inside distribution

9:35 blackdog: Lau_of_DK, do a search for JNA i think it's called on the clojur group

9:35 StartsWithK: and call it with java.library.path

9:35 blackdog: there's an example of calliing native code

9:36 StartsWithK: blackdog: jna dosn't need any native so files to work

9:36 just a .jar for your target platform

9:36 blackdog: sorry i saw a question by Lau_of_DK earlier so i may not have the current context

9:37 of this discussion

9:38 Lau_of_DK: blackdog, you were commenting on C integration ?

9:39 blackdog: yes

9:39 Lau_of_DK: oh okay, cool, thanks alot

9:39 StartsWithK, whats this Gluegen ?

9:40 StartsWithK: its wrapper they created just for opengl, so i think jogl.jar is autocreated from c api

9:40 blackdog: Lau_of_DK, http://groups.google.com/group/clojure/browse_thread/thread/77e626c5440bf1a0/487327209b633451?lnk=gst&q=jna#487327209b633451

9:40 StartsWithK: thats why GL class is one giant mess

9:40 Lau_of_DK: oh ok

9:40 StartsWithK: with all C names

9:40 Lau_of_DK: http://pastebin.com/f4708ffa8 try this for your ant build

9:41 Lau_of_DK: Cool

9:41 StartsWithK: i could't find a good way to use jogl with maven/ivy repositories

9:41 Lau_of_DK: StartsWithK, blackdog , thanks to the both of you

9:41 StartsWithK: so i have this snippet in my ant file

9:42 Lau_of_DK: and so that builds an executable jar ?

9:42 StartsWithK: no, it just downloads jogl.zip from java.net and copies file to my lib/ directory

9:43 and in build.properties i can select platform and os i want to use

9:43 Lau_of_DK: ok, Ive only ever used ant to build the clojure source

9:44 StartsWithK: it helps to eliminate external jars from your local revision system

9:45 for now i only have to keep clojure.jar, still no nice way to pull from svn in ant build

9:45 Lau_of_DK: Where did you start out, to get comfy with jogl ?

9:45 StartsWithK: i started jogl wrapper

9:46 and did gears demo, some examples from redbook and nehe tutorials

9:46 there is nehe (and redbook) port to java

9:47 Lau_of_DK: Oh thats right

9:47 StartsWithK: i plan to rewrite jogl wrapper, it was when i started using clojure, first thing i did, so its realy bad :)

9:47 Lau_of_DK: I believe you actually posted all that in here in the early days of clojure?

9:47 StartsWithK: yes

9:49 Lau_of_DK: http://ksojat.net/repository/ repository from that time is here

9:50 i don't think it works anymore, i integrated it with my main project, noone was using it anyway :)

10:10 rhickey_: svn 1104: added static main() support for AOT. Just defn main in your ns, will be applied to command line string args

10:17 Chouser: rhickey_: sweet. The only way to call that fn from the command line is after it's been AOT compiled, right?

10:17 rhickey_: Chouser: right

10:18 you should be able to jar up your Clojure app and invoke just as if it was a java app

10:18 Chouser: I wonder if there's any sensible way to make it callable when not pre-compiled.

10:19 rhickey_: Chouser: not sure what you mean

10:19 you can dynamically redefine main

10:19 Chouser: well, I'm not sure either. Some parts of the clojurescript .clj are useful as a command-line app.

10:19 blackdog: rhickey, vcool, betting on the betting on clojure gets validated daily, thanks!

10:20 rhickey_: you could define a main which took as it's first arg the name of the sub-command

10:20 its

10:21 kotarak: eg. svn co

10:21 Chouser: Currently I have the part that parses *command-line-args* in a separate main.clj, so you can run: java -cp ... clojure.lang.Script clojurescript/main.clj -- --help

10:21 rhickey_: it's fun because the main fn is applied - it can be overloaded on arity

10:22 Chouser: so it'd be nice to move main.clj into a defn main of the primary tojs.clj, but I'm not sure how to then call it without pre-compiling.

10:23 I guess the odd thing is I'm trying to make a single .clj work both as a support library and as a command-line app.

10:23 It's not uncommon in Python, but maybe it doesn't work in Java-land.

10:23 rhickey_: Chouser: I don't see why not

10:24 Chouser: well, when my tojs.clj loads, are the *command-line-args* for me or not?

10:26 rhickey_: seems like you shouldn't depend on them coming specifically from *command-line-args*

10:29 Chouser: ok, so instead I can define a main fn to take the args. But then how can I call that from the command-line without pre-compiling?

10:30 or are you saying a general convention of the first command-line arg specifying which .clj's main fn to call?

10:30 rhickey_: precompiling only puts the static void main in your .class file. If you defn main in a .clj it's there compiled or not

10:31 (your.ns/main ...) will work without precompilation

10:32 Chouser: yes, but how can I trigger that from the command line?

10:33 Again, one way would be to have a separate "main.clj" that just does (your.ns/main ...), and call it from the command-line like: java ...Script your/ns/main.clj

10:33 rhickey_: either you are running clojure.lang.Script or you are not, if you ar eyour script runs, if you end it with (when-not *compile-files* (apply main *command-line-args*)) that might work

10:35 I really don't understand the problem space, so I don't see the problem :(

10:36 you want to be able to say either java ... clojure.lang.Script my/app.clj -- args

10:36 or java my.app args

10:36 ?

10:36 kotarak: Do I have to set that compile-path? I thought it would default to classes?

10:37 Chouser: yeah, Java's never concentrated on support command-line; one of its few weaknesses that Clojure doesn't address yet. I'll write it up for the g.group

10:37 kotarak: it defaults to "./classes", so it's relative to your CWD when you start clojure.

10:38 rhickey_: kotarak: bound to classes only in the repl

10:38 dudleyf: Ideally, you shouldn't have to say 'java' anything

10:38 kotarak: Ah. That's it.

10:38 For a script I use (binding)?

10:38 rhickey_: there are many java app packagers

10:38 Chouser: dudleyf: that's a separate issue

10:39 rhickey_: kotarak: yes, binding

10:39 kotarak: rhickey_: thanks. :)

10:39 dudleyf: Chouser: I thought you were talking about command line invocations

10:39 kotarak: I was looking for to AOT. Just porting my projects. :)

10:40 Chouser: I already have a "clj" shell script that works pretty well for me, but I think I need more hooks from the outside.

10:40 dudleyf: Chouser: So do I, I think that's one of the problems ;-)

10:41 Chouser: hm, though perhaps I could use a java property or something hm...

10:43 rhickey_: what's wrong with (when-not *compile-files* (apply main *command-line-args*))

10:43 ?

10:44 a defmain macro could both defn main and emit that, just put at end of script

10:44 Chouser: I also want to be able to (require my.ns) inside some other app.

10:45 In that case, whether it's being compiled or not isn't the issue. I need to know if my ns is being invoked directly or not, similar to how a Java class can be "invoked" thus calling it's main() method.

10:45 rhickey_: Chouser: ah

10:46 kotarak: Sorry, me again: what does that mean? Exception in thread "main" java.lang.reflect.InvocationTargetException (clojurecheck.clj:23)

10:46 Chouser: python does this with something like: if __this__ == __main__: ...

10:46 kotarak: you have an error on line 23 of clojurecheck.clj :-)

10:47 kotarak: Chouser: in code which worked perfectly before.

10:47 The code looks like this: (defn todo* [body] (binding [*some-var* special-val] (body)))

10:48 Chouser: kotarak: defn? not a macro? so body must be an IFn

10:49 kotarak: (defmacro todo [& body] `(todo* (fn [] ~@body)))

10:50 This happens while compile, btw.

10:50 rhickey_: kotarak: got more stack trace?

10:50 kotarak: Sure. just a sec.

10:50 rhickey_: where'd the lisp paste bot go?

10:51 Chouser: lisp paste site wasn't even pasting right yesterday

10:52 Lau_of_DK: Clomacs should include built-in pasting to #clojure :)

10:53 Chouser: yeah, still not pasting.

10:55 kotarak: Yes. paste.lisp.org seems halfway broken, but w/o channel it worked: http://paste.lisp.org/display/70434

10:57 rhickey_: kotarak: your compile path must be in your classpath

10:57 kotarak: It should be. But will cross-check.

11:00 rhickey_: I've been thinking about removing that restriction, as so many people trip over it. What happens now is the classes you compile are loaded back from disk, a nice double-check. Without this restriction, I could just load from bytecode already in memory, but wouldn't be accessible as high up in the classloader hierarchy

11:00 Lau_of_DK: Shouldnt that just be optional ?

11:01 rhickey_: No, I think it should work one way

11:01 kotarak: Hmm... I had a symbolic link to the "compile" directory. But obviously the master .class from the master .clj is missing. So I suppose this was the problem. Setting it explicitely with env during the compile fixed the problem.

11:02 Lau_of_DK: rhickey, it seems a little like a waste of ressources to write to disk and then read it again, if you dont need it higher up, I would happily deselect that feature

11:03 rhickey_: every option doubles complexity

11:03 Lau_of_DK: k

11:04 AWizzArd: rhickey_: would it be possible to offer an (disassemble function)?

11:05 rhickey_: AWizzArd: I've left that part of ASM out of the Clojure build, for size reasons

11:06 AWizzArd: Size reasons? To make Clojure more available for cell phones and fridges?

11:07 rhickey_: cell phones are an important target Clojure still doesn't quite make yet

11:08 phone people have complained about the 450k size

11:09 AWizzArd: uh

11:10 rhickey_: But I admit it might be a false economy. If using stock ASM, could pull out of Clojure entirely, would become a jar dependency though...

11:10 AWizzArd: do they know it's nearly 2009? And that mobile phones come with several mb ram?

11:10 Lau_of_DK: I would suggest a clojure and a clojure-light, but that would probably quadrouple complexity

11:24 leafw: I would suggest waiting a year, when cell phones multiply their memory and it's no longer an issue at all.

11:25 no need to complicate matters.

11:42 johnwayner: Anyone else run into a "Var com.johnwayner.world/main is unbound" error when attempting to invoke main from the command line?

11:43 I've defn'd main and there's a world$main__2644.class file in my classpath (along with the other fns for that ns)

11:45 AWizzArd: rhickey_: is there some version number or timestamp compiled into Clojure, so that one can see that one definitly is using the newest version?

11:46 kotarak: AWizzArd: http://groups.google.com/group/clojure/browse_thread/thread/9fa07b00c88280fc

11:48 rhickey_: johnwayner: fixing now, hang tight

11:49 johnwayner: rhickey_: sweet.

11:58 AWizzArd: Is it possible to run the newest version of Clojure inside NetBeans? Or is there a a clojure.jar hard encoded inside the Enclojure plugin?

12:00 rhickey_: AWizzArd: try #enclojure

12:08 johnwayner: fixed - try rev 1105

12:09 jgracin: how do I create byte[] in Clojure? is it (make-array Byte x)?

12:10 rhickey_: user=> Byte

12:10 java.lang.Byte

12:10 user=> Byte/TYPE

12:10 byte

12:11 jgracin: rhickey: thanks!

12:11 rhickey_: all the primitive types can be found the same way

12:23 johnwayner: rhickey_: fixed, thanks!

12:24 rhickey_: johnwayner: great!

12:25 johnwayner: rhickey_: I suppose it's also expected behaviour that the jvm doesn't shut down after main returns?

12:26 rhickey_: johnwayner: depends on your app - my hello world test does

12:27 johnwayner: rhickey_: hmmm Perhaps I have running threads

12:27 rhickey_: I'll explore more.

12:34 danlei: how can i interrupt a long-taking computation in slime? slime-interrupt doesn't seem to work for me, when C-c in clj suffices.

12:40 Lau_of_DK: danlei, I would like to know that also! :)

12:41 You can always do a nasty work-around, but getting C-c C-c to work would be nice

12:42 danlei: what kind of workaround do you have in mind, besides C-c C-c in the inferior lisp buffer?

12:42 Lau_of_DK: I dont know. If I have threads running computations, my only escape is to have them throw exceptions

12:44 danlei: (set x (range 333333333333333333))

12:44 * danlei always hits the wrong buffer ...

12:44 Lau_of_DK: hehe

12:45 danlei: =)

12:45 AWizzArd: just give it some time, and it will finish

12:45 Lau_of_DK: haha, AWizzArd didnt you give the same advice to rhickey regarding the clojure cell-phone variant ?

12:46 AWizzArd: hmm, I don't think so

12:46 danlei: AWizzArd: that would be the stoic solution, yes

12:47 Lau_of_DK: AWizzArd, youre right, that was leafw

13:35 abe: I have very limited lisp experiance and i have a beginer macro problem.

13:37 i want to doseq in my macro and i cant get the computer bind to a counter without throwing an error

13:37 am i being clear?

13:37 and is anybody actually here?

13:37 Chousuke: are you using old style binding or new style binding? :)

13:37 doseq changed a while ago

13:38 as of revision 1089 it takes a vector

13:38 abe: oh...i have no idea what revision i am using

13:38 Chousuke: did you get it form SVN?

13:38 from*

13:38 abe: nah

13:39 Chousuke: then it's probably fairly old

13:39 there have been a lot of interesting changes recently

13:40 abe: think i should download from the svn?

13:40 Chousuke: probably.

13:40 abe: ok well i will do that later

13:40 Chousuke: if you use slime you'll need a newer clojure-swank too

13:41 abe: i havent even set up a real development environment. i'm really just browsing

13:42 but the body of my macro looks like this

13:42 `(do (doseq ~i ~args (~tprint ~i)) (~f ~@args))))

13:43 its just to print the arguments of a fncall out before it executes

13:43 Chouser: where's i coming from?

13:43 abe: this is the whole jobbe

13:43 (defmacro debug [f & args]

13:43 (let [tprint #(do (print %) (print ":"))]

13:43 `(do (doseq ~i ~args (~tprint ~i)) (~f ~@args))))

13:43 Chousuke: http://groups.google.com/group/clojure/browse_thread/thread/8618a1d93cbbf8b7# here's a list of recent breaking changes

13:44 Chouser: abe: ~i will evaluate the expression i -- I assume that's what the error is about?

13:45 abe: yeah

13:45 how can i just get some sort of dummy in there to bind

13:45 Chouser: because i is not defined. Try giving it a value -- (let [i (gensym)] `(do ...))

13:46 or as a short-cut, replace all ~i with i#

13:51 abe: i am confused because (doseq i [1 2 3] (print i)) works

13:51 Chouser: abe: yes, but notice that there you've replaced ~args with [1 2 3], but ~i with i

13:52 abe: ahhhh thank you

13:54 Chousuke: abe: that form will stop working with the newer version :) it's now (doseq [i [1 2 3]] (print i))

14:05 nd: hi! I get latest version of clojure from svn, build it and have errors running slime:

14:05 (clojure/require (quote swank))

14:05 java.lang.Exception: No such namespace: clojure (NO_SOURCE_FILE:3)

14:05 user=>

14:05 (swank/ignore-protocol-version "2008-11-02")

14:05 java.lang.Exception: No such namespace: swank (NO_SOURCE_FILE:5)

14:05 user=>

14:05 (swank/start-server "/tmp/slime.5462" :encoding "iso-latin-1-unix")

14:05 java.lang.Exception: No such namespace: swank (NO_SOURCE_FILE:7)


14:05 I also update clojure swank-clojure, but it doesn't help.. What should I do to make it work again?

14:06 Chousuke: what instructions suggest using (clojure/require 'swank) :/

14:06 my settings don't have that, and they work.

14:06 Chouser: rhickey_: My opinion (whatever that's worth) is that current behavior of compile regarding "./classes" should remain. You'd need your classpath to correct eventually anyway, I think it's currently less confusing than it would be otherwise.

14:07 Chousuke: nd: use these settings: http://en.wikibooks.org/wiki/Clojure_Programming#Emacs_.2F_Slime_Integration

14:07 nd: Chousuke: thanks, I'll try it

14:09 drewr: nd: The latest swank works with the latest Clojure. Make sure you've loaded everything. Restart Emacs, perhaps.

14:23 nd: it seems that i forget to update something, update all again, and now it's work. thanks

14:26 drewr: Trying out main support. What am I missing?

14:26 (defn main [& args] (println (str "args: " args)))

14:27 Calling that from a file on the command line.

14:27 (ns foo.bar) is before that.

14:27 rhickey_: drewr: what svn rev?

14:28 drewr: rhickey_: 1105

14:28 rhickey_: what happens?

14:28 drewr: No output.

14:28 No errors.

14:29 Running with "java -cp clojure.jar clojure.lang.Script main.clj -- foo bar"

14:29 rhickey_: drewr: you don't use Script with main

14:30 drewr: Just run it outright?

14:30 rhickey_: java ... foo.bar.main args

14:30 Chouser: drewr: and you have to compile your ns first

14:30 rhickey_: sorry

14:30 hava ... foo.bar args

14:30 java

14:31 with foo/bar.class in classpath

14:31 main support is for standard Java invocation

14:32 (ns my.hello)

14:32 (defn main []

14:32 (println "Hello World!"))

14:33 localhost:clojure rich$ java -server -cp ./test:./classes:clojure.jar my.hello

14:33 Hello World!

14:34 drewr: Is add-classpath enough to load the directory I'm saving the file in?

14:35 scottj: rhickey_: what wiki software is clojure.org using?

14:35 rhickey_: drewr: probably not

14:35 drewr: scottj: http://www.wikispaces.com/

14:51 OK, got it to work.

14:51 rhickey_: drewr: cool

14:51 drewr: So would there still be any advantage to using Script?

14:52 This seems a little more straightforward once you get it wired up.

14:52 No tricks on the command line, *command-line-args*, etc.

14:52 Lau_of_DK: rhickey, since AOT is now working, is gen-&-load-class and all these related func's removed ?

14:52 Chouser: if you don't want to re-compile every time make a change.

14:52 Lau_of_DK: not yet. They still have features that haven't been rolled into AOT yet.

14:52 Lau_of_DK: Sweet :)

14:54 kotarak: is it possible to assign an existing function to a multimethod? (defn foo-impl [x] (+ x 1)) (defmethod foo Integer foo-impl) ?

14:55 rhickey_: Chouser: I've made it so main calls RT.load, which does the is-the-classfile-newer-than-the-clj test, if not will load .clj

14:55 duck1123: has anyone seen the message: cannot load '/model/entry/entry.clj' again while it is loading

14:56 I think it might be because I have 2 files that use each other, but I can't figure out how to resolve it

14:56 Chouser: rhickey_: ohhhh... of course. So you only need to compile once to get your properly named class with a main() stub.

14:57 rhickey_: Chouser: right, the same command line will give you your not-yet-compiled clj script

14:57 via the old class stub

14:58 Chouser: does it just load the .clj, or compile it to disk first?

14:58 rhickey_: Chouser: just loads

14:59 compilation to disk is always explicit

14:59 Chouser: ok

15:00 * rhickey_ working on genclass fold-in now

15:00 badkins: Has anyone expressed interest in getting Clojure in the running on the shootout site? http://shootout.alioth.debian.org/

15:00 rhickey_: there will be a :genclass option in ns

15:00 taking the same args as genclass

15:00 badkins: I realize there are some "issues" with the methodology, but it would be nice if Clojure was represented - the performance seems quite good.

15:01 rhickey_: will apply to the AOT class corresponding to the current ns

15:01 Chouser: rhickey_: ah! sounds nice.

15:01 still using the Class-method naming scheme?

15:02 rhickey_: Chouser: no, I'm back to -method

15:02 since class is in the ns

15:02 Chouser: right, ok. leading - then?

15:02 rhickey_: yep

15:03 main hardwired to main

15:03 Chouser: sure, that should be fine.

15:04 rhickey_: so for basic use (not really defining a class for instantiation) you'll get main and won't need :genclass section

15:04 Chouser: you don't want to lift the :genclass sub-options right up to the ns macro level?

15:05 I ask these things as if you haven't already thought them all through. I should know better by now.

15:05 rhickey_: Chouser: no, then they'll need to be independently addressable - genclass will use the same name->method hack as does :use :require etc

15:06 Chouser: ah, sure.

15:06 rhickey_: plus a spectacular hack of gen-class to work in this new contet

15:06 context

15:06 gen-and-load and gen-and-save will go away

15:07 * rhickey_ always hated gen-and-load

15:07 kotarak: hallelujah

15:08 rhickey_: badkins: someone should probably do it - coordinate here for perf tips

15:11 arohner: since listpaste is broken, is there an alternative?

15:11 Chouser: arohner: try using it with not channel selected?

15:12 kotarak: arohner: yes. That works, but you have to post the URL manually.

15:12 arohner: Chouser was right, it works if the channel is not selected

15:12 I could use some help with this macro

15:13 I'm trying to write an mocking/expectation library

15:13 I'm trying to write a macro that looks like binding, messes with the arguments and sends the modified arguments to (clojure/binding)

15:13 http://paste.lisp.org/display/70458

15:16 Chouser: arohner: try moving the ` from let down to binding

15:16 then use macroexpand-1 and see if you like what you get.

15:18 arohner: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.ClassCastException: clojure.lang.PersistentList (NO_SOURCE_FILE:1)

15:18 when trying to run it or expand it

15:19 can I refer to local variables created outside of the backtick inside of it?

15:19 drewr: arohner: Yep, it creates a "clojure" :-)

15:21 arohner: :-) I think I have my head wrapped around 'normal' closures. Still trying to figure out how they work with macros

15:21 Chouser: no, I think in this case it expands the value into the expanded s-expr. Not a closure.

15:22 drewr: The sexp that gets returned has a bound environment that the let creates. That's the def of a closure, at least in my mind.

15:23 arohner: Here's how I expect to be able to use this http://paste.lisp.org/display/70458#1

15:23 that (mock) function returns a hash that contains the stub function, and state that tracks how many times the stub has been called, how many times it should be called, etc

15:24 so I want to pull the stub fn out of the hash, and create a binding that is [var stub-fn]

15:26 Chouser: drewr: I think if closures were inserted into macro expansions, you'd see in a macroexpand a reference to the (invisible) data. But you don't, you see the raw printed data itself.

15:27 rhickey_: if you insert a real closure into code as a constant value it will not work, closures can't be serialized yet. Non-closure fns can

15:29 Lau_of_Test: Lau_of_DK:

15:29 arohner: so if I move the backtick back up to the let, I won't have a closure, right?

15:33 Chouser: arohner: how does http://paste.lisp.org/display/70458#2 strike you?

15:34 arohner: NPE

15:34 Chouser: hmph

15:35 even with macroexpand?

15:35 arohner: oh, no

15:35 now that works except that the value in the binding is null

15:36 (clojure/binding [user/foo nil] (test/function))

15:37 rhickey_: I really, really recommend you write macros by saying: I want to write this, I expect the expansion to be that, and write a first expansion by hand to make sure it works, then make sure your macro generates the same expansion

15:39 arohner: Chouser: I think you got me back on the right track. thanks

15:42 rhickey_: the place where i get hung up is not clearly understanding the rules about what is possible and how each thing works

15:42 Chouser: If I try to skip any step of that advice, I almost always end up having to go back and do it anyway.

15:43 rhickey_: arohner: if you have those 2 things, and paste them with your macro, it is so much easier to help you

15:44 arohner: ok. I pasted the expected input. I guess part of my problem was that I didn't know what the expected output was

15:44 rhickey_: exactly

15:44 me neither :)

15:44 arohner: :-)

15:45 having more about macros in the docs would be helpful, like explaining what ~ and ~@ do.

15:46 the docs currently appear to be 'clojure for people who are CL experts'

15:47 AWizzArd: arohner: you can look it up here: http://www.gigamonkeys.com/book/macros-defining-your-own.html

15:47 it's about in the middle of the page, search for "Backquote Examples"

15:47 and think of ~ as ,

15:47 danlei: ~ unquotes in a quasiquotation, that means `(~a a) == (list a 'a)

15:48 drewr: Table 8-1 on that page is very helpful.

15:48 AWizzArd: you never need ~ and never need ~@

15:48 danlei: AWizzArd: exactly

15:48 AWizzArd: you can write all macros with append and list

15:48 drewr: Oh, that's the one called "Backquote examples" :-)

15:48 * drewr clicks before reading

15:49 rhickey_: arohner: I understand - there's a lot to explain in Clojure, even though it's small, it covers Lisp/FP/STM etc

15:50 the docs are a language ref but don't supply background in all those areas, yet

15:50 the community is helping fill in the blanks

15:51 AWizzArd: and rhickey_ makes sure to give us new blanks (= extensions of Clojure) :-)

15:58 Chousuke: I think syntax-quote in clojure is different enough in clojure that it doesn't suffice just to say it works like in CL :/

15:58 since namespaces affect it

15:58 kotarak: yes, ' is not `

15:59 Chousuke: I meant ` in clojure is not ` in CL, though :)

15:59 even though they're very similar :/

15:59 kotarak: I think ' in Clojure is ` in CL, no?

15:59 danlei: those auto-gensyms are nice, imho

15:59 no

15:59 Chousuke: kotarak: no, ' is ' in CL too

16:00 kotarak: Hmmm... I can do '(foo ,bar)?

16:00 I thought this works only with `: `(foo ,bar)

16:00 Chousuke: clojure doesn't have ,? what.

16:00 kotarak: But I'm not a CL guy. So I should believe you. ;)

16:01 Chousuke: oops.

16:01 question mark in hte wrong place.

16:01 drewr: Chousuke: Yes, it's ~/

16:01 Er ~.

16:01 kotarak: I meant CL: Can I do '(foo ,bar) in CL?

16:01 danlei: no

16:02 "comma not inside a backquote", or similar condition

16:02 Chousuke: the thing to note is that in clojure `(a ~a) -> (user/a 1) but in CL: `(a ,a) -> (A 1)

16:03 assuming a is def'd as 1

16:03 Chouser: hygene without the pain

16:03 danlei: hm

16:04 Chousuke: if you wanted (a 1) you'd have to do `(~'a ~a) in clojure

16:04 kotarak: Hmm. I was under impression, that '(foo ~x) would work in Clojure, but now I get a ExceptionInInitializer. Hmmm...

16:04 danlei: but then, in cl it would be the interned symbol cl-user:a

16:04 (or whatever package you're in)

16:04 * kotarak has very leaky memory, it seems.

16:04 danlei: it's gensyms, that are automatically inserted in clojure,

16:04 avoiding var capure

16:05 for example, in cl, if you're binding a var inside a macro, it could be captured. that's what you use gensym for. in clojure, you have # for the same effect.

16:06 kotarak: But there are situations, where you also have to fall back to gensym.

16:06 danlei: (correct me, if i'm wrong, i'm not a cl guru either)

16:06 Chousuke: so your names in your macros get qualified with your namespace, so there's no fear that they will interfere with macros from other namespaces.

16:07 danlei: couldn't a var in a clojure macro (if not suffixed by # in the backquote expression) be captured too?

16:07 Chouser: kotarak: pre-AOT '(foo ~x) didn't produce an exception. What it produced wasn't terribly useful, but your memory may not be entirely at fault.

16:08 Chousuke: danlei: I think variable capture is possible; I'm not quite clear on how it happens in clojure :/

16:09 you can force macros to emit non-qualified names when you *do* want to capture something in the surrounding environment

16:09 kotarak: danlei: if you don't suffix your var with # (or use gensym) you will get a qualified name. So `(let [x ...] ..) should complain.

16:09 danlei: i guess, if a bound (non gensymed) var is used within the expansion of the macro

16:09 kotarak: one can use `(let [~'x ...] ...) which can be captured.

16:10 (Done for example with proxy's this)

16:10 Chousuke: yeah it'll say: java.lang.Exception: Can't let qualified name: user/a (NO_SOURCE_FILE:6)

16:11 rhickey_: kotarak: but not unintentionally, that's the point

16:12 kotarak: rhickey_: I know.

16:13 Chousuke: ~'foo is ugly enough to immediately alert any readers too :P

16:14 kotarak: It just has to be well documented (as in the proxy case) and has to be used with care.

16:17 Chouser: rhickey: what are the chances of getting duck-streams or something like it into core for 1.0?

16:18 rhickey_: Chouser: it's possible - I have to admit to being unfamiliar with the bulk of contrib :( It would be great if you guys could put together what you think are the best candidates for inclusion

16:19 Chouser: heh. I bet we each think the thing we wrote ought to be in core.

16:19 rhickey_: heh

16:19 Chouser: but I guess it is true that I didn't write duck-streams or case, and would vote for both.

16:19 kotarak: make a poll on the list. say 3 or 5 extensions, which can be voted.

16:23 danlei: kotarak: thanks, works like a charm (defmacro awhen [expr & body] `(let [~'it ~expr] (when ~expr ~@body))), for example

16:23 (if one likes anaphoric macros)

16:24 Chouser: danlei: beware the wrath of rhickey_, though. :-)

16:24 danlei: =)

16:24 kotarak: danlei: think twice before you do that, and once you really decided for capturing clearly document the fact

16:24 Chouser: He'll site you for language abuse.

16:24 danlei: well, let's call it research then :)

16:26 kotarak: you're right, i know about the implications. anyway, nice to know how, if i needed it

16:38 Chousuke: hmmhmm

16:38 * Chousuke got an exception trying to run tests from contrib

16:44 Chouser: Please do NOT fill out this form yet: https://spreadsheets.google.com/viewform?key=p1hkQs__fVyaQGEP_bOFRVQ

16:45 But do please comment on its structure and language. What do you think?

16:46 Chousuke: haa

16:47 found the culprit I think

16:47 for some reason, (bigdec 3) throws an exception :/

16:51 Chouser: wow

16:52 3M is ok, though

16:52 bradbev: Chouser: It looks good to me. maybe have text box for comments?

16:52 Chouser: bradbev: sure, good idea.

16:54 Chousuke: I wonder what's wrong with bigdec

16:54 it looks okay to me.

16:55 bradbev: If I wanted to do really fast 2d graphics in Java, what is the best place to start. I'm talking 30hz game kinda speed. Also, what good profilers are there for Clojure/Java?

16:55 (maybe my drawing isn't the issue :))

16:57 Lau_of_DK: bradbev: Have a quick look a JOGL - It might be too heavy

16:57 bradbev: too heavy effort wise or rendering-wise?

16:58 Lau_of_DK: Library-wise, I dont know if you need to unbutton OpenGL for the project you have in mind

16:58 Chousuke: hm

16:58 it seems BigDecimal's valueOf doesn't like ints

16:58 Chouser: Chousuke: bigdec apparently won't take an Integer. Other options: (bigdec 3.0) (bigdec (long 3))

16:58 ah, you found it. :-)

16:59 bradbev: I've written a realtime viewer for nand chip access. 1/2 listens on a socket, 1/2 draws it. There is so much socket access that drawing via swing appears to be getting shutout unless I sleep the socket thread. :(

16:59 Chouser: Chousuke: I think the latter is your best bet. Unless I'm mistaken, (long 3) becomes a literal primitive when compiled, even though it looks like a function call.

17:00 Chousuke: Chouser: so is the test in test-clojure supposed to throw a big scary exception? :)

17:00 Chouser: Chousuke: above my pay-grade. :-)

17:00 bradbev: I know nothing from personal experience, but I've seen some impressive animation demos of large numbers of graphics objects using Qt/Jambi.

17:02 bradbev: Chouser: I'll have to take a look.

17:05 StartsWithK: bradbev: maybe you should check out pulp to (i have no personal experience with it) http://www.interactivepulp.com/pulpcore/

17:16 Jedi_Stannis: kotarak: the makefile with gorilla gives me the following error: Makefile:40: *** missing separator. Stop.

17:16 kotarak: Jedi_Stannis: that's because it's not a GNU makefile. You should have to use it anyway.

17:17 Jedi_Stannis: what's the recommended way of installing it?

17:18 kotarak: Just use the jar, which comes with the distribution.

17:18 But it in your classpath and the vim file in the corresponding places in your .vim directory.

17:18 Jedi_Stannis: k

17:19 kotarak: The Makefile won't help you installing it, since it just creates the jar.... Please note: this is all highly experimental and will most likely blow up.

17:21 Jedi_Stannis: it looks very cool though

17:22 kotarak: Yeah. I'm working on the stability. But syncronising Clojure with vim is a problem.

17:22 Jedi_Stannis: the repl in vim looks like a big improvement, since you get the indenting and the colors

17:22 kotarak: yes, but it's intended for editing.

17:22 it's not...

17:23 For small expressions its fine, but larger expressions should be edited in a separate buffer and send via \et

17:23 Jedi_Stannis: yeah, still looks like a good usability improvement. I'll try it out and let you know if I find any bugs

17:24 kotarak: I jumped through some hoops to get <CR> as smart as possible, but it can be easily confused.

17:24 Note, also: it's not compatible with the latest Clojure SVN head, yet.

17:24 Jedi_Stannis: ok, I haven't updated yet

17:24 im still using an older one

17:25 danlei: Jedi_Stannis: have you also considered slime?

17:26 Jedi_Stannis: I've been using vim for a while, I like it a lot

17:26 can't really imagine relearning an editor, never gave emacs to long of a try, but never liked any of its bindings compared to vim

17:27 danlei: ah, ok. slime is quite nice, though

17:27 kotarak: yeah, that's why I'm working on Gorilla: to something slime like to Vim.

17:28 Jedi_Stannis: yeah, I've gathered that's what most people use for lisp, but I wanna stick with vi. chimp has been working out pretty well, and gorilla looks even better

17:28 what other features does slime have?

17:28 danlei: well, i can't compare it, because i only use slime. features? hm, there are a lot

17:29 kotarak: There's a video showing the features of slime. One feature is that you shouldn't stop the process. hehe. But most likely this is fixed now.

17:29 danlei: nice it just integrates nicely, gives you a good debugger and inspector, hard to pin it down

17:29 Chouser: debugger doesn't work for clojure yet, does it? slime's I mean.

17:30 danlei: well, you cant walk around in the stack frames

17:30 like with a cl

17:30 but at least it runs with closure, i'm sure it will further improve

17:31 for cl, its said to be the best solution (free one) available

17:31 Chousuke: in the meantime, you'll have to use a java debugger :)

17:31 danlei: well, at the moment, i'm just playing a bit

17:50 Jedi_Stannis: I'm no java expert, what am I doing wrong here?

17:50 java -cp gorilla-1.0.0.jar de.kotka.socketrepl.SocketRepl

17:50 Gives me a class not found error

17:52 kotarak: java -cp clojure.jar:gorilla-1.0.0.jar de.kotka.socketrepl.SocketRepl

17:54 Jedi_Stannis: thanks

17:55 kotarak: Jedi_Stannis: -cp overrides your CLASSPATH env var, as far as I can tell. But I'm no Java expert either...

17:56 Jedi_Stannis: yeah, as long as it works im happy

17:57 so does each \et run in its own instance now? I used to use \et to change currently running code, it seem slike I can't do that now

17:58 kotarak: \et runs in its own connection, but that is visible in the Repl. Run a (def x 5) with \et and the type x in the Repl and you will get 5. (As long as the buffer with the def and the repl are in the same namespace.)

17:59 Jedi_Stannis: ok, cool

17:59 kotarak: Gorilla tries to be smart and looks for a ns or in-ns call in the buffer.

18:00 In that case it uses the given namespace when evaluating the code.

18:00 The Repl can also do a change with in-ns, but this won't be reflected in the prompt as normal. This will probably change.

18:01 Jedi_Stannis: ok, sounds good

18:01 \me and \m1 are giving me NoMethodError: undefined method 'macro_expand' for Gorilla:Module

18:02 kotarak: huh? Just a sec.

18:02 Lau_of_DK: Chouser: Did you finish work on (source x) ?

18:04 kotarak: Jedi_Stannis: Ok. Obviously I'm stupid. Please have a look in ~/.vim/plugin/gorilla.vim, search for expand_macro and change it to macro_expand. I can remember I wanted to change the name, but somehow this got stuck halfway through. And then I obviously tested the wrong version. I shouldn't release software late in the evening....

18:05 Jedi_Stannis: lol, no problem, it happens

18:05 I'm also having problems with \eb and \ef, they don't seem to be working

18:06 kotarak: No. This is a known limitation for now. One can send only one expression per send, since the prompt after each expression is used for syncronisation.

18:07 Jedi_Stannis: got it

18:07 hmm

18:07 kotarak: So we have to know the number of expressions. This requires a full blown reader. eg. 123"hello":foo are three expressions....

18:07 Jedi_Stannis: right

18:07 you need the reader on both sides?

18:07 kotarak: I need it in Vim to know, how often I have to wait for the prompt.

18:08 Say I send two expression, and wait until the first prompt.

18:08 Then Clojure tries to send more, but Vim doesn't expect it.

18:08 Problem..

18:08 So I have to know "2 Prompts", then it's ok.

18:09 But then again I have to parse the code.... ergo I need a reader...

18:10 Jedi_Stannis: is it possible to somehow modify the socketrepl to let vim know when it should be waiting for more input from it or not instead of having vim just look for the prompt?

18:11 bradbev: Has anybody used JRat with Clojure? Or really, any good profilers?

18:11 kotarak: I could tell the repl to read as much as possible, and send the prompt only at the end.

18:12 But what happens for a connection over a slow line? How does the repl now, that the input is finished?

18:12 Maybe I have to send some special markers. Something like gorilla/start .... gorilla/end

18:13 And catch those in the repl.

18:13 Although I wanted to avoid that.

18:14 It would be more flexible to be able to connect to an arbitrary repl.

18:14 Jedi_Stannis: yeah, it seems like you would need some sort of special repl markers or have a full reader on the vim side

18:14 kotarak: beh.. for either way....

18:15 Maybe the reader would be good, but it's a lot of work.

18:16 Jedi_Stannis: it would be nice if you could just tap into clojure's reader from vim somehow

18:18 what if for \ef at least, you just have it send each form one at a time?

18:20 kotarak: Hmmm.... That would be a possibility. I see no reason, why there should a global :keyword or "string" or something. So for well-behaved buffers, this should be possible.

18:23 bradbev: is anybody working on tools that would expose the JVMTI interface to Clojure?

18:41 AWizzArd: Does anyone else also get a "502 Bad Gateway" for Clojures svn? http://clojure.svn.sourceforge.net/viewvc/clojure/

18:41 kotarak: no, seems to work

18:41 Jedi_Stannis: its working fine for me over here

18:51 gnuvince_: Does proxy create methods or does it just override them?

18:53 Chouser: gnuvince_: overrides existing methods only

18:54 gnuvince_: OK.

18:55 Unless I'm reading wrong, it is not mentionned in the documentation

18:55 Chouser: kotarak: For a browser repl I've used a technique of sending whatever the user has typed so far, and feeding it to read via a StringReader

18:56 kotarak: Chouser: and how do you syncronise?

18:56 Chouser: kotarak: then if I get an Exception message with "EOF while reading", I know the expression's not done yet, and I do no more processing.

18:56 if it fails with some other exception, I report to the user

18:57 kotarak: And how do you handle multiple expressions?

18:57 Chouser: onlyy if the read succeeds do I proceed with the rest of the work

18:57 hm, good question. I bet multiple expressions wouldn't work right.

18:58 I guess I could keep running read until I reach EOF on the StringReader

18:58 kotarak: My main problem is the following: (defn x 5) (defn y 6) => the repl responds with #'user/x Prompt=> #'user/y Prompt=>

18:58 The Vim side uses Prompt=> to check whether the response of the repl is complete.

18:58 Chouser: kotarak: right, I'm not trying to parse the repl's response at all.

18:59 kotarak: I have to. I need to know, when it's finished.

18:59 (not really parsing, but checking for the end)

18:59 Chouser: right, but if you run the string through read first (with an EOF) you'll get an exception if it's not done.

19:00 oh! you need to know if the output from the expression is complete.

19:00 kotarak: yes. but (def x 5) (def y 6) will not give an exception

19:00 yes exactly.

19:00 Chouser: ah, sorry, I don't have that problem because I don't eval on the server. :-/

19:00 kotarak: Do I need to wait for more output, or is it finished?

19:00 Jedi_Stannis: kotarak: can you just parens match to see how many forms there are?

19:01 Chouser: no because the output could be any text.

19:01 kotarak: Jedi_Stannis: you can also type x at the repl and get 5 as a response

19:01 Jedi_Stannis: I meant on the input to know how many prompts to wait for

19:01 kotarak: I need a full-blown reader then.

19:01 Jedi_Stannis: hm right

19:01 kotarak: x is an input

19:01 Chouser: yeah, i bet it would work best to eval some unique sentinel after each expression. I think you already mentioned that.

19:02 kotarak: In files it's rather unlikely. There you will most likely have only () at the toplevel. But not in the repl

19:02 Chouser: I'd like to avoid that. :| But if it's the only way...

19:02 Chouser: doesn't sound too bad to me. this is the repl, after all.

19:03 I'd still run the original through read first, to make sure it's all well-formed before tacking more program text on the end.

19:04 kotarak: Hmmm.... I could define a namespace gorilla with the end function. It just prints "GORILLA END". And after each send, I simply call it (gorilla/end). And filter it transparently for the user. That wouldn't need modifications to the repl.

19:12 Jedi_Stannis, Chouser: thanks for the ideas. I will give that a try tomorrow.

19:13 Jedi_Stannis: no problem, thanks for working on gorilla

19:13 Chousuke: hmm

19:14 * Chousuke tries vimpulse on emacs

19:15 Chousuke: I'm not exactly a grandmaster of either editor, so maybe I could get the best of both...

19:45 mmcgrana: Hi all, I'm trying to use the latest clojure head but am getting a weird error when running ant:

19:46 2008-11-15 19:42:53.509 java[20155:613] Apple AWT Startup Exception : *** -[NSCFArray insertObject:atIndex:]: attempt to insert nil

19:46 Chousuke: hmm

19:46 that doesn't happen on my system

19:46 mmcgrana: I've used recent clojure versions and post aot versions ok, it seems to have stopped working with recent precompile core stuff

19:46 Chousuke: which java version are you using?

19:46 mmcgrana: 1.6

19:46 Chousuke: try 1.5

19:47 mmcgrana: mac os x leopard

19:47 Chousuke: I think the GUI stuff is broken in 1.6

19:48 mmcgrana: hm ok is there an easy way to tell ant to use 1.5 or would i have to switch the java bin symlinks to 1.5

19:48 Chousuke: and clojure precompiles things that import some GUI stuff which apparently requires some special GUI interaction on OS X

19:48 I don't know. :/

19:52 mmcgrana: ok well thanks for the thoughts I'm just going to temporarily revert to 1.5 to see if i can get it working

19:53 Chousuke: mmcgrana: you could also edit the precompile.clj script and remove clojure.inspector from the precompiled stuff

19:53 mmcgrana: it's the only one that requires GUI stuff

19:53 mmcgrana: o nice yeah i'll try that

19:54 Chousuke: though if you do that you won't be able to use it, as the jar will only contain the precompiled things

19:54 mmcgrana: right, np

19:55 Chousuke: to work around *that*, remove the comment marks form the line <!-- <fileset dir="${cljsrc}" includes="**/*.clj"/> --> in build.xml :P

19:55 that'll include non-precompiled stuff as well

19:55 clojure will prefer precompiled classes, so that shouldn't be a problem

19:55 your jar will just be a bit larger

19:58 mmcgrana: ok that worked (editing precompile.clj), thanks Chousuke, I have slightly better startup time now

19:59 Chousuke: :)

22:59 djkthx: i'm trying to compile a file in emacs/slime with a namespace declaration

22:59 (clojure/ns mylib.nifty-funs)

22:59 when i try

22:59 it throws this error

22:59 -+ Errors (2) |-- java.lang.Exception: No such namespace: clojure (niftyfuns.clj:1) `-- java.lang.Exception: No such namespace: clojure

23:00 hiredman: clojure.core

23:00 the clojure stuff got moved into clojure.core to avoid single segment namespaces

23:01 djkthx: ahh

Logging service provided by n01se.net