Re: Reflection warning: reference to field getClass can't be resolved.
On Aug 4, 4:46 pm, Vagif Verdi vagif.ve...@gmail.com wrote: When reflection warning is on, i get 2 warnings on every my file: reference to field getClass can't be resolved. reference to field getClassLoader can't be resolved. Is this something i should be worried about ? Probably not. It appears to be in the ns macro: user= (set! *warn-on-reflection* true) true user= (ns foo.bar) Reflection warning, NO_SOURCE_PATH:2 - reference to field getClass can't be resolved. Reflection warning, NO_SOURCE_PATH:2 - reference to field getClassLoader can't be resolved. nil foo.bar= --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Package manager proposal
2009/8/4 Meikel Brandmeyer m...@kotka.de: I think, clojure context is underestimating things. The high integration of external Java libraries makes it necessary that such dependencies can be handled in the same way. Agreed. I was actually going to write that whatever approach is chosen it must be able to handle Java dependencies as well, but somehow it got lost in the edits ;-) John Newman brought up a good point as well concerning support for other possible clojure platforms like JS, CLR, and Parrot: if we support Java library packaging than shouldn't we also support packaging on other platforms? Maybe the first step should be to provide something that works for clojure code and worry about Java / C# / ... libraries only later? Btw. how does Ruby Gems deal with external dependencies like C libraries? Will the gem install simply fail if an external dependency is not met? And is that analogous to a missing Java library in Clojure's case? I guess one difference is the fact that an installed C library (at least on Unix) is installed in a globally accessable location on the filesystem, whereas Java libs don't have such conventions (or do they these days?). Sincerely Meikel -- ! Lauri --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: transient quicksort
On Aug 4, 11:08 am, Jonas jonas.enl...@gmail.com wrote: Can you give any hints on how I can make the transient sort faster? I would like to get as close as possible to the native Java speed. You are comparing apples to oranges. Clojure's persistent vectors do not magically turn into Java arrays when using the new transients feature; they are still good old persistent vectors, with the added bonus that some operations can be done by mutating existing structure. But this structure is still the same old awesome piece of persistent vector! A bit lame analogy, but maybe helps some people understand the point I'm trying to make. It's like the good old story about how MySQL is faster than PostgreSQL. Not. At least if you want safety. What the native sort function does is just what I wanted to suggest you do: turn the persistent vector into a plain old array, sort that, and then convert the sorted array back into a Clojure data structure. --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Package manager proposal
Hi, On Aug 5, 10:32 am, Lauri Pesonen lauri.peso...@iki.fi wrote: John Newman brought up a good point as well concerning support for other possible clojure platforms like JS, CLR, and Parrot: if we support Java library packaging than shouldn't we also support packaging on other platforms? The history book on the shelf / is always repeating itself. I think there was some meta package manager, which created from one description a .deb, .rpm, .tgz, whatever to bridge the Linux distros. Something like that would be necessary than. I'm not sure something like that exists to create an installer for Unix, Windows and OS X from the same description. Maybe the first step should be to provide something that works for clojure code and worry about Java / C# / ... libraries only later? opinion I'm sorry. No. I think one of the big pluses of Clojure is the easy integration of the quadrizillion Java libraries out there. So I don't have to wait for a Clojure implementations of some particular library. I think it will still be a long way until such a wealthy flora of libraries will exist in pure Clojure. If the packager doesn't solve my problems *now*, I don't need it. /opinion Btw. how does Ruby Gems deal with external dependencies like C libraries? Will the gem install simply fail if an external dependency is not met? And is that analogous to a missing Java library in Clojure's case? I guess one difference is the fact that an installed C library (at least on Unix) is installed in a globally accessable location on the filesystem, whereas Java libs don't have such conventions (or do they these days?). Well, this is independent of whether you have a C or Java library. You can install each C library in its own directory and tell the linker to look there. Then you have basically a .jar like setup: If you don't tell the linker the right directory the library is not there. Similar you can declare /usr/java/lib as your global directory and unzip each and every jar there. Then configure your java launcher to add that directory to the classpath and you have a setup, like the usual one for C libraries. So this could even be system policy. All these setups can be done (more or less comfortable) with today existing solutions for Java. Instead of re-inventing those, it would be more useful to abstract away their specifics. Create a meta-package manager which creates JVM, CLR and whatever packages sitting on the existing infrastructure for the respective platform. Then it is also possible to hook from the platform into Clojure. I think I saw something like Accessing Clojure from Jython/JRuby/Jsomething. So even none-Clojure projects might want to use a clojure library for some reason. Providing them platform-usual dependency handling would be an additional plus. Any CLR experts around? How does the packaging work there? 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Transient Data Structures
On Tue, Aug 4, 2009 at 5:50 PM, Rich Hickey richhic...@gmail.com wrote: On Aug 4, 4:31 pm, John Harrop jharrop...@gmail.com wrote: What about things like: (persistent! (reduce (fn [x [i v]] (assoc! x i v)) (transient (vec (repeat 0 (reduce max (map first coll-of-index-val-pairs) coll-of-index-val-pairs)) Yes, that's completely fine intended usage, as the return value of the reducing fn becomes an argument to the next call. which is just the transientification of Nice word - transientification. Thanks. Of course, this makes me think of ways to possibly speed up other operations. For example: (defn vmap* [fun vect] (let [c (count vect)] (loop [out (transient []) i 0] (if (= i c) out (recur (conj! out (fun (nth vect i))) (inc i)) (defn vmap [fun vect] (persistent! (vmap* fun vect))) Vector in, vector out, conj'd up using a transient. And, of course: (defn vpmap [fun vect] (loop [out (vmap* #(future (fun %)) vect) i (dec (count vect))] (let [o2 (assoc! out i @(nth out i))] (if (zero? i) (persistent! o2) (recur o2 (dec i) Note that this last manipulates a transient vector in a single thread, though other threads (from the agent pool) calculate a bunch of futures that are stored in it. The transient vector of futures is generated using the vmap* from above, and then the futures are replaced with their values in-place by the loop in vpmap, before this persistentizes and returns that vector. The future-dereferencing loop works backwards from the end of the vector in case zero? is a quicker test than a general equality test. This is likely on hardware that implements an equality test as a subtraction followed by a zero test, because it eliminates the subtraction. On the other hand, hardware with a 1-cycle equality test of 32-bit ints is plausible, as is hardware that optimizes forward traversal of vectors, so I can't vouch for that being an optimization. The first loop has to go forward to conj up the output vector without reversing it, though. --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Reflection warning: reference to field getClass can't be resolved.
On Tue, Aug 4, 2009 at 7:46 PM, Vagif Verdi vagif.ve...@gmail.com wrote: When reflection warning is on, i get 2 warnings on every my file: reference to field getClass can't be resolved. That one is very weird, because getClass is a method of java.lang.Object. It should always be possible to resolve that one without reflection. --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Newbie question: Writing a GUI with clojure
Hey, New to Java and Clojure. My possibly relevant experience is with Gtk and Ruby and C++ programming. I'd like to develop a GUI in Clojure. I'm guessing I want to use Swing. This application will be targeted towards scientists who are used to working with the most horribly-designed Tk UI known to man, so I'm sure they will be fine with Swing. So, where's the best place to start? What I've been doing: - Watched the peepcode - Working my way through Stuart's book - Playing with netbean's GUI designer Is it possible to use the netbean designer and clojure at the same time? What's the best way of doing that? I'm used to writing GUIs in C++, would Clojure have a drastically different approach (as far as application logic and event handling)? --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: transient quicksort
Hi, Thank's for pointing this out for me. I didn't realize how to use these constructs correctly. Seeing the !-mark i just thought that assoc! was to be used like set! set-car! set-cdr! in Scheme... my mistake. On Tue, Aug 4, 2009 at 8:49 PM, Jarkko Oranenchous...@gmail.com wrote: On Aug 4, 11:08 am, Jonas jonas.enl...@gmail.com wrote: Hi I'm playing with the new transient/persistent! features in Clojure. I have implemented quicksort as described on wikipedia (http:// en.wikipedia.org/wiki/Quicksort#Algorithm). Here is the code: (defn swap-index! [v i j] (let [tmp (v i)] (assoc! v i (v j)) (assoc! v j tmp))) I think Rich mentioned on IRC that you should not reuse the transient vector binding after an operation; that it works is merely an implementation detail. The transient documentation page also says tells to capture return value, use for next call. So: (defn swap-index! [tv i j] (let [tmp (tv i)] (- tv (assoc! i (v j)) (assoc! j tmp And similar modifications for the quicksort below. (defn partition! [v left-index right-index pivot-index] (let [pivot-value (v pivot-index)] (swap-index! v pivot-index right-index) (loop [i left-index store-index left-index] (if ( i right-index) (if (= (v i) pivot-value) (do (swap-index! v i store-index) (recur (inc i) (inc store-index))) (recur (inc i) store-index)) (do (swap-index! v store-index right-index) store-index) (defn qsort! [v left right] (when ( right left) (let [pivot-index left pivot-new-index (partition! v left right pivot-index)] (qsort! v left (dec pivot-new-index)) (qsort! v (inc pivot-new-index) right (defn qsort [v] (let [tv (transient v)] (qsort! tv 0 (dec (count v))) (persistent! tv))) This sorts a vector of doubles in about 6000-7000 msec on my machine: user= (def s (time (qsort (rvector 100 Elapsed time: 6681.35889 msecs This is much faster than the classical functional programming quicksort: ; Fromhttp://rosettacode.org/wiki/Quicksort#Clojure (defn qsort-rs [[pivot xs]] (when pivot (let [smaller #( % pivot)] (lazy-cat (qsort (filter smaller xs)) [pivot] (qsort (remove smaller xs)) user= (def s (time (doall (qsort-rs (rvector 100) Elapsed time: 32565.537389 msecs The Java sort however is about 5 times faster then the transient version: user= (def s (time (sort (rvector 100 Elapsed time: 1354.427239 msecs Can you give any hints on how I can make the transient sort faster? I would like to get as close as possible to the native Java speed. This is partially comparing apples to oranges though: sort returns a lazy seq, while the quicksort algorithm produces a proper vector. Anyway, (nth v i) might be somewhat faster than (v i) because it gets inlined. I did not try, though. Ok, I will try that Below is code that avoids reusing the reference to v: (defn swap-index! [v i j] (let [tmp (nth v i)] (- v (assoc! i (nth v j)) (assoc! j tmp (defn partition! [v left-index right-index pivot-index] (let [pivot-value (nth v pivot-index) new-v (swap-index! v pivot-index right-index)] (loop [v new-v, i left-index, store-index left-index] (if ( i right-index) (if (= (nth v i) pivot-value) (recur (swap-index! v i store-index) (inc i) (inc store- index)) (recur v (inc i) store-index)) [(swap-index! v store-index right-index) store-index] (defn qsort! [v left right] (if ( right left) (let [pivot-index left [new-v pivot-new-index] (partition! v left right pivot- index)] (- new-v (qsort! left (dec pivot-new-index)) (qsort! (inc pivot-new-index) right v) (defn qsort [v] (let [tv (transient v)] (qsort! tv 0 (dec (count v))) (persistent! tv))) Nice, thank you! -- Jarkko --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Miscellanea prompted by a comp.lang.lisp post about Clojure
I just saw someone post a bunch of Clojure code to comp.lang.lisp one function from which was: (defn partition-with [pred coll] (loop [in coll curr [] out []] (if (empty? in) (conj out curr) (let [obj (first in)] (if (pred obj) (recur (rest in) [] (conj out curr)) (recur (rest in) (conj curr obj) out)) This looks like it might be generally useful (and the CLL poster thought so too); it splits a collection at items determined by the predicate, producing a vector of vectors of items not matching the predicate: user= (partition-with odd? [3 4 8 7 9 2 4 6]) [[] [4 8] [] [2 4 6]] (The empty collections are from before 3 and between 7 and 9, from the look of it. user= (remove empty? (partition-with odd? [3 4 8 7 9 2 4 6])) ([4 8] [2 4 6]) gives what you might want instead, in some situations.) The same CLL poster noticed that conj with two maps for arguments seems to duplicate the functionality of merge. I've just tested this and it seems to be true, even with key duplications: user= (merge {:key2 2 :key3 3} {:key1 1 :key4 4 :key3 7} ) {:key4 4, :key1 1, :key2 2, :key3 7} user= (conj {:key2 2 :key3 3} {:key1 1 :key4 4 :key3 7} ) {:key4 4, :key1 1, :key2 2, :key3 7} This makes merge appear redundant. Further experimentation shows that there isn't even a type-safety reason to prefer merge. It doesn't throw on vectors. In fact: user= (merge [1 2 3] 4) [1 2 3 4] user= (merge '(1 2 3) 4) (4 1 2 3) user= (merge #{1 2 3} 8) #{1 2 3 8} user= (merge #{1 2 3} 3) #{1 2 3} user= (merge #{1 2 3} #{4 3}) #{1 2 3 #{3 4}} user= (conj #{1 2 3} #{4 3}) #{1 2 3 #{3 4}} so merge appears to be strictly synonymous with conj. Curiouser and curiouser... --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Question about pmap
Could it be that your CPU has a single floating-point unit shared by 4 cores on a single die, and thus only 2 floating-point units total for all 8 of your cores? If so, then that fact, plus the fact that each core has its own separate ALU for integer operations, would seem to explain the results you are seeing. Exactly, this would explain the behaviour. But unfortunately it is not the case. I implemented a small example using Java (Java Threads) and C (PThreads) and both times I get a linear speedup. See the attached code below. The cores only share 12 MB cache, but this should be enough memory for my micro-benchmark. Seeing the linear speedup in Java and C, I would negate a hardware limitation. _ Johann ### C ### #include pthread.h #include stdio.h #include stdlib.h #define NUM_THREADS 8 int inc(int); double inc_d(int); int inc(int x){ int y; y = x + 1; return y; } double inc_d(int x){ double y; y = (double)x + 1.0; return y; } void *BusyWork(void *t){ int i; long tid; int result=0; tid = (long)t; printf(Thread %ld starting...\n,tid); for (i=0; i10; i++){ /* result = result + sin(i) * tan(i); */ result = inc(i); } printf(Thread %ld done. Result = %i\n,tid, result); pthread_exit((void*) t); } void *BusyWork_d(void *t){ int i; long tid; double result=0.0; tid = (long)t; printf(Thread %ld starting...\n,tid); for (i=0; i10; i++){ /* result = result + sin(i) * tan(i); */ result = inc_d(i); } printf(Thread %ld done. Result = %e\n,tid, result); pthread_exit((void*) t); } void *BusyWork_single(){ int i; double result=0.0; for (i=0; i10; i++){ /* result = result + sin(i) * tan(i); */ result = inc_d(i); } } int main (int argc, char *argv[]){ time_t start,end; double dif; pthread_t thread[NUM_THREADS]; pthread_attr_t attr; int rc; long t; void *status; start = time(NULL); /* Running serial code */ for(t=0; tNUM_THREADS; t++){ printf(Running serial code #: %ld\n, t); BusyWork_single(); } end = time(NULL); dif = difftime(end,start); printf(Runtime for serial code: %f\n, dif); start = time(NULL); /* Initialize and set thread detached attribute */ pthread_attr_init(attr); pthread_attr_setdetachstate(attr, PTHREAD_CREATE_JOINABLE); for(t=0; tNUM_THREADS; t++){ printf(Main: creating thread %ld\n, t); /* Let's rock */ /* rc = pthread_create(thread[t], attr, BusyWork, (void *)t); */ rc = pthread_create(thread[t], attr, BusyWork_d, (void *)t); if (rc) { printf(ERROR; return code from pthread_create() is %d\n, rc); exit(-1); } } /* Free attribute and wait for the other threads */ pthread_attr_destroy(attr); for(t=0; tNUM_THREADS; t++){ rc = pthread_join(thread[t], status); if (rc) { printf(ERROR; return code from pthread_join() is %d\n, rc); exit(-1); } printf(Main: completed join with thread %ld having a status of %ld \n,t,(long)status); } end = time(NULL); dif = difftime(end,start); printf(Runtime for parallel code: %f\n, dif); printf(Main: program completed. Exiting.\n); pthread_exit(NULL); } ### Java ### import java.text.DecimalFormat; public class MapTest{ public static class IntTest implements Runnable{ long loops; long result; public IntTest(long loops){ this.loops = loops; } // stupid work public void run(){ result = 0; for (long i = 0L; i loops; i++){ result = result + 1; } System.out.println(result); } } public static class DoubleTest implements Runnable{ long loops; double result; public DoubleTest(long loops){ this.loops = loops; } // stupid work public void run(){ result = 0.0; for (long i = 0L; i loops; i++){ result = result + 1.0; } System.out.println(result); } }
Re: Miscellanea prompted by a comp.lang.lisp post about Clojure
On Wed, Aug 5, 2009 at 08:05, John Harropjharrop...@gmail.com wrote: I just saw someone post a bunch of Clojure code to comp.lang.lisp one function from which was: (defn partition-with [pred coll] (loop [in coll curr [] out []] (if (empty? in) (conj out curr) (let [obj (first in)] (if (pred obj) (recur (rest in) [] (conj out curr)) (recur (rest in) (conj curr obj) out)) This looks like it might be generally useful (and the CLL poster thought so too); it splits a collection at items determined by the predicate, producing a vector of vectors of items not matching the predicate: user= (partition-with odd? [3 4 8 7 9 2 4 6]) [[] [4 8] [] [2 4 6]] (The empty collections are from before 3 and between 7 and 9, from the look of it. user= (remove empty? (partition-with odd? [3 4 8 7 9 2 4 6])) ([4 8] [2 4 6]) gives what you might want instead, in some situations.) The same CLL poster noticed that conj with two maps for arguments seems to duplicate the functionality of merge. I've just tested this and it seems to be true, even with key duplications: user= (merge {:key2 2 :key3 3} {:key1 1 :key4 4 :key3 7} ) {:key4 4, :key1 1, :key2 2, :key3 7} user= (conj {:key2 2 :key3 3} {:key1 1 :key4 4 :key3 7} ) {:key4 4, :key1 1, :key2 2, :key3 7} This makes merge appear redundant. Further experimentation shows that there isn't even a type-safety reason to prefer merge. It doesn't throw on vectors. In fact: user= (merge [1 2 3] 4) [1 2 3 4] user= (merge '(1 2 3) 4) (4 1 2 3) user= (merge #{1 2 3} 8) #{1 2 3 8} user= (merge #{1 2 3} 3) #{1 2 3} user= (merge #{1 2 3} #{4 3}) #{1 2 3 #{3 4}} user= (conj #{1 2 3} #{4 3}) #{1 2 3 #{3 4}} so merge appears to be strictly synonymous with conj. Curiouser and curiouser... At first, I figured it'd be (defn merge Returns a map that consists of the rest of the maps conj-ed onto the first. If a key occurs in more than one map, the mapping from the latter (left-to-right) will be the mapping in the result. [ maps] (when (some identity maps) (reduce #(conj (or %1 {}) %2) maps))) Merge combines (by reducing with conj) the maps its given. The difference is in how nil as the first argument is handled. When the first argument is nil, it is treated as if it were an empty map. (clojure has a somewhat ambiguous relation to nil. Often nil is treated as an empty collection, in this case en empty map. In contrast to regular empty collections, however, nil is considered false when evaluated as a boolean.) user (merge {} {1 1.0} {2 2.0 3 3.0}) {3 3.0, 2 2.0, 1 1.0} user (merge nil {1 1.0} {2 2.0 3 3.0}) {3 3.0, 2 2.0, 1 1.0} The other differences stem from the fact that conj works a little differently with maps than it does with lists and the fact that conj considers nil equivalent to empty list (unlike merge, which considers it equivalent to empty map). user (conj nil {1 1.0} {2 2.0 3 3.0}) ({2 2.0, 3 3.0} {1 1.0}) user (conj {} {1 1.0} {2 2.0 3 3.0}) {3 3.0, 2 2.0, 1 1.0} Here we also notice that conj supports more than two arguments, which makes me wonder why merge uses reduce in the first place. It would seem to be unnecessary. (defn my-merge [ maps] ;; this appears equivalent to clojure.core/merge (when (some identity maps) (apply conj (cons (or (first maps) {}) (rest maps) // ben --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Miscellanea prompted by a comp.lang.lisp post about Clojure
Hi, On Aug 5, 8:05 am, John Harrop jharrop...@gmail.com wrote: I just saw someone post a bunch of Clojure code to comp.lang.lisp one function from which was: (defn partition-with [pred coll] (loop [in coll curr [] out []] (if (empty? in) (conj out curr) (let [obj (first in)] (if (pred obj) (recur (rest in) [] (conj out curr)) (recur (rest in) (conj curr obj) out)) This looks like it might be generally useful (and the CLL poster thought so too); it splits a collection at items determined by the predicate, producing a vector of vectors of items not matching the predicate. You might want to rewrite that to return a lazy-seq, which just consumes just enough to provide the partition parts. (defn partition-with [pred coll] (letfn [(step [s] (lazy-seq (when-let [s (seq s)] (let [[fst rst] (split-with (complement pred) s)] (cons fst (step (rest rst)))] (step coll))) The same CLL poster noticed that conj with two maps for arguments seems to duplicate the functionality of merge. I've just tested this and it seems to be true, even with key duplications: user= (merge {:key2 2 :key3 3} {:key1 1 :key4 4 :key3 7} ) {:key4 4, :key1 1, :key2 2, :key3 7} user= (conj {:key2 2 :key3 3} {:key1 1 :key4 4 :key3 7} ) {:key4 4, :key1 1, :key2 2, :key3 7} This makes merge appear redundant. Looking at the source `merge` just reduces the maps using `conj`. `conj` on maps again, expect either a MapEntry or a vector. Otherwise it `seq`s its argument and `conj`s the elements onto the map. `seq`ing a map gives a seq of MapEntries, and hence we get the observed result. But the nil handling is different: user= (conj nil {:a 5}) ({:a 5}) user= (merge nil {:a 5}) {:a 5} Also there's merge-with. Further experimentation shows that there isn't even a type-safety reason to prefer merge. type-safety somehow seems funny in Clojure... Maybe abstraction-safety? It doesn't throw on vectors. In fact: user= (merge [1 2 3] 4) [1 2 3 4] user= (merge '(1 2 3) 4) (4 1 2 3) user= (merge #{1 2 3} 8) #{1 2 3 8} user= (merge #{1 2 3} 3) #{1 2 3} user= (merge #{1 2 3} #{4 3}) #{1 2 3 #{3 4}} user= (conj #{1 2 3} #{4 3}) #{1 2 3 #{3 4}} so merge appears to be strictly synonymous with conj. Curiouser and curiouser... The contract (the docstring) says maps. What happens when you feed different things to `merge` is unspecified. Since it uses internally `conj` it's no surprise, that it also works with vectors and sets. However you can see that the result are broken. There might be a hypothetical merge, which would also work on vectors and sets in a meaningful way: user= (hypothetical-merge [1 2 3 4] [5 6]) [5 6 3 4] user= (hypothetical-merge #{1 2} #{2 3}) #{1 2 3} For lists, however, I don't see such an operation. Upshot: `conj` and `merge` are not synonyms, cf. nil handling. 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Transient Data Structures
On Tue, Aug 4, 2009 at 10:13 PM, John Harropjharrop...@gmail.com wrote: On Tue, Aug 4, 2009 at 5:50 PM, Rich Hickey richhic...@gmail.com wrote: On Aug 4, 4:31 pm, John Harrop jharrop...@gmail.com wrote: What about things like: (persistent! (reduce (fn [x [i v]] (assoc! x i v)) (transient (vec (repeat 0 (reduce max (map first coll-of-index-val-pairs) coll-of-index-val-pairs)) Yes, that's completely fine intended usage, as the return value of the reducing fn becomes an argument to the next call. which is just the transientification of Nice word - transientification. Thanks. Of course, this makes me think of ways to possibly speed up other operations. For example: (defn vmap* [fun vect] (let [c (count vect)] (loop [out (transient []) i 0] (if (= i c) out (recur (conj! out (fun (nth vect i))) (inc i)) (defn vmap [fun vect] (persistent! (vmap* fun vect))) Vector in, vector out, conj'd up using a transient. Mapping into vectors and similar ops are coming, although nothing like vmap* would ever be exposed. And, of course: (defn vpmap [fun vect] (loop [out (vmap* #(future (fun %)) vect) i (dec (count vect))] (let [o2 (assoc! out i @(nth out i))] (if (zero? i) (persistent! o2) (recur o2 (dec i) Note that this last manipulates a transient vector in a single thread, though other threads (from the agent pool) calculate a bunch of futures that are stored in it. The transient vector of futures is generated using the vmap* from above, and then the futures are replaced with their values in-place by the loop in vpmap, before this persistentizes and returns that vector. The future-dereferencing loop works backwards from the end of the vector in case zero? is a quicker test than a general equality test. This is likely on hardware that implements an equality test as a subtraction followed by a zero test, because it eliminates the subtraction. On the other hand, hardware with a 1-cycle equality test of 32-bit ints is plausible, as is hardware that optimizes forward traversal of vectors, so I can't vouch for that being an optimization. The first loop has to go forward to conj up the output vector without reversing it, though. There is already a very nice pvmap in the par branch that uses ForkJoin. I strongly recommend against trying to write parallel ops with transients - that's not what they are for. What's nice about pvmap is that, just like transients, it also takes, manipulates, and returns ordinary Clojure vectors (unlike the old parallel lib which copied into and out of ForkJoin's ParallelArrays). The goal is to make using the normal data structures as powerful as possible, and not needing to switch to something else for performance. 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Question about pmap
On Wed, Aug 5, 2009 at 8:29 AM, Johann Krausjohann.kr...@gmail.com wrote: Could it be that your CPU has a single floating-point unit shared by 4 cores on a single die, and thus only 2 floating-point units total for all 8 of your cores? If so, then that fact, plus the fact that each core has its own separate ALU for integer operations, would seem to explain the results you are seeing. Exactly, this would explain the behaviour. But unfortunately it is not the case. I implemented a small example using Java (Java Threads) and C (PThreads) and both times I get a linear speedup. See the attached code below. The cores only share 12 MB cache, but this should be enough memory for my micro-benchmark. Seeing the linear speedup in Java and C, I would negate a hardware limitation. _ Johann ### C ### That's a lot of code for a message, could you please use a pastebin next time? Thanks. I looked briefly at your problem and don't see anything right off the bat. Do you have a profiler and could you try that out? I'm interested. Thanks, 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Newbie question: Writing a GUI with clojure
If you really want to get into Swing I suggest taking a look at the following book: http://oreilly.com/catalog/9780596009076/ It's got tons of I didn't knnow you could do that... ideas On Aug 5, 9:01 am, John Harrop jharrop...@gmail.com wrote: On Tue, Aug 4, 2009 at 10:33 PM, Joe Van Dyk joevan...@gmail.com wrote: Hey, New to Java and Clojure. My possibly relevant experience is with Gtk and Ruby and C++ programming. I'd like to develop a GUI in Clojure. I'm guessing I want to use Swing. This application will be targeted towards scientists who are used to working with the most horribly-designed Tk UI known to man, so I'm sure they will be fine with Swing. So, where's the best place to start? What I've been doing: - Watched the peepcode - Working my way through Stuart's book - Playing with netbean's GUI designer Is it possible to use the netbean designer and clojure at the same time? What's the best way of doing that? I'm used to writing GUIs in C++, would Clojure have a drastically different approach (as far as application logic and event handling)? I've not done much GUI work in Clojure yet, but what I have done has not involved any GUI builders. Just Clojure functions, some calling Swing methods. A lot simplifies once you have some useful utility functions and macros. For example: (defmacro jbutton Creates a JButton with the specified text, which when clicked executes the body with an ActionEvent bound to event. [text [event] body] `(let [b# (JButton. ~text)] (.addActionListener b# (proxy [ActionListener] [] (actionPerformed [~event] ~...@body) (defn add-all Adds the specified things, in order to obj. Useful for obj = a Swing JPanel with a BoxLayout or a FlowLayout and things = Swing components. [obj things] (doseq [thing things] (.add obj thing))) (defn box-layout-panel Given a JPanel or other component that can have a layout, gives it a BoxLayout with the specified orientation. [panel orientation] (.setLayout panel (BoxLayout. panel orientation))) (defn horizontal-box-layout-panel Given a JPanel or other component that can have a layout, gives it a BoxLayout with horizontal orientation. ([panel] (box-layout-panel panel BoxLayout/LINE_AXIS) panel) ([] (horizontal-box-layout-panel (JPanel. (defn horizontal-glue [] (Box/createHorizontalGlue)) (defn left-component Given a JComponent, returns a component that will try to display it at its preferred size on the left side of its container. [component] (let [result (horizontal-box-layout-panel)] (.add result component) (.add result (horizontal-glue)) result)) (defn combine-borders Combines multiple borders into one. The first argument will be the outermost, followed by the next argument, and the next; the last argument will be the innermost. ([border] border) ([outer inner] (BorderFactory/createCompoundBorder outer inner)) ([outermost nxt more] (reduce combine-borders (cons outermost (cons nxt more) and so forth. I've even got: (def *instruction-columns* 60) (def *instruction-inset* 10) (defn instructions Turns strings, or other objects, using str, into instruction text and returns a component suitable for displaying these in a Swing UI. [ strings] (doto (JTextArea. (apply str strings)) (.setEditable false) (.setLineWrap true) (.setWrapStyleWord true) (.setColumns *instruction-columns*) (.setOpaque false) (.setBorder (combine-borders (lowered-bevel-border) (empty-border *instruction-inset*) which produces a component that displays essentially a multi-line label with a 10-pixel space around its perimeter; as the name says, useful for putting instruction strings in a dialog box or whatever without worrying about where to put manual line breaks. I've used this in wizards, which often have large chunks of textual instructions as well as a few form fields and back, next, cancel buttons. Naturally, other code does things like take a passed-in JPanel and pop up a JDialog with a specified title, the JPanel front and center, and OK and Cancel buttons or similar at the bottom, with a supplied block of code to execute when OK is pressed and the behavior that both Cancel and the close button close and dispose the JDialog without doing anything; the macro for this expands into code that evaluates to nil on cancel and whatever the OK code returns on OK. It can take as little as ten minutes to slap something like one of these things together and another ten to test it. With these kinds of reusable UI fragments, both framed elements (like jbutton and instructions generate) and framing ones (like the JDialog generator macro), slapping together a GUI in code becomes easy. You might have noticed indications of my preference for using
Re: Newbie question: Writing a GUI with clojure
We use NetBeans' matisse designer for static form layout, and we hook up the components' behaviour using clojure. This is pretty easy, especially if you configure matisse to expose the components in a form by creating them with 'public final' visibility, thereby making them a (.componentName component) call away. - Chas On Aug 4, 2009, at 10:33 PM, Joe Van Dyk wrote: Hey, New to Java and Clojure. My possibly relevant experience is with Gtk and Ruby and C++ programming. I'd like to develop a GUI in Clojure. I'm guessing I want to use Swing. This application will be targeted towards scientists who are used to working with the most horribly-designed Tk UI known to man, so I'm sure they will be fine with Swing. So, where's the best place to start? What I've been doing: - Watched the peepcode - Working my way through Stuart's book - Playing with netbean's GUI designer Is it possible to use the netbean designer and clojure at the same time? What's the best way of doing that? I'm used to writing GUIs in C++, would Clojure have a drastically different approach (as far as application logic and event handling)? --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
clojure.zip keywords
Having finally dug into clojure.zip and contrib's zip-filter, I eventually needed a zipper? (or loc?) fn. Thinking I'd just check for the existence of one of the keys in each loc's metadata, I noticed that clojure.zip is using unusual keywords in that metadata, e.g.: #^{:zip/branch? branch? :zip/children children :zip/make-node make-node} I was fully expecting those keywords to be in the clojure.zip namespace (e.g. ::branch? ::children? ::make-node); the way things are now, they're in the zip namespace. Is this correct/intentional? It feels like the code was written when the reader had slightly different behaviour w.r.t. namespaced keywords. - Chas --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Reflection warning: reference to field getClass can't be resolved.
2009/8/5 John Harrop jharrop...@gmail.com On Tue, Aug 4, 2009 at 7:46 PM, Vagif Verdi vagif.ve...@gmail.com wrote: When reflection warning is on, i get 2 warnings on every my file: reference to field getClass can't be resolved. That one is very weird, because getClass is a method of java.lang.Object. It should always be possible to resolve that one without reflection. getClass is a method ... --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
partition-like function
Hey all, I'm looking for a variation on partition. user=(def my-vec [:a :b :c :d :e]) ;normal behavior user=(partition 2 my-vec) ((:a :b) (:c :d)) The behavior I want is user=(psuedo-partition 2 my-vec) ((:a :b) (:c :d) (:e)) Any suggestions? Sean --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: partition-like function
Try partition-all in clojure.contrib.seq-utils On Aug 5, 10:38 am, Sean Devlin francoisdev...@gmail.com wrote: Hey all, I'm looking for a variation on partition. user=(def my-vec [:a :b :c :d :e]) ;normal behavior user=(partition 2 my-vec) ((:a :b) (:c :d)) The behavior I want is user=(psuedo-partition 2 my-vec) ((:a :b) (:c :d) (:e)) Any suggestions? Sean --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: partition-like function
Perfect! On Aug 5, 1:51 pm, Mark Addleman mark_addle...@bigfoot.com wrote: Try partition-all in clojure.contrib.seq-utils On Aug 5, 10:38 am, Sean Devlin francoisdev...@gmail.com wrote: Hey all, I'm looking for a variation on partition. user=(def my-vec [:a :b :c :d :e]) ;normal behavior user=(partition 2 my-vec) ((:a :b) (:c :d)) The behavior I want is user=(psuedo-partition 2 my-vec) ((:a :b) (:c :d) (:e)) Any suggestions? Sean- Hide quoted text - - Show quoted text - --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: partition-like function
See partition-all in seq-utils. user= (partition-all 2 my-vec) ((:a :b) (:c :d) (:e)) On Wed, Aug 5, 2009 at 6:38 PM, Sean Devlinfrancoisdev...@gmail.com wrote: Hey all, I'm looking for a variation on partition. user=(def my-vec [:a :b :c :d :e]) ;normal behavior user=(partition 2 my-vec) ((:a :b) (:c :d)) The behavior I want is user=(psuedo-partition 2 my-vec) ((:a :b) (:c :d) (:e)) Any suggestions? Sean --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: partition-like function
Though you may need to do something like (flatten (nnext (partition-all 2 my-vec))) due to certain properties of partition-all: user= (partition-all 2 [1 2 3 4 5 6 7]) ((1 2) (3 4) (5 6) (7)) I'd be happy to hear a better option, since I actually just wrote code that did something like this the other day. On Wed, Aug 5, 2009 at 6:43 PM, Benjamin Stewartbstew...@gmail.com wrote: See partition-all in seq-utils. user= (partition-all 2 my-vec) ((:a :b) (:c :d) (:e)) On Wed, Aug 5, 2009 at 6:38 PM, Sean Devlinfrancoisdev...@gmail.com wrote: Hey all, I'm looking for a variation on partition. user=(def my-vec [:a :b :c :d :e]) ;normal behavior user=(partition 2 my-vec) ((:a :b) (:c :d)) The behavior I want is user=(psuedo-partition 2 my-vec) ((:a :b) (:c :d) (:e)) Any suggestions? Sean --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Build error in latest clojure checkout
I just reinstalled my Clojure environment using the Emacs Starter Kit + Clojure Mode. The M-x clojure-install command has worked fine in the past, but this time, it hits an error in compiling PersistentArrayMap.java: -- Begin output --- clean: init: [mkdir] Created dir: /Users/chad/src/clojure/clojure/classes init-version: [copy] Copying 1 file to /Users/chad/src/clojure/clojure compile-java: [javac] Compiling 132 source files to /Users/chad/src/clojure/clojure/classes [javac] /Users/chad/src/clojure/clojure/src/jvm/clojure/lang/PersistentArrayMap.java:333: cannot find symbol [javac] symbol : method copyOf(java.lang.Object[],int) [javac] location: class java.util.Arrays [javac] return new PersistentArrayMap(Arrays.copyOf(array, len)); [javac] ^ [javac] Note: Some input files use unchecked or unsafe operations. [javac] Note: Recompile with -Xlint:unchecked for details. [javac] 1 error BUILD FAILED /Users/chad/src/clojure/clojure/build.xml:82: Compile failed; see the compiler error output for details. Total time: 3 seconds -- End output --- The M-x clojure-install command checks out the latest clojure using: git clone git://github.com/richhickey/clojure.git so I am assuming that this is a recently-introduced issue. Does anyone know what is going on here? Thanks for your help, Chad Harrington chad.harring...@gmail.com --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Package manager proposal
On 5 Aug., 12:07, Meikel Brandmeyer m...@kotka.de wrote: Any CLR experts around? How does the packaging work there? Well, there's NMaven: http://nmaven.codeplex.com/Wiki/View.aspx?title=Getting%20Started - not sure, though, how popular this is. The CLR has a built-in versioning concept, which may have an impact on the design for a packaging system for .NET. Claus --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Clojure as a First Language
First of all, sorry that this post is so long-winded. I don't have a blog, so this seems like the best place to put to words something I've been thinking about for a while. One subject I haven't seen discussed is that of Clojure as a first language. By that I mean, the programming language that a person first learns before learning any other programming language. I'm no expert at computer programming, which is why this subject interests me in the first place, but I do think there is a strong case for Clojure's candidacy as a novice's first language. I'm not sure if I can call Clojure my first language. I've taken a 101 and 102 course in Java. I've dabbled in Python, Ruby, and even Io, in order of precedence. But I've never done any significant work or projects. I read a lot about programming, I subscribe to many of the programming rss feeds, but I only ever write code when it delights me, not because I have to. And, of most of the languages I've tried, the languages eventually got in the way and I lost interest. To my delight, Clojure doesn't get in my way. I can hack and play and explore with minimal fuss. I've now written more in Clojure than any other language. Now, as to whether my positive experience with Clojure is indicative of Clojure's appropriateness as a first language, I have to ask myself whether, in all my years on the sidelines of programming, I've unconsciously progressed and am no longer a novice. In other words, am I a good subject for this discussion -- a case study on Clojure as a first language? I think I am, but perhaps other programming novices like me can un-lurk, chime in, and give their experiences. Seeing as how Clojure is geared towards functional programming, one might think these really advanced concepts of macros, immutability, laziness, etc., aren't suitable for beginners. In fact, I think languages like Haskel have created a stigma around functional programming. A friend of mine is in the same boat as I am and I can't get him to try Clojure because he doesn't feel like he can dive in to functional programming at this point. True, Clojure has some advanced concepts, but I've written some neat toy programs in Clojure so far (a small chat server/client, a cellular automaton, some cli tools) and I haven't used any macros, multi-methods, parameter destructuring, or any other gizmos. I feel confident I'll move on to those when I'm ready. So yes, Clojure is advanced but it is also simple and easy to understand. This is due in part to the homoiconicity of Clojure (and Lisp). As a novice, I can immediately recognize the benefits of homoiconicity, as it lowers the bar to entry – my impression is that it provides a more uniform canvas on which to paint, where I can say if this works here, then it will also work there. The transactional memory, as it has often been compared to garbage collection, has also significantly lowered the bar to entry for novices like myself. I first wrote my multi-threaded chat server/client in Java and my Clojure version is much more readable. The Java version worked but the Clojure version worked correctly. I know that it's also been argued in academic circles that Scheme (or some functional language) should be one's first language, not Basic, because it teaches you to think about programming the right way the first time. I can't speak with them as an expert but I can say that if they are right, Clojure makes even more sense. This has been my experience. Even as a novice, Clojure's access to Java libraries has enabled me to experiment and learn on my own. Keep in mind, I'm only doing it because it's fun – There's nothing forcing me to write code. Now, with that being said, if it's true that Clojure is indeed a good candidate for a first language, is that worth anything? I hope I've stimulated some thought (and discussion) about the relationship between Clojure and novice programmers, but I also want to argue for taking this aspect of Clojure into account when creating the future of Clojure and it's libraries. Accommodating novices as a first language doesn't have to be a stated design goal, but it should at least be known that the simplicity of Clojure is a win for novices everywhere, and that can only benefit Clojure. Specifically, I would ask, can Clojure be kept simple? Can it even move towards more simplicity? If two future features in Clojure overlap to some degree, can they be combined, for the sake of simplicity? More simplicity might cause a knee-jerk reaction in some people's minds, but it can be argued that simplifying some things, like abstracting the first/rest cons-cell notion from lists on to the rest of Clojure's data-structures, has made Clojure more powerful. For me, it's also made things easier to understand. As a side note, I'd like to add that the helpfulness and maturity of the Clojure community is also a win for novices using Clojure. Please, keep being awesome and helpful and keep gently
Re: Clojure as a First Language
I've also given this subject some thought when I was deciding on what language I should use to teach first time programmers. In the end, I ultimately decided against teaching Clojure as someone's first language, but would like to transition into Clojure as soon as possible. ---These were my reasons for wanting to teach Clojure:--- -Simple syntax. Students should learn that learning programming is not learning syntax. I don't want their concepts to be muddled because of tedious syntax. -Functional programming. Students should learn how to write programs in as organized and in as general a fashion as possible. Functional programming also emphasizes recursion, which is a method of thinking that should be taught early I think. -No objects. In my opinion, OOP is taught way too early nowadays, which results in students writing monolithic inheritance structures. ---These were my reasons finally against teaching Clojure as a first language.--- -Immutability. I think for a beginner, mutability is easier to understand. Immutable data structures are quite a bit more complicated, but most importantly, their advantages are not seen by someone who has never programmed before. For this reason, Clojure's STM is unnecessarily confusing for beginners. Imagine trying to explain why you need the dosync command when trying to set a ref. -No Syntax. As good as lisp syntax is, it's not what the rest of the world uses. Algorithms are almost always explained using C, or Java, or some other C-like pseudocode. Beginner's need to be able to read these algorithms. -Less Resources. As great as the Clojure community is, it's still easier to look and ask for help with a Java program than it is with a Clojure program. And this is important, because beginners will need A LOT of help and resources. -Java interop. One of Clojure's greatest strengths is its seamless integration with Java. But I found that you require a decent knowledge of Java first to understand how to use it. For example, (Math/ sqrt ...) and (.add object ..) why do these functions look different from normal Clojure functions? What's the difference between the two? What does the (new) command do? So I found that since you really need to learn Java anyway (to some degree) to use Clojure, you might as well learn Java first. Just my thoughts -Patrick --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Package manager proposal
On Aug 4, 2:44 pm, Sean Devlin francoisdev...@gmail.com wrote: James, Just go for it. You've certainly proved you can design a library. Deliver something that works for you, and tell us if you think it's ready. If it's better than other stuff (which I suspect it will be), the community will start using it. If not, back to the drawing board. You're probably right. I'll try and knock something up this weekend that demonstrates the basic concepts. Regarding compatibility with Ivy and Maven, that should be relatively straightforward. There could be a gateway server that transforms the metadata from the Maven repository into whatever format Clod will use. I'm also wondering whether or not I could construct a package manager that operates from within the REPL. Hmm. - James --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Package manager proposal
I'm also wondering whether or not I could construct a package manager that operates from within the REPL. Hmm. Well, if it's written in Clojure you get this one for free right? BECAUSE THAT WOULD BE AWESOME! --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Build error in latest clojure checkout
Chad Harrington napisał(a): I just reinstalled my Clojure environment using the Emacs Starter Kit + Clojure Mode. The M-x clojure-install command has worked fine in the past, but this time, it hits an error in compiling PersistentArrayMap.java: -- Begin output --- clean: init: [mkdir] Created dir: /Users/chad/src/clojure/clojure/classes init-version: [copy] Copying 1 file to /Users/chad/src/clojure/clojure compile-java: [javac] Compiling 132 source files to /Users/chad/src/clojure/clojure/classes [javac] /Users/chad/src/clojure/clojure/src/jvm/clojure/lang/PersistentArrayMap.java:333: cannot find symbol [javac] symbol : method copyOf(java.lang.Object[],int) [javac] location: class java.util.Arrays [javac] return new PersistentArrayMap(Arrays.copyOf(array, len)); [javac] ^ [javac] Note: Some input files use unchecked or unsafe operations. [javac] Note: Recompile with -Xlint:unchecked for details. [javac] 1 error BUILD FAILED /Users/chad/src/clojure/clojure/build.xml:82: Compile failed; see the compiler error output for details. Total time: 3 seconds -- End output --- The M-x clojure-install command checks out the latest clojure using: git clone git://github.com/richhickey/clojure.git so I am assuming that this is a recently-introduced issue. Does anyone know what is going on here? It works for me: $ git pull Already up-to-date. $ git log HEAD^! commit 2098f5d57ecf3affb09a4cdaf2e01ad4de861eef Author: Rich Hickey richhic...@gmail.com Date: Wed Aug 5 14:29:32 2009 -0400 replace copyOf with arrayCopy $ java -version java version 1.5.0_09 Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_09-b03) Java HotSpot(TM) Client VM (build 1.5.0_09-b03, mixed mode, sharing) Last commit seems to solve the problem you mentioned. HTH, Rob --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Build error in latest clojure checkout
Yes. The recent commit fixed the problem and I am back up and running. I guess that's the problem with living on the bleeding edge... Chad Harrington chad.harring...@gmail.com On Wed, Aug 5, 2009 at 1:29 PM, Rob Wolfe r...@smsnet.pl wrote: Chad Harrington napisał(a): I just reinstalled my Clojure environment using the Emacs Starter Kit + Clojure Mode. The M-x clojure-install command has worked fine in the past, but this time, it hits an error in compiling PersistentArrayMap.java: -- Begin output --- clean: init: [mkdir] Created dir: /Users/chad/src/clojure/clojure/classes init-version: [copy] Copying 1 file to /Users/chad/src/clojure/clojure compile-java: [javac] Compiling 132 source files to /Users/chad/src/clojure/clojure/classes [javac] /Users/chad/src/clojure/clojure/src/jvm/clojure/lang/PersistentArrayMap.java:333: cannot find symbol [javac] symbol : method copyOf(java.lang.Object[],int) [javac] location: class java.util.Arrays [javac] return new PersistentArrayMap(Arrays.copyOf(array, len)); [javac] ^ [javac] Note: Some input files use unchecked or unsafe operations. [javac] Note: Recompile with -Xlint:unchecked for details. [javac] 1 error BUILD FAILED /Users/chad/src/clojure/clojure/build.xml:82: Compile failed; see the compiler error output for details. Total time: 3 seconds -- End output --- The M-x clojure-install command checks out the latest clojure using: git clone git://github.com/richhickey/clojure.git so I am assuming that this is a recently-introduced issue. Does anyone know what is going on here? It works for me: $ git pull Already up-to-date. $ git log HEAD^! commit 2098f5d57ecf3affb09a4cdaf2e01ad4de861eef Author: Rich Hickey richhic...@gmail.com Date: Wed Aug 5 14:29:32 2009 -0400 replace copyOf with arrayCopy $ java -version java version 1.5.0_09 Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_09-b03) Java HotSpot(TM) Client VM (build 1.5.0_09-b03, mixed mode, sharing) Last commit seems to solve the problem you mentioned. HTH, Rob --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Newbie question: Writing a GUI with clojure
On Aug 5, 6:53 am, Chas Emerick cemer...@snowtide.com wrote: We use NetBeans' matisse designer for static form layout, and we hook up the components' behaviour using clojure. This is pretty easy, especially if you configure matisse to expose the components in a form by creating them with 'public final' visibility, thereby making them a (.componentName component) call away. You wouldn't want to whip up a quick example (or blog post) for me, would ya? --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Newbie question: Writing a GUI with clojure
On Aug 5, 6:01 am, John Harrop jharrop...@gmail.com wrote: On Tue, Aug 4, 2009 at 10:33 PM, Joe Van Dyk joevan...@gmail.com wrote: Hey, New to Java and Clojure. My possibly relevant experience is with Gtk and Ruby and C++ programming. I'd like to develop a GUI in Clojure. I'm guessing I want to use Swing. This application will be targeted towards scientists who are used to working with the most horribly-designed Tk UI known to man, so I'm sure they will be fine with Swing. So, where's the best place to start? I've not done much GUI work in Clojure yet, but what I have done has not involved any GUI builders. Just Clojure functions, some calling Swing methods. A lot simplifies once you have some useful utility functions and macros. For example: snip Thanks for the code! I'll definitely use it when needing to add/ modify GUI widgets. There's no official swing wrapper in clojure yet, right? Joe --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Improving Clojure's primitive handling (warning: not thought through)
On Aug 5, 2009, at 5:00 PM, Joe Van Dyk wrote: On Aug 4, 8:02 am, Mark Addleman mark_addle...@bigfoot.com wrote: I think there may be a somewhat straightforward solution to improving Clojure's performance when passing primitives between functions. Here's my understanding of the problem: The IFn interface is a series of invoke method signatures that take a number of java.lang.Objects as parameters and returns a java.lang.Object. Primitives can't be passed this way and it would be a silly explosion of code to create the methods signatures in IFn that included primitives. The performance characteristcs of boxing primitives relies on the JVM's performance of allocating and deallocating objects. What's meant by boxing? See: http://en.wikipedia.org/wiki/Autoboxing#Autoboxing - Chas --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Transient Data Structures
I really, really like this feature. My only complaint is that you have to use different names for the modifying functions. If the function signatures will be identical to their non-transient variants, then I guess the primary arguments would be: * Clojure convention for names of functions with side-effects, * An additional interface check in conj/assoc? But if after calling (conj v 1), you can't use the 'v' reference anymore, then did you really cause a side effect? Its another tree falling in the woods situation. Thanks, Stu On Wed, Aug 5, 2009 at 9:05 AM, Rich Hickey richhic...@gmail.com wrote: On Tue, Aug 4, 2009 at 10:13 PM, John Harropjharrop...@gmail.com wrote: On Tue, Aug 4, 2009 at 5:50 PM, Rich Hickey richhic...@gmail.com wrote: On Aug 4, 4:31 pm, John Harrop jharrop...@gmail.com wrote: What about things like: (persistent! (reduce (fn [x [i v]] (assoc! x i v)) (transient (vec (repeat 0 (reduce max (map first coll-of-index-val-pairs) coll-of-index-val-pairs)) Yes, that's completely fine intended usage, as the return value of the reducing fn becomes an argument to the next call. which is just the transientification of Nice word - transientification. Thanks. Of course, this makes me think of ways to possibly speed up other operations. For example: (defn vmap* [fun vect] (let [c (count vect)] (loop [out (transient []) i 0] (if (= i c) out (recur (conj! out (fun (nth vect i))) (inc i)) (defn vmap [fun vect] (persistent! (vmap* fun vect))) Vector in, vector out, conj'd up using a transient. Mapping into vectors and similar ops are coming, although nothing like vmap* would ever be exposed. And, of course: (defn vpmap [fun vect] (loop [out (vmap* #(future (fun %)) vect) i (dec (count vect))] (let [o2 (assoc! out i @(nth out i))] (if (zero? i) (persistent! o2) (recur o2 (dec i) Note that this last manipulates a transient vector in a single thread, though other threads (from the agent pool) calculate a bunch of futures that are stored in it. The transient vector of futures is generated using the vmap* from above, and then the futures are replaced with their values in-place by the loop in vpmap, before this persistentizes and returns that vector. The future-dereferencing loop works backwards from the end of the vector in case zero? is a quicker test than a general equality test. This is likely on hardware that implements an equality test as a subtraction followed by a zero test, because it eliminates the subtraction. On the other hand, hardware with a 1-cycle equality test of 32-bit ints is plausible, as is hardware that optimizes forward traversal of vectors, so I can't vouch for that being an optimization. The first loop has to go forward to conj up the output vector without reversing it, though. There is already a very nice pvmap in the par branch that uses ForkJoin. I strongly recommend against trying to write parallel ops with transients - that's not what they are for. What's nice about pvmap is that, just like transients, it also takes, manipulates, and returns ordinary Clojure vectors (unlike the old parallel lib which copied into and out of ForkJoin's ParallelArrays). The goal is to make using the normal data structures as powerful as possible, and not needing to switch to something else for performance. 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Newbie question: Writing a GUI with clojure
On Aug 6, 6:51 am, Joe Van Dyk joevan...@gmail.com wrote: You wouldn't want to whip up a quick example (or blog post) for me, would ya? Taking a quick look in the files section of this group found this: http://clojure.googlegroups.com/web/clojure-gui-and-netbeans.pdf?hl=engda=f1jT-U4AAAC-wnUK1KQ919yJcmM1ACuZF_7r2-2rkSjhF_gc_N1Bbpenpc0tTgTfOT8mbP3D_UHFOPRGngYCB6zi_choflON47Cl1bPl-23V2XOW7kn5sQ =) JG --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Newbie question: Writing a GUI with clojure
I normally go to the swing tutorials on Sun's website when I have questions. I'm writing a GUI in clojure. I'm using IntelliJ's (not great) FormDesigner. Clojure is in some sense 'on top of' Java, since it uses the Java libs. Writing a Swing GUI in Clojure hasn't been that much different than writing it in java, except that you can automate away a lot of the ceremony that Swing so loves. Many people hate layout managers and just lay things out with XYLayout. It certainly makes it easier to lay something out if you're not using a visual designer type package. The only real trick to using swing is understanding that most everything that modifies the UI has to happen in the event thread. So, if you, say, have a cancel button in a dialog for a long operation, and the cancel button goes away when the operation completes (assuming the dialog stays open, maybe to display some results) then you need to use SwingWorker to run the code that removes the button in the proper thread. Fortunately this doesn't apply to most property settings, so if you change the text in a label or turn a button green you're OK. And of course if you click a button and that makes another button go away, that's fine, since you're already IN the event thread. --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Transient Data Structures
On Aug 5, 7:48 pm, Stu Hood stuh...@gmail.com wrote: I really, really like this feature. My only complaint is that you have to use different names for the modifying functions. If the function signatures will be identical to their non-transient variants, then I guess the primary arguments would be: * Clojure convention for names of functions with side-effects, * An additional interface check in conj/assoc? But if after calling (conj v 1), you can't use the 'v' reference anymore, then did you really cause a side effect? Its another tree falling in the woods situation. Not at all. The normal persistent functions, e.g. conj/assoc, make a promise that the thing they return *can* be held onto, indefinitely, and immutably, and reused, thus 'persistent'. Calling an operation that does not make those guarantees the same thing would be destroying that promise. The names have to be different. 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Clojure as a First Language
John, I hope that learning a Lisp first is a good idea for novice programmers, because I intend to inflict Clojure on my poor children. (They didn't take to http://scratch.mit.edu/ and Google's rehash of BASIC is a non-starter). So far I have just a few reasons for picking Clojure as a first language: * Like big dogs, hopefully growing up with parentheses teaches the kids to respect instead of fear them. * The syntax is minimal, consistent, and as you noted designed with simplicity as a priority. Obviously my lesson isn't ready yet, but the course has been charted. Seth On Aug 5, 2:44 pm, John Newman john...@gmail.com wrote: First of all, sorry that this post is so long-winded. I don't have a blog, so this seems like the best place to put to words something I've been thinking about for a while. One subject I haven't seen discussed is that of Clojure as a first language. By that I mean, the programming language that a person first learns before learning any other programming language. I'm no expert at computer programming, which is why this subject interests me in the first place, but I do think there is a strong case for Clojure's candidacy as a novice's first language. I'm not sure if I can call Clojure my first language. I've taken a 101 and 102 course in Java. I've dabbled in Python, Ruby, and even Io, in order of precedence. But I've never done any significant work or projects. I read a lot about programming, I subscribe to many of the programming rss feeds, but I only ever write code when it delights me, not because I have to. And, of most of the languages I've tried, the languages eventually got in the way and I lost interest. To my delight, Clojure doesn't get in my way. I can hack and play and explore with minimal fuss. I've now written more in Clojure than any other language. Now, as to whether my positive experience with Clojure is indicative of Clojure's appropriateness as a first language, I have to ask myself whether, in all my years on the sidelines of programming, I've unconsciously progressed and am no longer a novice. In other words, am I a good subject for this discussion -- a case study on Clojure as a first language? I think I am, but perhaps other programming novices like me can un-lurk, chime in, and give their experiences. Seeing as how Clojure is geared towards functional programming, one might think these really advanced concepts of macros, immutability, laziness, etc., aren't suitable for beginners. In fact, I think languages like Haskel have created a stigma around functional programming. A friend of mine is in the same boat as I am and I can't get him to try Clojure because he doesn't feel like he can dive in to functional programming at this point. True, Clojure has some advanced concepts, but I've written some neat toy programs in Clojure so far (a small chat server/client, a cellular automaton, some cli tools) and I haven't used any macros, multi-methods, parameter destructuring, or any other gizmos. I feel confident I'll move on to those when I'm ready. So yes, Clojure is advanced but it is also simple and easy to understand. This is due in part to the homoiconicity of Clojure (and Lisp). As a novice, I can immediately recognize the benefits of homoiconicity, as it lowers the bar to entry – my impression is that it provides a more uniform canvas on which to paint, where I can say if this works here, then it will also work there. The transactional memory, as it has often been compared to garbage collection, has also significantly lowered the bar to entry for novices like myself. I first wrote my multi-threaded chat server/client in Java and my Clojure version is much more readable. The Java version worked but the Clojure version worked correctly. I know that it's also been argued in academic circles that Scheme (or some functional language) should be one's first language, not Basic, because it teaches you to think about programming the right way the first time. I can't speak with them as an expert but I can say that if they are right, Clojure makes even more sense. This has been my experience. Even as a novice, Clojure's access to Java libraries has enabled me to experiment and learn on my own. Keep in mind, I'm only doing it because it's fun – There's nothing forcing me to write code. Now, with that being said, if it's true that Clojure is indeed a good candidate for a first language, is that worth anything? I hope I've stimulated some thought (and discussion) about the relationship between Clojure and novice programmers, but I also want to argue for taking this aspect of Clojure into account when creating the future of Clojure and it's libraries. Accommodating novices as a first language doesn't have to be a stated design goal, but it should at least be known that the simplicity of Clojure is a win for novices everywhere, and that can only benefit Clojure. Specifically,
Re: Transient Data Structures
I like this very much... that's the kind of clever optimizations that preserves Clojure principles and can yield significant performance increases. This could also help dealing with performance critics in these small mutable languages benchmarks that newbies attempt to clone in Clojure. Thank's Rich ! Luc On Wed, 2009-08-05 at 17:09 -0700, Rich Hickey wrote: On Aug 5, 7:48 pm, Stu Hood stuh...@gmail.com wrote: I really, really like this feature. My only complaint is that you have to use different names for the modifying functions. If the function signatures will be identical to their non-transient variants, then I guess the primary arguments would be: * Clojure convention for names of functions with side-effects, * An additional interface check in conj/assoc? But if after calling (conj v 1), you can't use the 'v' reference anymore, then did you really cause a side effect? Its another tree falling in the woods situation. Not at all. The normal persistent functions, e.g. conj/assoc, make a promise that the thing they return *can* be held onto, indefinitely, and immutably, and reused, thus 'persistent'. Calling an operation that does not make those guarantees the same thing would be destroying that promise. The names have to be different. Rich Luc Préfontaine Armageddon was yesterday, today we have a real problem... --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Newbie question: Writing a GUI with clojure
I'll second the book recommendation, have the hacks sitting here on my desk and has been very useful so far. I've found that the easiest way for me to do UIs has been to write helper functions that make the components and stitch them together then return them inside hashmaps. Then I write a bunch of other functions that add listeners (or that return functions which add listeners) onto the different components that I stored in hashmaps. I'm still a little bit wary of the performance implications of doing it that way, but so far it has made my UIs code a lot more intelligible (I think), than using a lot of Java directly. On Aug 4, 10:33 pm, Joe Van Dyk joevan...@gmail.com wrote: Hey, New to Java and Clojure. My possibly relevant experience is with Gtk and Ruby and C++ programming. I'd like to develop a GUI in Clojure. I'm guessing I want to use Swing. This application will be targeted towards scientists who are used to working with the most horribly-designed Tk UI known to man, so I'm sure they will be fine with Swing. So, where's the best place to start? What I've been doing: - Watched the peepcode - Working my way through Stuart's book - Playing with netbean's GUI designer Is it possible to use the netbean designer and clojure at the same time? What's the best way of doing that? I'm used to writing GUIs in C++, would Clojure have a drastically different approach (as far as application logic and event handling)? --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Transient Data Structures
On Aug 3, 8:39 pm, Rich Hickey richhic...@gmail.com wrote: In short, the O(1) overhead is less than the cost of even a single edit. So, e.g. into/vec/vector now use transients unconditionally if possible. Rich Are we going to feel a big performance boost once all of the core functions are rewritten using transients? I can't wait. Are hashmaps next? I can think of a few places in my code that would definitely benefit from them. Eric --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
gen-class not capturing the expected *ns*
In testing out clojure.contrib.logging within a generated servlet, I noticed that the value of *ns* is always clojure.core, and not the ns of the code. I just wanted to make sure I wasn't missing something obvious. The servlet code: (ns com.example.servlet (:require (clojure.contrib [logging :as log])) (:import (javax.servlet.http HttpServlet HttpServletRequest HttpServletResponse)) (:gen-class :extends javax.servlet.http.HttpServlet)) (defn -doGet [this #^HttpServletRequest req #^HttpServletResponse resp] (.. resp getWriter (println *ns*))) Expected response: com.example.servlet Actual response: clojure.core --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: gen-class not capturing the expected *ns*
In testing out clojure.contrib.logging within a generated servlet, I noticed that the value of *ns* is always clojure.core, and not the ns of the code. I have observed this too (running in SailFin, which is based on GlassFish). Expected response: com.example.servlet Actual response: clojure.core I don't think so. Remember, this'll print the current binding of *ns* when that function is invoked, not at compile time. Counter-example: user= (ns foo (:refer-clojure)) nil foo= (defn bar [] (println *ns*)) #'foo/bar foo= (bar) #Namespace foo nil foo= (ns baz (:refer-clojure)) nil baz= (foo/bar) #Namespace baz nil The important thing is the binding of *ns* in the thread that invokes your servlet. I don't know of a way to control that. -R --~--~-~--~~~---~--~~ 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---