2008-09-29
| 08: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 | Chouser | Is there any value in that, when no package name is given? |
| 10:43 | Chouser | 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 | StartsWithK | now i would like to create one complex macro and im stuck with this kind of basics |
| 11:34 | StartsWithK | what should quasiquote do? |
| 11:34 | ozzilee | StartsWithK: Ah, gotcha. The difference is, ` allows you to use ~ to unquote parts of forms. |
| 11:34 | ozzilee | For example, if I say (def foo "foo"), '(foo bar) gives me a list of two symbols, foo and bar. |
| 11:35 | ozzilee | However, `(~foo bar) gives me the string "foo" and the symbol bar. |
| 11:35 | ozzilee | 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 | ozzilee | (defmacro macro-println [arg] `(println ~arg)) |
| 11:36 | ozzilee | (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 | ozzilee | *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 | Chouser | 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 | StartsWithK | http://pastebin.com/d21addbfb |
| 11:41 | StartsWithK | 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 | Chouser | 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 | Chouser | 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 | StartsWithK | 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 | StartsWithK | 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 | StartsWithK | http://pastebin.com/d65f1b7dd |
| 11:52 | StartsWithK | original clojure/doto creates duplicate (let), one outside syntax quotes and then again one inside them |
| 11:53 | StartsWithK | 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 | Chouser | The second let will actually show up in the output |
| 11:54 | Chouser | 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 | danlarkin | 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 | danlarkin | wwmorgan: thanks |
| 13:05 | ozzilee | Has anyone tried running Clojure on the Jam VM? |
| 13:08 | achim_p | hi! |
| 13:11 | achim_p | rhickey: i uploaded my first attempt at implementing jmap along with some examples to the group's file area |
| 13:11 | achim_p | http://groups.google.com/group/clojure/web/jmap.diff |
| 13:11 | achim_p | http://groups.google.com/group/clojure/web/jmap-examples.clj |
| 13:11 | achim_p | 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 | leafw | 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 | leafw | yes I could do a macro ... just wondering whether it existed. |
| 14:32 | leafw | need rescue from loop-oriented mindset ... |
| 14:33 | leafw | 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 | leafw | 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 | leafw | thank you wwmorgan |
| 14:39 | leafw | really neat |
| 14:39 | leafw | (doc compare), didn't know about this one |
| 14:46 | leafw | can't map Math/log10, always fails. (memfn Math/log10) also fails. |
| 14:49 | leafw | 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 | abrooks | 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 | abrooks | I think . is builtin syntax. |
| 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 | leafw | 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 | leafw | yo ucn use %1 %2 %3 ... |
| 15:04 | Chouser | #( ) with a % in it is just a shortcut for (fn [...] ...) |
| 15:04 | Chouser | as leafw is describing. :-) |
| 15:04 | leafw | (map #(/ (+ %2 10) %1)) '(1 2 3 4)) |
| 15:04 | leafw | sorry |
| 15:04 | leafw | that took two args, needed a reduce |
| 15:04 | leafw | xD |
| 15:04 | leafw | not a map. |
| 15:04 | danlarkin | I see |
| 15:06 | danlarkin | thanks |
| 15:06 | leafw | (reduce #(/ (+ %2 10) %1) '(1 2 3 4)) |
| 15:06 | leafw | 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 | leafw | 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 | danlarkin | why does the last form return false? |
| 17:16 | leafw | not the same type? |
| 17:16 | leafw | but then the 3rd should be false too |
| 17:16 | danlarkin | right |
| 17:16 | leafw | an ordering problem? |
| 17:17 | leafw | (seq l) may have reverted the order of the elements |
| 17:17 | wwmorgan | they don't refer to the same object |
| 17:17 | wwmorgan | 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 | leafw | 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 | lisppaste8 | 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 | metasyntax | and perhaps I just missed it on the site but |
| 21:10 | metasyntax | 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 | metasyntax | 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 | danlarkin | (defn [] (first (foo))) |
| 22:14 | danlarkin | it surprises me that that form throws an exception |
| 22:14 | danlarkin | oh |
| 22:14 | danlarkin | wait |
| 22:14 | Chouser | :-) |
| 22:14 | Chouser | there it is. |
| 22:15 | danlarkin | (defn bam [] (first (foo))) |
| 22:15 | danlarkin | there we go.. that's what surprises me |
| 22:15 | danlarkin | 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 | Chouser | 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 | danlarkin | 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 | Chouser | 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 | albino | 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 | albino | I think my struggle with immutability is harming my motivation for learning factor |
| 22:41 | albino | any advice on how to overcome that? |
| 22:41 | albino | err clojure |
| 22:41 | albino | 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 | danlarkin | /s/iport/import |
| 22:44 | arohner | I don't believe there is an import * in clojure |
| 22:46 | arohner | 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 | Chouser | IMHO. :-) |
| 22:55 | blackdog | i haven't tried this, but it made a big diff to jruby starup time |
| 22:55 | blackdog | Here's another from me, which I've posted about previously: |
| 22:55 | blackdog | -XX:bootclasspath and friends. JRuby is a Ruby implementation, which |
| 22:55 | blackdog | means it needs to perform reasonably well as a command-line tool. |
| 22:56 | blackdog | Typical JVM startup precludes fast command-line startup, but it turns |
| 22:56 | blackdog | out a large portion of that time is spent verifying bytecode. |
| 22:56 | blackdog | bootclasspath allows JRuby and its dependencies to skip verification, |
| 22:56 | blackdog | which in our case improved startup time almost 3X, putting it |
| 22:56 | blackdog | comfortably under 0.5s on OS X. That was a *huge* find, akin to a silver |
| 22:56 | blackdog | bullet for startup speed. |
| 22:56 | blackdog | 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 |