#clojure log - Sep 29 2008

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

8:18 pjb3: rhickey: Are we going to be seeing tonight's presentation as the next episode on Clojure TV? :)

10:42 Chouser: (gen-and-load-class 'Foo)

10:42 Is there any value in that, when no package name is given?

10:43 I can't refer to Foo from within Clojure, apparently. Is that a weakness of Clojure, or is it just completely broken to gen a class with no package?

10:44 abrooks: Chouser: Ah, that happens with gen-class as well as gen-interface?

10:45 Chouser: it appears to.

11:31 StartsWithK: what is a real difference between `(args..) and '(args...)?

11:32 ozzilee: StartsWithK: One is sugar for (quasiquote args), the other is sugar for (quote args). Except Clojure doesn't seem to actually have quote and quasiquote macros...

11:33 StartsWithK: i created some macros up to now, but they were very simple and i copied parts of them from what i found on the net

11:34 now i would like to create one complex macro and im stuck with this kind of basics

11:34 what should quasiquote do?

11:34 ozzilee: StartsWithK: Ah, gotcha. The difference is, ` allows you to use ~ to unquote parts of forms.

11:34 For example, if I say (def foo "foo"), '(foo bar) gives me a list of two symbols, foo and bar.

11:35 However, `(~foo bar) gives me the string "foo" and the symbol bar.

11:35 A macro returns a list of the symbols that should be inserted into the code. With `, you can insert the arguments to the macro using ~.

11:36 (defmacro macro-println [arg] `(println ~arg))

11:36 (macro-println "foo") will insert (println "foo") into your code.

11:37 StartsWithK: what if i have [& args] and would like to kreate separate println for each arg, but using loop construct?

11:37 danlarkin: ozzilee: so "," in common lisp becomes ~ in clojure?

11:38 ozzilee: danlarkin: Yup. "," is treated as whitespace.

11:38 Chouser: (quote foo) works in clojure

11:38 ozzilee: Chouser: Oh, you're right. quote by itself didn't evaluate, my mistake.

11:39 Chouser: StartsWithK: it's all about building the data structure that you want clojure to eval.

11:39 danlarkin: ozzilee: do you know why ~ was chosen instead of ,? To ease the transition from lists separated with commas?

11:39 ozzilee: danlarkin: Exactly that, I beliebe.

11:40 *believe.

11:40 Chouser: StartsWithK: it helps if you start by writing out an example call to your macro, and the exact code you want your macro to produce in that case.

11:40 then start working on your macro, using (macroexpand ...) to check that you're producing what you want.

11:41 StartsWithK: Chouser: yes, i tried to create smaller part, i have some macros that demonstrate different parts of it, but i cant make them work as a one

11:41 http://pastebin.com/d21addbfb

11:41 this is what i tried for generating code with loop, it fails

11:42 Chouser: yeah, the m# syntax is likely to be insufficient for you

11:42 that works ok for simple macros, but in more complicated ones it often just makes things harder. You can only use it in a single level of `()

11:43 instead, try (let [m (gensym) parts (gensym)] ...)

11:44 wwmorgan: in the sample you pasted, the m# forms aren't inside a macro quote

11:44 StartsWithK: hmm, how will that work for loop? (loop [m (gensym)]).. but where do i assoc

11:45 wwmorgan: i tried it as described at http://www.greenwave-solutions.com/blog/files/20-Days-of-Clojure-Day-19.html

11:46 wwmorgan: StartsWithK: you're right. that does work

11:46 Chouser: I think you're getting confused as to which bits of code are working to build your resulting data, and which bits of code are *in* your resulting data. This is a very common problem when writing macros.

11:47 StartsWithK: your right, it is confusing, at least now when im just starting

11:49 i looked how (clojure/doto) and (clojure/proxy) macros work, and i'm lost

11:49 wwmorgan: StartsWithK: I think this will do what you're trying to do http://pastebin.com/m4f337152

11:50 StartsWithK: wwmorgan: that could work i think

11:51 http://pastebin.com/d65f1b7dd

11:52 * ozzilee needs to study up on macros, apparently.

11:52 StartsWithK: original clojure/doto creates duplicate (let), one outside syntax quotes and then again one inside them

11:53 this way it can evaluate x form before entering macro body?

11:54 Chouser: StartsWithK: It needs two because the outer one is to define a local xs which is only used when the macro is running (at compile time) *not* in the code that gets produced.

11:54 The second let will actually show up in the output

11:54 That second let is the one you see if you do: (macroexpand-1 '(doto foo bar))

11:55 StartsWithK: compile time = macro expansion time?

12:44 danlarkin: is there a clojure equivalent for the common lisp #' ?

12:44 ie to get a function literal

12:46 wwmorgan: danlarkin: Clojure is a lisp-1. Functions belong to the same namespace as non-functions

12:46 danlarkin: ah ha

12:47 wwmorgan: thanks

13:05 ozzilee: Has anyone tried running Clojure on the Jam VM?

13:08 achim_p: hi!

13:11 rhickey: i uploaded my first attempt at implementing jmap along with some examples to the group's file area

13:11 http://groups.google.com/group/clojure/web/jmap.diff

13:11 http://groups.google.com/group/clojure/web/jmap-examples.clj

13:11 in case you consider including it: the CA is on its way. let me know if it needs some more work.

13:12 leafw: can all symbols declared in an interface be imported into the current namespace, with a namespace command?

13:13 something like (import-all ij.measure.Measurements current-namespace)

13:15 achim_p: leafw: you'd like all methods of Measurements to become functions in current-namespace? i don't think that's possible out of the box, but probably not much work (via memfn and reflection)

13:16 leafw: well, actually all fields. The interface only has fields.

13:16 yes I could do a macro ... just wondering whether it existed.

14:32 need rescue from loop-oriented mindset ...

14:33 I have two arrays of equal length, of ints, which I have to compare: make the log10 of both values; when both values are identical, set a 0, when different, set a 1 or a -1 (depending on which one is larger)

14:34 can one 'reduce' over two lists?

14:35 danlarkin: you can zip! At least it's zip in python... let me see what clojure calls it again...

14:38 wwmorgan: leafw: you might try this (map compare (map log10 as) (map log10 bs))

14:38 leafw: interesting

14:39 thank you wwmorgan

14:39 really neat

14:39 (doc compare), didn't know about this one

14:46 can't map Math/log10, always fails. (memfn Math/log10) also fails.

14:49 also: weird bug: this works: (into-array '(1.01 2.0 3.0)) .. but this does NOT work: (into-array '(1.01 2 3.0)) --- note the '2' instead of '2.0'

14:50 abrooks: leafw: (map #(.log10 Math %) [1 2 3])

14:50 Or, if you prefer #(. Math log10 %)

14:51 leafw: abrooks: it's a bit overkill to make a function to wrap log10 .. can't a java method be mapped as if it was a function?

14:51 abrooks: I don't know if menfn would work with ".".

14:51 I think . is builtin syntax.

14:51 * abrooks checks

14:52 danlarkin: ah ha! found it... interleave is the function I was trying to remember

14:52 leafw: the dot should work

14:52 but it's not desired anymore for static fields and methods

15:02 Chouser: or #(Math/log10 %) -- something like that is indeed necessary to get a clojure function from a java method.

15:03 danlarkin: what is the % doing in this context? is it part of the java math library? or some syntax

15:03 leafw: danlarkin: argument placement

15:03 yo ucn use %1 %2 %3 ...

15:04 Chouser: #( ) with a % in it is just a shortcut for (fn [...] ...)

15:04 as leafw is describing. :-)

15:04 leafw: (map #(/ (+ %2 10) %1)) '(1 2 3 4))

15:04 sorry

15:04 that took two args, needed a reduce

15:04 xD

15:04 not a map.

15:04 danlarkin: I see

15:06 thanks

15:06 leafw: (reduce #(/ (+ %2 10) %1) '(1 2 3 4))

15:06 sure.

15:07 danlarkin: I simplified it to help me understand :-D: (def a #(/ %1 %2)) (a 4 5)

15:07 leafw: I love these regex-args functions

15:08 all cruft is gone, just write what you mean.

17:13 danlarkin: I have a question about identity... http://paste.lisp.org/display/67632

17:14 why does the last form return false?

17:16 leafw: not the same type?

17:16 but then the 3rd should be false too

17:16 danlarkin: right

17:16 leafw: an ordering problem?

17:17 (seq l) may have reverted the order of the elements

17:17 wwmorgan: they don't refer to the same object

17:17 identical? is akin to java =

17:17 leafw: you mean java ==

17:17 wwmorgan: yes

17:17 leafw: wwmorgan: but then the 3rd identity should fail as well

17:18 Chouser: this is really subtle, but I think I have it.

17:18 leafw: sorry 3rd line

17:18 ozzilee: leafw: My guess is because (seq l) just returns l unaltered

17:18 Chouser: PersistentList implements ISeq, so when you do (seq l), it just returned itself

17:19 leafw: ozzilee: yoru guess is, according, to Chouser, right.

17:19 brb

17:19 Chouser: so your first "identical?" is comparing your original list with itself -- true.

17:19 ozzilee: (identical? l '(a b c)) is illuminating

17:20 leafw: indeed.

17:20 danlarkin: ozzilee: as is (identical? '(a b c) '(a b c))

17:20 ozzilee: danlarkin: Indeed.

17:20 Chouser: in your second "identical?" you create two different PersistentList objects -- false

17:20 danlarkin: that answers my question, thanks everyone

17:20 Chouser: you almost never want to use "identical?", you want "="

17:26 StartsWithK: lisppaste8: help

17:26 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

17:28 StartsWithK pasted "Extended doto" at http://paste.lisp.org/display/67633

17:29 stuarthalloway: I have posted a spike for ClojureCheck on the mailing list. If anybody here would like to discuss in real time I'd love feedback.

17:50 danlarkin: eek... the series of invoke definitions at the bottom of src/jvm/clojure/lang/Ref.java is an interesting way to do things

18:54 wwmorgan: I wrote a script in clojure that takes a clojure source file as input and uses the functions pr and read to copy the code to a new file. Somehow, the resulting output code is 10 times slower than the input on our tests. Any ideas before I go chasing this one?

21:10 metasyntax: hi, I just happened to find Clojure and it looks interesting

21:10 and perhaps I just missed it on the site but

21:10 is there a way to load Clojure code and call Clojure-defined functions from Java?

21:23 danlarkin: metasyntax: you can use some of the data structures but not the code, I don't believe

21:49 metasyntax: danlarkin: http://en.wikibooks.org/wiki/Clojure_Programming#Invoking_Clojure_from_Java

21:50 danlarkin: seems like it is possible; at least this example works, cool

21:50 danlarkin: metasyntax: yeah I guess you're right, very cool!

22:14 (defn [] (first (foo)))

22:14 it surprises me that that form throws an exception

22:14 oh

22:14 wait

22:14 Chouser: :-)

22:14 there it is.

22:15 danlarkin: (defn bam [] (first (foo)))

22:15 there we go.. that's what surprises me

22:15 why does foo need to be defined for me to define bam

22:15 Chouser: because it gets resolved and compiled into bytecode

22:16 it's faster to resolve at compile time and let the runtime be a direct java method call.

22:16 danlarkin: :-/ dtable lookups aren't that slow

22:18 Chouser: compared to an inline-able java call?

22:19 danlarkin: profiling objc shows a fraction of time spent in method lookup

22:20 can I define a function but delay compilation until I try to use it?

22:20 Chouser: you can def the var and re-def (or use thread binding) to change the value later.

22:23 danlarkin: hard to get used to knowing lisp, scheme and python

22:25 Chouser: I've done quite a bit of python and haven't had too much trouble in real programs with this

22:26 you'll find that (after startup cost) clojure runs quite a bit faster than python.

22:26 albino: the startup time is the problem though

22:26 for one off scripts

22:27 Chouser: yeah, it's something to work on. I've heard of a couple possible solutions knocking around. Nothing concrete yet, afaik.

22:27 walters: it won't be that way forever; there are some not too hard things to fix in openjdk to improve startup time

22:27 albino: walters: like what?

22:28 walters: albino: using an mmap cache for system installed classfiles instead of unzipping and reverifying every jar would help...

22:29 albino: anyone tried to run clojure on top of nailgun? http://www.martiansoftware.com/nailgun/

22:41 I think my struggle with immutability is harming my motivation for learning factor

22:41 any advice on how to overcome that?

22:41 err clojure

22:41 sorry, I did mean clojure

22:42 arohner: what kinds of struggles are you having?

22:42 Chouser: I'd recommend starting with small problems and work up. I enjoyed projecteuler.net

22:43 danlarkin: I have another newbie question... I see all the clojure source in clojure-contrib using named imports ie (import '(java.util.logging Logger Level)) -- And I see java source using iport java.util.logging.* -- can I do the latter in clojure? Is there a reason (other than namespace) that I wouldn't want to?

22:44 /s/iport/import

22:44 arohner: I don't believe there is an import * in clojure

22:46 http://groups.google.com/group/clojure/msg/ddca7ec56ea8b51f

22:47 danlarkin: arohner: perfect answer, thanks :D

22:49 Chouser: albino: don't give up. Even if you end up ditching clojure, learning to work with immutable data structures will help you write better code in any language.

22:49 IMHO. :-)

22:55 blackdog: i haven't tried this, but it made a big diff to jruby starup time

22:55 Here's another from me, which I've posted about previously:

22:55 -XX:bootclasspath and friends. JRuby is a Ruby implementation, which

22:55 means it needs to perform reasonably well as a command-line tool.

22:56 Typical JVM startup precludes fast command-line startup, but it turns

22:56 out a large portion of that time is spent verifying bytecode.

22:56 bootclasspath allows JRuby and its dependencies to skip verification,

22:56 which in our case improved startup time almost 3X, putting it

22:56 comfortably under 0.5s on OS X. That was a *huge* find, akin to a silver

22:56 bullet for startup speed.

22:56 that's from Charles Nutter to the jvm list

22:57 Chouser: interesting!

23:02 blackdog: actually the thread has a lot of good info http://groups.google.com/group/jvm-languages/browse_thread/thread/6e12cf1dd09ae40e/34feca136e728807?lnk=gst&q=startup+performance#34feca136e728807

23:06 Chouser: Unrecognized VM option 'bootclasspath'

23:06 blackdog: java -X

23:10 Chouser: Hm, I'll have to mess with it tomorrow. G'night folks.

23:11 blackdog: ciao

Logging service provided by n01se.net