Re: Patch: callable defstruct (PersistentStructMap$Def extends AFn)
On Nov 6, 9:19 am, Chouser [EMAIL PROTECTED] wrote: On Wed, Nov 5, 2008 at 12:10 AM, Chouser [EMAIL PROTECTED] wrote: The attached patch allows: user= (point 42 11) {:x 42, :y 11} Seems like a very nice enhancement to me. It would make the code more terse. Parth The right tool for the job makes all the difference. Attached is a much simpler patch to accomplish the same thing. --Chouser structmap-def-extends-restfn.patch 1KViewDownload --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
sort with custom comparator
The doc of sort states that you need to implement java.util.Comparator in order to use custom sorting. Why then does this not cause any error? user= (defn my-comp [x y] (cond ( x y) 1 (= x y) 0 :else -1)) #=(var user/my-comp) user= (sort [5 3 1 2]) (1 2 3 5) user= (sort my-comp [5 3 1 2]) (5 3 2 1) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: sort with custom comparator
To answer my own question - AFn.java implements java.util.Comparator. On Nov 6, 10:18 am, [EMAIL PROTECTED] [EMAIL PROTECTED] wrote: The doc of sort states that you need to implement java.util.Comparator in order to use custom sorting. Why then does this not cause any error? user= (defn my-comp [x y] (cond ( x y) 1 (= x y) 0 :else -1)) #=(var user/my-comp) user= (sort [5 3 1 2]) (1 2 3 5) user= (sort my-comp [5 3 1 2]) (5 3 2 1) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: A trivial question about type and class
Thanks~ clojure.lang.PersistentHashMap works~ :) But I feel something is strange.. See next code, especially arrowed line. user clojure.lang.PersistentHashMap #=clojure.lang.PersistentHashMap user (= (class {:a 1 :b 2}) clojure.lang.PersistentHashMap) true user (= (class {}) clojure.lang.PersistentHashMap) true user (= (class {:a 1 :b 2}) (class {})) true user (= (class {:a 1}) (class {})) ;; = false user (= (class {:a 1}) clojure.lang.PersistentHashMap) ;; = false user (= (class (hash-map :a 1)) clojure.lang.PersistentHashMap) true user (= (class (hash-map :a 1)) (class {:a 1})) ;; = false user (:a {:a 1}) 1 Is {:a 1} not a hash-map? It seems that there is some inconsistency... On 11월6일, 오후4시27분, Michael Wood [EMAIL PROTECTED] wrote: On Thu, Nov 6, 2008 at 8:25 AM, Chanwoo Yoo [EMAIL PROTECTED] wrote: Hi all. In Stuart's book - Programming Clojure, there is a multi method like following: (defmulti blank? class) (defmethod blank? String [s] (every? #{\space} s)) (defmethod blank? nil [_] true) After reading the method, I was curious about type or class of native data structures of Clojure. So I typed next code in slime. Hmm.. I didn't understand why classes of {:a 1} and {} are not same. Like Stuart's code, to make multi method branching based on clojure data structure type(map, vector, list), what symbol should I use? (Like String for string, Is there a Map for {:a 1}? I tried PersistentHashMap, HashMap, Map, so on.. I didn't find it.) I think what you're looking for is clojure.lang.PersistentHashMap instead of just PersistentHashMap. user= String java.lang.String user= PersistentHashMap java.lang.Exception: Unable to resolve symbol: PersistentHashMap in this context [...] user= clojure.lang.PersistentHashMap clojure.lang.PersistentHashMap user= I don't know much about Clojure, though, so I suspect there is better advice than the above :) user (= (class abc) String) true user (class {:a 1 :b 2}) #=clojure.lang.PersistentHashMap user (class {}) #=clojure.lang.PersistentHashMap user (= (class {:a 1}) (class {})) false user (= (class {:a 1}) (class {:b 2})) true That seems rather strange to me too. -- Michael Wood [EMAIL PROTECTED] --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: A trivial question about type and class
Hi, On 6 Nov., 13:30, Chanwoo Yoo [EMAIL PROTECTED] wrote: Is {:a 1} not a hash-map? It seems that there is some inconsistency... Clojure holds promises about the interface and the performance characteristics of the provided functions. In general Clojure is a lot about abstract interfaces. The underlying thing may change as necessary to provide the best implementation for the specific case. An array map may be good for maps with a very small number of entries, but inappropriate for maps with a big number of entries. Since Clojure only promises the interface, it's free to decide that assoc should now return a converted map for performance reasons. At least this is the impression I got from Rich's talk at - I think - the Boston Lisp Group. I think he mentioned something like this. Please correct me if I'm wrong. Sincerely Meikel --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: sort with custom comparator
On Nov 6, 2008, at 7:05 AM, [EMAIL PROTECTED] wrote: On Nov 6, 12:43 pm, Rich Hickey [EMAIL PROTECTED] wrote: On Nov 6, 5:23 am, [EMAIL PROTECTED] [EMAIL PROTECTED] wrote: To answer my own question - AFn.java implements java.util.Comparator. That is documented here: http://clojure.org/special_forms IFns implement the Java Callable, Runnable and Comparator interfaces. Pedantically speaking IFn extends Callable and Runnable, and AFn implements IFn and additionally Comparator (and Serializable). I was checking IFn.java first but couldn't see the Comparator interface being listed there which made me writing my initial post. Now reading the sentence above I wonder if it counts as a bug that IFn doesn't extend from Comparator? It's a documentation bug - it should say fns and not IFns, and now does. Rich --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: sort with custom comparator
On Thu, Nov 6, 2008 at 7:05 AM, [EMAIL PROTECTED] [EMAIL PROTECTED] wrote: I was checking IFn.java first but couldn't see the Comparator interface being listed there which made me writing my initial post. This is a more convenient and reliable way to check inheritance: (ancestors (class #())) Cleaned up output: #{#=clojure.lang.AFn #=clojure.lang.IFn #=clojure.lang.IObj #=clojure.lang.Obj #=java.io.Serializable #=java.lang.Object #=java.lang.Runnable #=java.util.Comparator #=java.util.concurrent.Callable} --Chouser --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: prefer-method print-method problem
On Thu, Nov 6, 2008 at 7:53 AM, MikeM [EMAIL PROTECTED] wrote: But when I try to prefer this: (prefer-method print-method clojure.lang.PersistentTreeMap clojure.lang.IPersistentMap) You don't need this, because PersistentTreeMap is already a more specific type than IPersistentMap -- you get the right behavior by default: user= (sorted-map 1 2 3 4 5 6) #=(sorted-map 1 2,3 4,5 6) That still doesn't get read in right, and I'm not sure why. But it seems to be printing ok. --Chouser --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: A trivial question about type and class
I really appreciate your answer... and exciting 'Clojure', Rich. :) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: A trivial question about type and class
On Nov 6, 8:27 am, Michael Wood [EMAIL PROTECTED] wrote: On Thu, Nov 6, 2008 at 8:25 AM, Chanwoo Yoo [EMAIL PROTECTED] wrote: Hi all. In Stuart's book - Programming Clojure, there is a multi method like following: (defmulti blank? class) (defmethod blank? String [s] (every? #{\space} s)) (defmethod blank? nil [_] true) After reading the method, I was curious about type or class of native data structures of Clojure. So I typed next code in slime. Hmm.. I didn't understand why classes of {:a 1} and {} are not same. Like Stuart's code, to make multi method branching based on clojure data structure type(map, vector, list), what symbol should I use? (Like String for string, Is there a Map for {:a 1}? I tried PersistentHashMap, HashMap, Map, so on.. I didn't find it.) I think what you're looking for is clojure.lang.PersistentHashMap instead of just PersistentHashMap. user= String java.lang.String user= PersistentHashMap java.lang.Exception: Unable to resolve symbol: PersistentHashMap in this context [...] user= clojure.lang.PersistentHashMap clojure.lang.PersistentHashMap user= I don't know much about Clojure, though, so I suspect there is better advice than the above :) user (= (class abc) String) true user (class {:a 1 :b 2}) #=clojure.lang.PersistentHashMap user (class {}) #=clojure.lang.PersistentHashMap user (= (class {:a 1}) (class {})) false user (= (class {:a 1}) (class {:b 2})) true That seems rather strange to me too. -- Michael Wood [EMAIL PROTECTED] On Nov 6, 8:27 am, Michael Wood [EMAIL PROTECTED] wrote: On Thu, Nov 6, 2008 at 8:25 AM, Chanwoo Yoo [EMAIL PROTECTED] wrote: Hi all. In Stuart's book - Programming Clojure, there is a multi method like following: (defmulti blank? class) (defmethod blank? String [s] (every? #{\space} s)) (defmethod blank? nil [_] true) After reading the method, I was curious about type or class of native data structures of Clojure. So I typed next code in slime. Hmm.. I didn't understand why classes of {:a 1} and {} are not same. Like Stuart's code, to make multi method branching based on clojure data structure type(map, vector, list), what symbol should I use? (Like String for string, Is there a Map for {:a 1}? I tried PersistentHashMap, HashMap, Map, so on.. I didn't find it.) I think what you're looking for is clojure.lang.PersistentHashMap instead of just PersistentHashMap. user= String java.lang.String user= PersistentHashMap java.lang.Exception: Unable to resolve symbol: PersistentHashMap in this context [...] user= clojure.lang.PersistentHashMap clojure.lang.PersistentHashMap user= I don't know much about Clojure, though, so I suspect there is better advice than the above :) If you are just playing or if the class is only used once in your file/ namespace then this is absolutely okay (clojure does this in boot.clj) :). Or you type (import '(clojure.lang PersistentHasMap)), or (ns my-namespace (:import (clojure.lang PersistentHashMap))) on top of your file. user (= (class abc) String) true user (class {:a 1 :b 2}) #=clojure.lang.PersistentHashMap user (class {}) #=clojure.lang.PersistentHashMap user (= (class {:a 1}) (class {})) false user (= (class {:a 1}) (class {:b 2})) true That seems rather strange to me too. This is a reader optimization. For very short hashmaps (currently 1 element), the clojure reader uses a clojure.lang.PersistentArrayMap instead of a full fledged HashMap. The reader does this because he knows that this map ({:a 1}) will only be constructed with one MapEntry. user (= (class (into {} '([:a 1]))) (class {})) true Here the reader doesn't see any literal maps and (into {} '([:a 1])) evals to a PersistentHashMap with one MapEntry. Multimethods use the isa? function for dispatch, so to dispatch on a Map type in general, one would use a java.util.Map or a clojure.lang.IPersistentMap as the dispatch-value. user (and (isa? (class {}) java.util.Map) (isa? (class {:a 1}) java.util.Map)) true There is also a similar optimization for clojure vectors. They are constructed as c.l.LazilyPersistentVector which is basically a wrapper arround a java array. Once you conj onto them, they turn into a c.l.PersistentVector. user (let [v [1 2]] [(class v) (class (conj v 3))]) [#=clojure.lang.LazilyPersistentVector #=clojure.lang.PersistentVector] --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
prefer-method print-method problem
I would like to print sorted maps readably (otherwise my sorted maps when printed and read back get turned into the default map), so I tried this: (defmethod print-method clojure.lang.PersistentTreeMap [o, #^java.io.Writer w] (let [eprint (fn eprint [e sep?] (do (print-method (key e) w) (.write w ) (print-method (val e) w) (if sep? (.write w ,) )))] (.write w (if *print-readably* #=(sorted-map {)) (loop [s (seq o)] (if (rest s) (do (eprint (first s) true) (recur (rest s))) (eprint (first s) nil))) (.write w (if *print-readably* ) } But when I try to prefer this: (prefer-method print-method clojure.lang.PersistentTreeMap clojure.lang.IPersistentMap) I get an exception because clojure.lang.IPersistentMap is already preferred to clojure.lang.PersistentTreeMap. Questions: Where does the preference for IPersistentMap come from? Is it from the following in boot.clj: (prefer-method print-method clojure.lang.IPersistentMap java.util.Map) since PersistentTreeMap is a java.util.Map? Is there a work-around to allow what I'm trying to do? Can MultiFn be changed to allow inspection of the preferTable? I'm thinking something like (get-prefers multifn) which would return the preferTable to help with diagnosing problems such as the above. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: A trivial question about type and class
Aha, I'm sorry for my laziness and spamming. {:a 1} is not a hash-map. I guess there is some reason of performance about this... Anyway, as mac pointed out, dispatching based on types will be inappropriate to clojure data structures. Thank you mac for the thread link~ user (class {:a 1}) #=clojure.lang.PersistentArrayMap On 11월6일, 오후9시22분, Chanwoo Yoo [EMAIL PROTECTED] wrote: Thanks~ clojure.lang.PersistentHashMap works~ :) But I feel something is strange.. See next code, especially arrowed line. user clojure.lang.PersistentHashMap #=clojure.lang.PersistentHashMap user (= (class {:a 1 :b 2}) clojure.lang.PersistentHashMap) true user (= (class {}) clojure.lang.PersistentHashMap) true user (= (class {:a 1 :b 2}) (class {})) true user (= (class {:a 1}) (class {})) ;; = false user (= (class {:a 1}) clojure.lang.PersistentHashMap) ;; = false user (= (class (hash-map :a 1)) clojure.lang.PersistentHashMap) true user (= (class (hash-map :a 1)) (class {:a 1})) ;; = false user (:a {:a 1}) 1 Is {:a 1} not a hash-map? It seems that there is some inconsistency... On 11월6일, 오후4시27분, Michael Wood [EMAIL PROTECTED] wrote: On Thu, Nov 6, 2008 at 8:25 AM, Chanwoo Yoo [EMAIL PROTECTED] wrote: Hi all. In Stuart's book - Programming Clojure, there is a multi method like following: (defmulti blank? class) (defmethod blank? String [s] (every? #{\space} s)) (defmethod blank? nil [_] true) After reading the method, I was curious about type or class of native data structures of Clojure. So I typed next code in slime. Hmm.. I didn't understand why classes of {:a 1} and {} are not same. Like Stuart's code, to make multi method branching based on clojure data structure type(map, vector, list), what symbol should I use? (Like String for string, Is there a Map for {:a 1}? I tried PersistentHashMap, HashMap, Map, so on.. I didn't find it.) I think what you're looking for is clojure.lang.PersistentHashMap instead of just PersistentHashMap. user= String java.lang.String user= PersistentHashMap java.lang.Exception: Unable to resolve symbol: PersistentHashMap in this context [...] user= clojure.lang.PersistentHashMap clojure.lang.PersistentHashMap user= I don't know much about Clojure, though, so I suspect there is better advice than the above :) user (= (class abc) String) true user (class {:a 1 :b 2}) #=clojure.lang.PersistentHashMap user (class {}) #=clojure.lang.PersistentHashMap user (= (class {:a 1}) (class {})) false user (= (class {:a 1}) (class {:b 2})) true That seems rather strange to me too. -- Michael Wood [EMAIL PROTECTED] --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: A trivial question about type and class
On Nov 6, 7:50 am, mb [EMAIL PROTECTED] wrote: Hi, On 6 Nov., 13:30, Chanwoo Yoo [EMAIL PROTECTED] wrote: Is {:a 1} not a hash-map? It seems that there is some inconsistency... Clojure holds promises about the interface and the performance characteristics of the provided functions. In general Clojure is a lot about abstract interfaces. The underlying thing may change as necessary to provide the best implementation for the specific case. An array map may be good for maps with a very small number of entries, but inappropriate for maps with a big number of entries. Since Clojure only promises the interface, it's free to decide that assoc should now return a converted map for performance reasons. At least this is the impression I got from Rich's talk at - I think - the Boston Lisp Group. I think he mentioned something like this. Please correct me if I'm wrong. You are right - this is the correct answer to the question. Clojure is about programming to abstractions, among other things. So you don't want to rely on the exact concrete types of things, but rather the interfaces they implement. There are many useful interfaces in Clojure. Chouser put together a nice visualization: http://clojure.googlegroups.com/web/chart.png If you use class as a dispatch function in a multimethod, you can use an interface, like IPersistentMap, as a dispatch value and it will match all classes that extend IPersistentMap, since multimethod dispatch uses isa? There are also predicates that correspond to most of the interfaces, like map?, list?, vector?, sorted? etc, all of which internally use (instance? someInterface x). The aforementioned chart includes the corresponding predicates. In general, it is bad style to use class equality, as in (= (class this) (class that)) - better to use instance? or isa?. Rich --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: sort with custom comparator
On Nov 6, 5:23 am, [EMAIL PROTECTED] [EMAIL PROTECTED] wrote: To answer my own question - AFn.java implements java.util.Comparator. That is documented here: http://clojure.org/special_forms Rich --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: prefer-method print-method problem
On Thu, Nov 6, 2008 at 10:01 AM, MikeM [EMAIL PROTECTED] wrote: I can reproduce what you did in a fresh local REPL (SVN 1075), but my server (also at SVN 1075) doesn't do this. I'm trying to find out how this can be. Any idea where I can find the code that generates the #=(sorted-map ... printing? I've looked but can't find it in boot.clj. Now *I'm* confused. It's your code that's printing #=(sorted-map ... for me, without any call to prefer-method required. --Chouser --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: prefer-method print-method problem
Now *I'm* confused. It's your code that's printing #=(sorted-map ... for me, without any call to prefer-method required. --Chouser Well, you're not the only one confused. I thought the #=(sorted- map ... came from boot.clj somehow, but I now realize my local REPL pulled in user.clj, where I had the print-method defined. I periodically forget that user.clj is read automatically. Sorry for being dense, and thanks again. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: jEdit Mode for Clojure
Daniel wrote Mostly for amusement, I created a jEdit mode for Clojure a while back. I don't get a chance to play with Clojure all that much, so it hasn't been heavily tested (go-to *is* a Clojure keyword, right?). ;-) It's primarily based upon the Vim mode in terms of what keywords it supports and how. Auto-indentation was something I looked at, but it isn't something I actually bothered to support due to time constraints (jEdit is capable of some pretty slick auto-indenting where Lisp-like languages are concerned). This is good timing for me. I am in the process of integrating clojure into a jEdit-based Mathematics Computing Environment I am creating called MathRider: http://mathrider.org MathRider currently includes clojure but syntax highlighting is not complete yet. I will look at your jEdit mode to see if it is more functional than what MathRider is currently using. If you have time to add auto-indentation, that would be great. If anyone wants to experiment with clojure in MathRider, there is a file called clojure_examples.mrw in the mathrider/examples directory. Ted Kosan --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Bug in genclass?
Hi, I am getting the following error trying to extend java.lang.Exception in the latest revision of Clojure: user=(defmacro defexception [name] `(try (gen-and-load-class (quote ~name) :extends Exception) (catch java.lang.LinkageError le# (. le# (printStackTrace) user= (defexception my.Exception) java.lang.ClassFormatError: JVMCFRE114 field name is invalid; class=my/Exception, offset=0 at java.lang.ClassLoader.defineClassImpl(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:265) at java.lang.ClassLoader.defineClass(ClassLoader.java:202) at clojure.lang.DynamicClassLoader.defineClass(DynamicClassLoader.java:39) at clojure.gen_and_load_class__2231.doInvoke(genclass.clj:461) at clojure.lang.RestFn.invoke(RestFn.java:443) at user.fn__2491.invoke(Unknown Source) at clojure.lang.AFn.applyToHelper(AFn.java:182) at clojure.lang.AFn.applyTo(AFn.java:175) at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:2664) at clojure.lang.Compiler.eval(Compiler.java:4116) at clojure.lang.Repl.main(Repl.java:91) nil user= The 'defexception macro is actually from swank-clojure. I have used this successfully in the past, the difference here is that I am using the IBM 1.6.0 JRE in this case: [EMAIL PROTECTED] trunk]$ java -version java version 1.6.0 Java(TM) SE Runtime Environment (build pxi3260sr2-20080818_01(SR2)) IBM J9 VM (build 2.4, J2RE 1.6.0 IBM J9 2.4 Linux x86-32 jvmxi3260-20080816_22093 (JIT enabled, AOT enabled) J9VM - 20080816_022093_lHdSMr JIT - r9_20080721_1330ifx2 GC - 20080724_AA) JCL - 20080808_02 I'm not sure if this is Clojure's bug or IBM's. I don't have the luxury of testing this on any other JVMs at the moment. I presume that since everyone is able to use swank-clojure at the latest revision that this is not happening on other JVMs? /mike. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
lancet: Clojure controlling Ant
Hi all, I am playing around with using Clojure to control Ant, something along the lines of Groovy's Gant. I don't know how far I will take this-- right now it is serving as a code example for the book. Two questions: (1) Anybody interested in seeing lancet carried forward into a real project? (2) Below is an example of lancet syntax (compare with Clojure's own build.xml). Any big likes/dislikes? Cheers, Stuart (project {:name clojure :default jar} (properties :src src :jsrc (i :src /jvm) :cljsrc (i :src /clj) :build classes :clojure_jar clojure.jar :bootclj (i :cljsrc /clojure/boot.clj)) (target {:name test} (echo {:message init target})) (target {:name compile :depends init :description Compile Java sources.} (javac {:srcdir (i :jsrc) :destdir (i :build) :includejavaruntime yes :debug true :target 1.5})) (target {:name init} (tstamp) (mkdir {:dir (i :build)})) (target {:name clean :description Remove autogenerated files and directories} (delete {:dir (i :build)})) ) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Clojure Maven integration
Does anyone know of any Clojure maven integration? What I'd like to see is something that will modify Clojure's classpath updated based upon a given pom.xml file. Thanks. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: lancet: Clojure controlling Ant
On Thu, Nov 6, 2008 at 11:48 AM, Stuart Halloway [EMAIL PROTECTED]wrote: Hi all, I am playing around with using Clojure to control Ant, something along the lines of Groovy's Gant. I don't know how far I will take this-- right now it is serving as a code example for the book. Two questions: (1) Anybody interested in seeing lancet carried forward into a real project? Yes, I hate ant and pretty much anything would be better! I might have some time to help out with the implementation. (2) Below is an example of lancet syntax (compare with Clojure's own build.xml). Any big likes/dislikes? No complaints from me. I like the syntax. Cheers, Stuart (project {:name clojure :default jar} (properties :src src :jsrc (i :src /jvm) :cljsrc (i :src /clj) :build classes :clojure_jar clojure.jar :bootclj (i :cljsrc /clojure/boot.clj)) (target {:name test} (echo {:message init target})) (target {:name compile :depends init :description Compile Java sources.} (javac {:srcdir (i :jsrc) :destdir (i :build) :includejavaruntime yes :debug true :target 1.5})) (target {:name init} (tstamp) (mkdir {:dir (i :build)})) (target {:name clean :description Remove autogenerated files and directories} (delete {:dir (i :build)})) ) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Having struggle in understanding FP (and Clojure question)
On 05.11.2008, at 17:16, Mark H. wrote: and replace copies with destructive writes. I haven't seen a purely functional formulation of LU factorization but it could be done without too much trouble. Of course there's no reason to go through that effort because people spend so much time optimizing LU and its constituent components that you would be better off reusing their work. For the immediate future, yes. But with changing computer architectures, the existing algorithms and routines may lose much of their interest in the future. To me the more interesting and rewarding task is to figure out how to splice existing HPC libraries into a functional framework, without losing the ability to reason functionally about the components. Unfortunately, it is already a bit of a pain to link existing HPC libraries (written in Fortran, C, or C++) to functional code in any decent language. Clojure won't help there, as there are still very few HPC libraries for the JVM and JNI adds too much of an overhead. Definitely! We've got at least one fellow here who uses Common Lisp to generate stencil codes. He's been thinking about switching to Clojure ever since he and I worked on a thorny Lisp problem together ;-) I am looking forward to a nice Clojure library then :-) Konrad. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: jEdit Mode for Clojure
After I posted this, I realized that it was a little silly to talk about a Lisp editor mode without auto-indentation. It has been added! The main caveat is it doesn't seem to handle multiple unindents with the correctness I would like. For example: (defn say-hi [n] (println (str Hello, n))) ; more code here Obviously, the third line should result in two levels of undindenting. However, due to limitations in the way that jEdit handles auto-indenting, I don't think I can do both levels at once. Specifically, the auto-indenting would assume that the ; more code here line should be indented at level 1, despite the fact that all parens are closed by that point. It's possible that I may be able to leverage jEdit's brace matching to unindent properly, but that will require some more experimentation. Daniel On Nov 6, 11:41 am, tkosan [EMAIL PROTECTED] wrote: Daniel wrote Mostly for amusement, I created a jEdit mode for Clojure a while back. I don't get a chance to play with Clojure all that much, so it hasn't been heavily tested (go-to *is* a Clojure keyword, right?). ;-) It's primarily based upon the Vim mode in terms of what keywords it supports and how. Auto-indentation was something I looked at, but it isn't something I actually bothered to support due to time constraints (jEdit is capable of some pretty slick auto-indenting where Lisp-like languages are concerned). This is good timing for me. I am in the process of integrating clojure into a jEdit-based Mathematics Computing Environment I am creating called MathRider: http://mathrider.org MathRider currently includes clojure but syntax highlighting is not complete yet. I will look at your jEdit mode to see if it is more functional than what MathRider is currently using. If you have time to add auto-indentation, that would be great. If anyone wants to experiment with clojure in MathRider, there is a file called clojure_examples.mrw in the mathrider/examples directory. Ted Kosan --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: lancet: Clojure controlling Ant
On Nov 6, 7:48 pm, Stuart Halloway [EMAIL PROTECTED] wrote: I am playing around with using Clojure to control Ant, something along the lines of Groovy's Gant. [] I know next to nothing about ant, and what kind of control will lancet provide, but the proposed syntax reminds me of what I got playing with XML generation. As an exercise, I tried to reproduce clojure's build.xml and pom.xml (the output of the code below differs only in whitespace). Your proposal is more succint (in particular when it comes to properties), but I think it can be easily expanded to the representation below (which maps directly into XML). Cheers, Carlos (defn write-attributes [key val attrs] (print (format %s=\%s\ (name key) val)) (when attrs (apply write-attributes attrs))) (defn write-tag [data close] (let [tag (name (if (coll? data) (first data) data))] (print (format %s tag)) (when (coll? data) (apply write-attributes (rest data))) (if close (do (print /) nil) (do (print ) tag (defn write-xml [tree] (if (coll? tree) (let [values (rest tree) close-tag (write-tag (first tree) (not values))] (when (or (not (= 1 (count values))) (coll? (first values))) (println)) (doall (map write-xml values)) (when close-tag (println (format /%s close-tag (print tree))) ;; build.xml (write-xml '((:project :name clojure :default jar) (:description Build with \ant jar\ and then start the REPL via \java -cp clojure.jar clojure.lang.Repl src/boot.clj\.) ((:property :name src :location src)) ((:property :name jsrc :location ${src}/jvm)) ((:property :name cljsrc :location ${src}/clj)) ((:property :name build :location classes)) ((:property :name clojure_jar :location clojure.jar)) ((:property :name bootclj :location ${cljsrc}/clojure/ boot.clj)) ((:target :name init) (:tstamp) ((:mkdir :dir ${build}))) ((:target :name compile :depends init :description Compile Java sources.) ((:javac :srcdir ${jsrc} :destdir ${build} :includeJavaRuntime yes :debug true :target 1.5))) ((:target :name jar :depends compile :description Create jar file.) ((:jar :jarfile ${clojure_jar} :basedir ${build}) ((:fileset :dir ${cljsrc} :includes **/*.clj)) (:manifest ((:attribute :name Main-Class :value clojure.lang.Repl)) ((:attribute :name Class-Path :value .) ((:target :name clean :description Remove autogenerated files and directories.) ((:delete :dir ${build}) ;; pom.xml (defn write-pom [pom] (println ?xml version=\1.0\ encoding=\UTF-8\?) (write-xml (conj pom '(:project :xmlns http://maven.apache.org/POM/4.0.0; :xmlns:xsi http//www.w3.org/2001/XMLSchema-instance :xsi:schemaLocation http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd; (write-pom '((:modelVersion 4.0.0) (:groupId jvm.clojure) (:artifactId clojure-lang) (:name clojure-lang) (:version 1.0-SNAPSHOT) (:url http://clojure.org/;) (:build (:sourceDirectory src/jvm) (:scriptSourceDirectory src/clj) (:plugins (:plugin (:artifactId maven-compiler-plugin) (:configuration (:source 1.5) (:target 1.5) (:optimize true (:resources (:resource (:directory src/clj/)) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: lancet: Clojure controlling Ant
On Thu, Nov 06, 2008 at 01:48:43PM -0500, Stuart Halloway wrote: Hi all, I am playing around with using Clojure to control Ant, something along the lines of Groovy's Gant. I don't know how far I will take this-- right now it is serving as a code example for the book. Two questions: (1) Anybody interested in seeing lancet carried forward into a real project? Oh yes please! I had started playing around with something like this, got far enough to compile some Java source (a static base for some Clojure code of course), and haven't really touched it sense. (2) Below is an example of lancet syntax (compare with Clojure's own build.xml). Any big likes/dislikes? I've never liked XML DSLs because they lack standard general purpose language features and go on to invent their own ad-hoc versions. Is a property not just a 'def' ? Is a target not a just function? (which only performs its actions if needed) Isn't a project just a mapping from target names to functions, and dynamic bindings during the build process? ; properties (def src src) (def jsrc (str src /jvm)) (def cljsrc (str src /clj)) (def target classes) (def clojure.jar clojure.jar) (def bootclj (str cljsrc /clojure/boot.clj)) ; deftarget is like defn but takes no args, and wraps the body in machinery ; that will only call it once per session. (deftarget clean Remove autogenerated files and directories (delete :dir target)) (deftarget init (tstamp) (mkdir :dir target)) (deftarget compile-java Compile java sources (init) (javac :srcdir jsrc :destdir target :includejavaruntime true :debug true :target 1.5)) A project could be defined explicitly, or could be created through reflection (deftarget would also add some metadata in that case) This syntax seems Clojurish rather than happens-to-be-on-Clojure. I think it shows off both the cognitive simplicity of FP and the powerful incremental nature of a Lisp based internal DSL. Regards, Steve --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Generalized Type Inference Optimization
I've been perusing Stu Halloway's beta of Programming Clojure and I came across the following example: (defn describe-class [c] {:name (.getName c) :final (java.lang.reflect.Modifier/isFinal (.getModifiers c))}) As demonstrated by the *warn-on-reflection* flag, Clojure is unable to determine a type for c, therefore all (or rather, almost all) of the calls made upon it must be handled reflectively. The performance solution suggested in the book is just to annotate the c parameter with a type: (defn describe-class [#^Class c] ...) This is a perfectly valid solution, but it seems a little ugly to me. The thought that I had is perhaps the Clojure compiler could actually infer this type automatically. Languages like ML and Haskell have been doing this for decades. Traditionally, Hindley-Milner isn't applied to object-oriented languages (or rather, languages which deal with uncontrolled OO constructs), but from what I understand, most of the reasoning behind this does not apply to Clojure. For example, Clojure doesn't have structural or parametric types because of its dynamic nature. There would be no *need* to infer any type parameters on calls out to Java, so the type system could be treated as nominal. The algorithm I'm thinking of would be something like this: * Maintain a multi-map of method and field names to classes (this could be done incrementally based on what classes the compiler knows are in scope) * For each parameter with an unfixed type: * Traverse the FnExpr AST and find all Java member access to that parameter * For each access, obtain a set of possible classes from the scope multi-map * At each step, intersect the previous set of possible classes with the subsequent one (think: a fold) * Final set can be optimized by choosing the most-specific type (eliminating the inheritance case) * If the final set has size of 1, then the type has been inferred and can be used to avoid reflection * If the set has size 0, then fallback on reflection * If the set has size 1, either fallback on reflection or get more sophisticated Improvements on this could be added to the 1 case where the second pass could look for methods of a given name *and* a specific arity. Subsequent passes could also incorporate inferred types for the method parameters. It's not a complete inference algorithm, but it doesn't have to be. There's nothing stopping Clojure from falling back on reflection for unfixed types. The whole logic behind this dance is to avoid reflection as much as possible, producing a fairly serious optimization in Java-interop without requiring those ugly type annotations. I briefly looked at implementing this myself, but Clojure's compiler code is...well, it's a compiler. :-) At first glance, I couldn't even figure out where to place the appropriate hooks to kick off this process. A better question though is: has this been tried/considered before? What are your overall thoughts with regards to this? --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Generalized Type Inference Optimization
On Nov 6, 4:31 pm, Daniel Spiewak [EMAIL PROTECTED] wrote: I've been perusing Stu Halloway's beta of Programming Clojure and I came across the following example: (defn describe-class [c] {:name (.getName c) :final (java.lang.reflect.Modifier/isFinal (.getModifiers c))}) As demonstrated by the *warn-on-reflection* flag, Clojure is unable to determine a type for c, therefore all (or rather, almost all) of the calls made upon it must be handled reflectively. The performance solution suggested in the book is just to annotate the c parameter with a type: (defn describe-class [#^Class c] ...) This is a perfectly valid solution, but it seems a little ugly to me. The thought that I had is perhaps the Clojure compiler could actually infer this type automatically. Languages like ML and Haskell have been doing this for decades. Traditionally, Hindley-Milner isn't applied to object-oriented languages (or rather, languages which deal with uncontrolled OO constructs), but from what I understand, most of the reasoning behind this does not apply to Clojure. For example, Clojure doesn't have structural or parametric types because of its dynamic nature. There would be no *need* to infer any type parameters on calls out to Java, so the type system could be treated as nominal. The algorithm I'm thinking of would be something like this: * Maintain a multi-map of method and field names to classes (this could be done incrementally based on what classes the compiler knows are in scope) * For each parameter with an unfixed type: * Traverse the FnExpr AST and find all Java member access to that parameter * For each access, obtain a set of possible classes from the scope multi-map * At each step, intersect the previous set of possible classes with the subsequent one (think: a fold) * Final set can be optimized by choosing the most-specific type (eliminating the inheritance case) * If the final set has size of 1, then the type has been inferred and can be used to avoid reflection * If the set has size 0, then fallback on reflection * If the set has size 1, either fallback on reflection or get more sophisticated Improvements on this could be added to the 1 case where the second pass could look for methods of a given name *and* a specific arity. Subsequent passes could also incorporate inferred types for the method parameters. It's not a complete inference algorithm, but it doesn't have to be. There's nothing stopping Clojure from falling back on reflection for unfixed types. The whole logic behind this dance is to avoid reflection as much as possible, producing a fairly serious optimization in Java-interop without requiring those ugly type annotations. I briefly looked at implementing this myself, but Clojure's compiler code is...well, it's a compiler. :-) At first glance, I couldn't even figure out where to place the appropriate hooks to kick off this process. A better question though is: has this been tried/considered before? What are your overall thoughts with regards to this? It's not a bad idea, and I'm sure Clojure could do more inference than it does, but the devil's in the details as usual. You'd want the least specific type. The best you could do is make a type-inferred fastpath, since you could always be wrong: In the case above, let's say you had imported Class (actually Clojure did that for you), and nothing else you imported had getName and getModifiers methods. Making the inference 'must be Class' could be wrong, since the function should work fine on java.lang.reflect.Method, for instance, and maybe that was the intent. So you'd need a runtime instanceof test for Class, and use the fastpath if true, reflection if not. Perf could be harder to pin down, as adding an import could cause previously fast code to get slow. Calls can be made only in specific conditional branches, which some higher-level logic might understand maps to non-overlapping types, so the inference should be of the call site, not the parameter itself - i.e. it's perfectly fine to write fns that expect a set of unrelated types, without being duck-typed. In fact it's even ok to type hint it even though the hint is only correct in one path. You have to allow for by-name duck-type calls or call them out specifically. Right now they are allowed. I think a simple version of this would be easy to do, when I get some time. I think it hasn't been a priority as it takes very few hints at the moment to remove reflection, given that types are tracked from calls to new and static calls, and from any other hinted calls. But it would be great to not need them at all! Rich --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options,
Re: Generalized Type Inference Optimization
So you'd need a runtime instanceof test for Class, and use the fastpath if true, reflection if not. Perf could be harder to pin down, as adding an import could cause previously fast code to get slow. Actually, I was thinking of performing the inference based on *all* classes on the classpath, not just the ones which have been imported. However, considering the fact that Clojure allows dynamic additions to the classpath, coupled with the fact that not all available classes need to be loaded, this might not be the best idea. The idea of call- point import scoping is an interesting one, I'm not sure how solid you could make it though. I mean, don't you look at the FnExpr types prior to analyzing its usage? (at least, that's how I've always written my compilers) At the very least, it might make library functions a little more interesting (certainly ruling out any pre- compilation). With respect to the separate paths issue, I assume that you're talking about something like this: (defn bad-boy [c x] (if c (.getMethods x) (.length x))) I think in this case the proper inference would be #{} -- in other words, reflection. The overhead of trying to fastpath and then fallback in certain branches would probably outweigh any benefits in this sort of edge case. The best you could do is make a type-inferred fastpath, since you could always be wrong Yeah, that is annoying. I hadn't thought of the fact that you could infer at declaration point and get a totally unambiguous type but still be wrong (since calls in different scopes could pass unexpected types that happen to fulfill the structural signature). How much overhead does #getClass() impose these days? I heard they were optimizing some of that in Java 6, but I haven't actually benchmarked anything. I suppose a simple check of that sort wouldn't ever be more expensive that a full-blown reflective call, but still. At what point are functions actually compiled? Is it possible to apply some of the techniques used in tracing VMs (e.g. V8) to get some improved context before performing the inference? In that case, you could actually create several different fast-path compilations +fallback. There are just so many complicated places you could go with this, it's just a question of implementation details (and of course, time to do it). Daniel On Nov 6, 4:26 pm, Rich Hickey [EMAIL PROTECTED] wrote: On Nov 6, 4:31 pm, Daniel Spiewak [EMAIL PROTECTED] wrote: I've been perusing Stu Halloway's beta of Programming Clojure and I came across the following example: (defn describe-class [c] {:name (.getName c) :final (java.lang.reflect.Modifier/isFinal (.getModifiers c))}) As demonstrated by the *warn-on-reflection* flag, Clojure is unable to determine a type for c, therefore all (or rather, almost all) of the calls made upon it must be handled reflectively. The performance solution suggested in the book is just to annotate the c parameter with a type: (defn describe-class [#^Class c] ...) This is a perfectly valid solution, but it seems a little ugly to me. The thought that I had is perhaps the Clojure compiler could actually infer this type automatically. Languages like ML and Haskell have been doing this for decades. Traditionally, Hindley-Milner isn't applied to object-oriented languages (or rather, languages which deal with uncontrolled OO constructs), but from what I understand, most of the reasoning behind this does not apply to Clojure. For example, Clojure doesn't have structural or parametric types because of its dynamic nature. There would be no *need* to infer any type parameters on calls out to Java, so the type system could be treated as nominal. The algorithm I'm thinking of would be something like this: * Maintain a multi-map of method and field names to classes (this could be done incrementally based on what classes the compiler knows are in scope) * For each parameter with an unfixed type: * Traverse the FnExpr AST and find all Java member access to that parameter * For each access, obtain a set of possible classes from the scope multi-map * At each step, intersect the previous set of possible classes with the subsequent one (think: a fold) * Final set can be optimized by choosing the most-specific type (eliminating the inheritance case) * If the final set has size of 1, then the type has been inferred and can be used to avoid reflection * If the set has size 0, then fallback on reflection * If the set has size 1, either fallback on reflection or get more sophisticated Improvements on this could be added to the 1 case where the second pass could look for methods of a given name *and* a specific arity. Subsequent passes could also incorporate inferred types for the method parameters. It's not a complete inference algorithm, but it doesn't have to be. There's nothing stopping Clojure from falling
Re: lancet: Clojure controlling Ant
Stephen, You are absolutely right, and I hope to have all your syntax suggestions implemented tomorrow. By way of background: When I started, it seemed there were three obvious avenues to pursue: (1) write a Clojure DSL that generates the Ant XML (2) write a Clojure DSL that sticks close to the underlying Ant object model (3) stick to Clojure idioms and use individual Ant classes when they fit in I rejected #1 out of hand--I don't think that the Ant XML has value, and so wrapping it (and having it leak in the form of error messages) was unappealing. I picked #2 because I thought there were a ton of objects in the Ant model I would end up wanting, and that they would be so intertwined that I would need to use most of them in order to use any of them. A few hours working on #2 was enough to convince me that there not much in Ant that I wanted to keep. In particular targets, properties, and subtask elements aren't worth their weight. That leaves only tasks (and a stubbed-out project object). So now I am proceeding through door #3. The work on #2 wasn't a total waste -- I now know enough of the Ant object model to fake out the few things I need (so far). Cheers, Stuart On Thu, Nov 06, 2008 at 01:48:43PM -0500, Stuart Halloway wrote: Hi all, I am playing around with using Clojure to control Ant, something along the lines of Groovy's Gant. I don't know how far I will take this-- right now it is serving as a code example for the book. Two questions: (1) Anybody interested in seeing lancet carried forward into a real project? Oh yes please! I had started playing around with something like this, got far enough to compile some Java source (a static base for some Clojure code of course), and haven't really touched it sense. (2) Below is an example of lancet syntax (compare with Clojure's own build.xml). Any big likes/dislikes? I've never liked XML DSLs because they lack standard general purpose language features and go on to invent their own ad-hoc versions. Is a property not just a 'def' ? Is a target not a just function? (which only performs its actions if needed) Isn't a project just a mapping from target names to functions, and dynamic bindings during the build process? ; properties (def src src) (def jsrc (str src /jvm)) (def cljsrc (str src /clj)) (def target classes) (def clojure.jar clojure.jar) (def bootclj (str cljsrc /clojure/boot.clj)) ; deftarget is like defn but takes no args, and wraps the body in machinery ; that will only call it once per session. (deftarget clean Remove autogenerated files and directories (delete :dir target)) (deftarget init (tstamp) (mkdir :dir target)) (deftarget compile-java Compile java sources (init) (javac :srcdir jsrc :destdir target :includejavaruntime true :debug true :target 1.5)) A project could be defined explicitly, or could be created through reflection (deftarget would also add some metadata in that case) This syntax seems Clojurish rather than happens-to-be-on-Clojure. I think it shows off both the cognitive simplicity of FP and the powerful incremental nature of a Lisp based internal DSL. Regards, Steve --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: lancet: Clojure controlling Ant
Carlos, I went down a similar road once before, using a Ruby DSL to generate the XML for Spring DI. This approach may offer the quickest initial return, but it hits a ceiling very quickly. You end up having two APIs with a totally unnecessary XML layer in between. Worse, the XML layer spews error messages that are totally meaningless in terms of the new object model. I am going to skip the XML entirely and program against the parts of the Ant object model I want to keep. It may be worthwhile to write a tool that goes in the other direction, reading XML and emitting lancet, for people porting existing buildfiles. Cheers, Stuart On Nov 6, 7:48 pm, Stuart Halloway [EMAIL PROTECTED] wrote: I am playing around with using Clojure to control Ant, something along the lines of Groovy's Gant. [] I know next to nothing about ant, and what kind of control will lancet provide, but the proposed syntax reminds me of what I got playing with XML generation. As an exercise, I tried to reproduce clojure's build.xml and pom.xml (the output of the code below differs only in whitespace). Your proposal is more succint (in particular when it comes to properties), but I think it can be easily expanded to the representation below (which maps directly into XML). Cheers, Carlos (defn write-attributes [key val attrs] (print (format %s=\%s\ (name key) val)) (when attrs (apply write-attributes attrs))) (defn write-tag [data close] (let [tag (name (if (coll? data) (first data) data))] (print (format %s tag)) (when (coll? data) (apply write-attributes (rest data))) (if close (do (print /) nil) (do (print ) tag (defn write-xml [tree] (if (coll? tree) (let [values (rest tree) close-tag (write-tag (first tree) (not values))] (when (or (not (= 1 (count values))) (coll? (first values))) (println)) (doall (map write-xml values)) (when close-tag (println (format /%s close-tag (print tree))) ;; build.xml (write-xml '((:project :name clojure :default jar) (:description Build with \ant jar\ and then start the REPL via \java -cp clojure.jar clojure.lang.Repl src/boot.clj\.) ((:property :name src :location src)) ((:property :name jsrc :location ${src}/jvm)) ((:property :name cljsrc :location ${src}/clj)) ((:property :name build :location classes)) ((:property :name clojure_jar :location clojure.jar)) ((:property :name bootclj :location ${cljsrc}/clojure/ boot.clj)) ((:target :name init) (:tstamp) ((:mkdir :dir ${build}))) ((:target :name compile :depends init :description Compile Java sources.) ((:javac :srcdir ${jsrc} :destdir ${build} :includeJavaRuntime yes :debug true :target 1.5))) ((:target :name jar :depends compile :description Create jar file.) ((:jar :jarfile ${clojure_jar} :basedir ${build}) ((:fileset :dir ${cljsrc} :includes **/*.clj)) (:manifest ((:attribute :name Main-Class :value clojure.lang.Repl)) ((:attribute :name Class-Path :value .) ((:target :name clean :description Remove autogenerated files and directories.) ((:delete :dir ${build}) ;; pom.xml (defn write-pom [pom] (println ?xml version=\1.0\ encoding=\UTF-8\?) (write-xml (conj pom '(:project :xmlns http://maven.apache.org/POM/4.0.0; :xmlns:xsi http//www.w3.org/2001/XMLSchema-instance :xsi:schemaLocation http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd; (write-pom '((:modelVersion 4.0.0) (:groupId jvm.clojure) (:artifactId clojure-lang) (:name clojure-lang) (:version 1.0-SNAPSHOT) (:url http://clojure.org/;) (:build (:sourceDirectory src/jvm) (:scriptSourceDirectory src/clj) (:plugins (:plugin (:artifactId maven-compiler-plugin) (:configuration (:source 1.5) (:target 1.5) (:optimize true (:resources (:resource (:directory src/clj/)) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Having struggle in understanding FP (and Clojure question)
Thanks everyone. I've read all the replies, and I might understand something. (Though it seems that discussion goes to beyond my current understanding in the middle of this discussion threads) To explore further, I become another owner of 'Programming Clojure' :-) For my second question, I'll keep thinking and repost question. I'm really concern about concurrency of Clojure, since the concurrency in my world means _the C10K problem_, that is supporting simultaneous 1 connections or over for networking applications. (http://www.kegel.com/c10k.html) In YAWS, Erlang have shown one solution, so I'm curios that Clojure could be another viable alternative, and that how well-suited Clojure is for that kind of concurrency. My expectation is these: 1) For C10K problem (or C100K), application must not use native threads. Big stack size means low concurrency 2) For application developer, thread model is easy to develop and follow. 3) Therefore, underlying system should support concurrency facility like micro-thread, lightweight process (in Erlang) , agent (in Clojure), or whatever. In this case, underlying facility should have high-performance. 4) At the same time, there must be ways for connecting conceptual gap between 2) and 3). In other words, the way for suspending current execution of function, saving current execution snapshot (normally native thread stack, but may be different), and switching to other functions are needed when the request for I/O should be blocked. It's important that the size of current execution snapshot should be small, since it determine the degree of concurrency. After I invest some time to learn Clojure, I'll repost. Thank you. - cw --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Having struggle in understanding FP (and Clojure question)
On Nov 6, 11:58 am, Konrad Hinsen [EMAIL PROTECTED] wrote: On 05.11.2008, at 17:16, Mark H. wrote: For the immediate future, yes. But with changing computer architectures, the existing algorithms and routines may lose much of their interest in the future. Haha, yes, we're working on this ;-) (a number of my colleagues are, at least). To me the more interesting and rewarding task is to figure out how to splice existing HPC libraries into a functional framework, without losing the ability to reason functionally about the components. Unfortunately, it is already a bit of a pain to link existing HPC libraries (written in Fortran, C, or C++) to functional code in any decent language. Clojure won't help there, as there are still very few HPC libraries for the JVM and JNI adds too much of an overhead. Does the JNI require copy-in / copy-out for arrays of floating-point numbers? I know Java has messed-up floating-point (Sun stupidly took away x87's 80-bit temps and other good things) but I'd at least like to avoid copy overhead for matrix and vector ops. I don't mind the extra function call out of JVM space as long as I can amortize it over the cost of a big matrix operation. (No way I'm writing loops in Clojure for that.) There are a number of Python-based projects to do what you mentioned (link HPC libraries in Fortran or C to a higher-level language), so it's not impossible. It's just a lot of tedious work for some unlucky coders. Definitely! We've got at least one fellow here who uses Common Lisp to generate stencil codes. He's been thinking about switching to Clojure ever since he and I worked on a thorny Lisp problem together ;-) I am looking forward to a nice Clojure library then :-) We'll see -- he's got it working in CL now and he's got a deadline, so he may not bother migrating it. Plus he likes the ECL / C linkup; Java may not be so helpful for him. mfh --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Recommending Approach to Performance Critical Code
On Nov 6, 7:05 pm, CuppoJava [EMAIL PROTECTED] wrote: I'm doing some heavy numerical matrix crunching and would like to write it in as elegant a way as possible without sacrificing any speed. Can you define matrix crunching more precisely? mfh --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---