Re: Lazy load of imports
On Jun 12, 10:31 am, Chouser chou...@gmail.com wrote: On Thu, Jun 11, 2009 at 8:48 PM, Stephen C. Gilardisquee...@mac.com wrote: Do you think there will be any performance hits. I haven't run any tools on it. In looking around the reflection-related code in clojure.lang, it looks to me like the performance of new-by-name should be similar to that of other Clojure code that uses reflection rather than direct calls. I think that's correct. In my experience a call that requires runtime reflection like this is on the order of 50 times slower than a method call that is made directly. Depending on how often it gets called, I think that would generally count as a performance hit. Another option you could consider: moving all code that requires that class into a separate .clj file, then using 'load' when you need it. This would allow you to AOT compile (or not) and suffer none of the runtime reflection cost. Yet another option would be to eval a constructor function. Something like: (defn make-foo [arg1 arg2] (eval `(defn ~'make-foo [a1# a2#] (Foo. a1# a2#))) (make-foo arg1 arg2)) Note that's not well tested. I'm not sure, but you may have trouble elsewhere if you try to type-hint Foo. But basically, that defines a make-foo such that the first time it's called it compiles a new make-foo that will actually create instances of Foo. This will be slow, but subsequent calls to make-foo should run at full compiled speed. Both those options may be pretty painful depending on what you're actually doing, so if I were you I'd try new-by-name first and only if you're sure it's too slow would I try another option. --Chouser If I do the dynamic call to load, and in my clojure script I have a namespace defined. Load will still work and I will be able to reference that namespace later? --~--~-~--~~~---~--~~ 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: breaking early from a tight loop
Hello James, Thank you for more examples. (count (take-while belowCount (filter identity (map isInteresting pixels This particular piece of code doesn't look like it would work, unless I've misunderstood what Vlad is asking. I think you'd want something more like: If I understood the Patrick's code right, it works as: 1. The (map isInteresting ...) returns lazy sequence of true/false values for each pixel (true for interesting pixel) 2. The (filter identity ...) returns a lazy sequence of only true values from the above 3. The (take-while belowCount ...) will return items of lazy sequence while the predicate belowCount holds. This implies that the predicate would have to be stateful (i.e. increment a counter on each invocation and return false when this counter == count-I- am-interested-in . So the take-while stops once the count is reached 4. the result of (count ...) would be compared with count-I-am- interested-in and if ==, the image is interesting (defn interesting? [pixels c] (= c (count (take c (filter in-interval? pixels) Where c is the number past which an image is considered interesting. However, if c is very large, then (take c ...) is going to result in a large sequence. The large sequence should not be a problem for this particular application. We'd probably want to define a function: (defn count-more-than? [n xs] (or (zero? n) (if (seq xs) (recur (dec n) (rest xs) (defn interesting? [pixels c] (count-more-than? c (filter in-interval? pixels))) Cheers, I will try to code different variants, see how fast they are, + report back at some point with the findings. Kind regards, Vlad --~--~-~--~~~---~--~~ 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: breaking early from a tight loop
Hi Vlad, I just realized that you don't need the take-while. (take num coll) will directly retrieve up-to num elements out of coll. Cheers -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: breaking early from a tight loop
On Jun 12, 9:44 pm, James Reeves weavejes...@googlemail.com wrote: (defn count-more-than? [n xs] (or (zero? n) (if (seq xs) (recur (dec n) (rest xs) (defn interesting? [pixels c] (count-more-than? c (filter in-interval? pixels))) Nice, but user= (count-more-than? 0 ()) true (defn count-more-than? [n xs] (if (seq xs) (or (zero? n) (recur (dec n) (rest xs) seems to work. :) --~--~-~--~~~---~--~~ 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: breaking early from a tight loop
kedu Wrexsoul user= (count-more-than? 0 ()) true (defn count-more-than? [n xs] (if (not (seq xs)) (or (zero? n) (recur (dec n) (rest xs) I'm afraid your code didn't return true for me. Just look at your code, (seq '()) will always give nil, so your code will return nil and not true. To get true from your code I guess the (seq xs) should be changed to (not (seq xs)). Or am I missing something? Emeka On Sat, Jun 13, 2009 at 6:02 PM, Wrexsoul d2387...@bsnow.net wrote: On Jun 12, 9:44 pm, James Reeves weavejes...@googlemail.com wrote: (defn count-more-than? [n xs] (or (zero? n) (if (seq xs) (recur (dec n) (rest xs) (defn interesting? [pixels c] (count-more-than? c (filter in-interval? pixels))) Nice, but user= (count-more-than? 0 ()) true (defn count-more-than? [n xs] (if (seq xs) (or (zero? n) (recur (dec n) (rest xs) seems to work. :) --~--~-~--~~~---~--~~ 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: Anyone planning on using Clojure for ICFP 2009?
On Thu, Jun 11, 2009 at 2:54 AM, Sethseth.schroe...@gmail.com wrote: So the 12th International Conference on Functional Programming is coming up soon. A few months before the event a programming contest is held, typically with very ambitious requirements in a short period of time (2-3 days). The 2009 contest will be held from Friday 26 to Monday 29 June and I would be surprised if they tightly restrict the acceptable languages. I submitted a fair/poor entry in Ruby last year (team Foognostic). I apologize if I've missed the obvious, but is anyone planning on using Clojure for the contest? There was a thread about this recently. http://groups.google.com/group/clojure/search?group=clojureq=ICFP -- Michael Wood esiot...@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: A few suggestions and useful things
Hi, Am 13.06.2009 um 02:45 schrieb Wrexsoul: I think this exists already somewhere in clojure.contrib.java-utils or so. Don't have that third-party library. Maybe clojure.contrib.duck-streams? Don't have that third-party library. Then you should check it out, no? Let's see. http://clojure.org/atoms firefox inc-search for reset Oops, not found. http://clojure.org/API gives a good overview. Sorry, the only way I'd have known about half of this was to actually read the api docs cover to cover, and for half of the other half, to download and install a third-party library and read ITS docs cover-to- cover. :) Well. That's the usual way to gather information: reading. The other usual way is asking other people - ie. this group or the #clojure channel. So whenever you do something ugly like set-atom! you should stop and think that there are other bright heads out there, which probably already solved that problem. It's actually a feature, that Clojure has a small core. Much more appealing than Common Lisp. And if you don't want to stress this group or the clojure channel, you might also use this magic google thing. At least it seems more appropriate than Firefox inc search Sincerely Meikel smime.p7s Description: S/MIME cryptographic signature
Re: A few suggestions and useful things
On Jun 13, 6:38 am, Wrexsoul d2387...@bsnow.net wrote: Here's a bit more, public domain as usual: (defn get-ultimate-cause [exception] (loop [e exception] (let [e2 (. e getCause)] (if-not e2 e (recur e2) I think something like this is in clojure-contrib as well. It's a semi- official add-on library for Clojure (You need a CA to contribute), so you should take a look at it :) Also, try using (find-doc foo) and (doc foo) in a repl for documentation searches. For this function, you might want to check out if-let. I have no idea how the docs on the website are generated. I don't like them much either, and they seem to fall off sync occasionally. :/ (defmacro with-stack-trace [ body] `(try (eval (quote (do ~...@body))) (catch Throwable ex# (. (get-ultimate-cause ex#) printStackTrace The golden rule: eval is almost always wrong. Why not simply `(try ~...@body (catch ...))? Improved with-stack-trace. I got an exception with causes stacked four deep, which printed at the repl with the final one ending ... 7 more and the line number in my own code that set it off buried in the elided portion, so I decided to hell with those really deeply nested exceptions Clojure tends to churn out. The get-ultimate-cause fn gets the exception at the root of the cause chain, and with-stack-trace now uses it. (defn map-preserve-raw [f coll keys?] (if (map? coll) (loop [m {} s coll] (if (empty? s) m (let [e (first s) k (first e) v (second e)] (recur (assoc m (if keys? (apply f [k]) k) (apply f [v])) (rest s) (let [x (map f coll)] (if (vector? coll) (vec x) (if (set? coll) (set x) x) Something like this is in contrib too, done with multimethods. Check out clojure.contrib.generic.functor maps also are sequenceable into a seq of [k v] pairs so instead of explicitly looping it's possible to do (into {} (map (fn [[k v]] [(if keys? (f k) k) (f v)]) coll); notice the destructuring in the lambda parameters and that it returns a vector. I don't see why you do (apply f [k])... That's equivalent to (f k) You could also use destructuring in the let form above: (let [[[k v] the-rest] s] ...) I also personally dislike functions that take a boolean parameter; if you must, at least make it optional, with default to false and then require users to pass in a keyword (keywords are true in a boolean context) like so: (map-preserve-raw inc {1 2, 3 4} :transform-keys-too) (defn map-preserve [f coll] (map-preserve-raw f coll false)) (defn map-code [f coll] (map-preserve-raw f coll true)) user=(map-preserve #(* 2 %) {:key1 3 :key2 17 :key3 1/2}) {:key3 1, :key2 34, :key1 6} Now one version map-preserve for transforming data and one map-code for transforming code for macro purposes. I should make the latter recursive. Done. (defn map-code [f code] (if (coll? code) (map-preserve-raw #(map-code f %) code true) (apply f [code]))) This makes with-derefs (part of super-lazy-seq) simpler: I didn't quite get your super-lazy-seq, but then again I didn't look at it in detail yet. It seems like it might make constructing lazy seqs easier, but I'd need more examples. The use of atoms feels dubious. It seems to me that you're emulating mutability with them. I might be wrong, but if there's any way to get rid of the atoms, it's worth the effort :) Not to mention file-seq already exists in core, implemented using tree- seq which is rather simple, so your example isn't very convincing. :/ (defn with-derefs [names code] (map-code #(if (and (symbol? %) (contains? names %)) (list 'deref %) %) code)) Tested, works. This new with-derefs is very clear: map-code if symbol in names deref it otherwise don't touch it. Abstracting this stuff helps readability, not just productivity. In fact ... (defn map-recursive-raw [f obj keys?] (if (coll? obj) (map-preserve-raw #(map-recursive-raw f % keys?) obj keys?) (apply f [obj]))) (defn map-recursive [f coll] (map-recursive-raw f coll false)) (defn map-code [f code] (map-recursive-raw f code true)) OK, I'm really done this time. I promise. --~--~-~--~~~---~--~~ 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: breaking early from a tight loop
Hi Laurent, I like how you distilled the problem down to a reduce with an early- exit. I'm interested in what you said about my suggestion: using map then filter then take then count, which will result in creating, for at least num pixels, at worst the full number of pixels, 2 conses, and 3 times walking the array. map filter and take are all lazy. so doesn't the array only get iterated through once? by count? --~--~-~--~~~---~--~~ 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: breaking early from a tight loop
On Jun 13, 9:17 pm, Laurent PETIT laurent.pe...@gmail.com wrote: This thread is interesting because we have a solution that is suggested : using map then filter then take then count, which will result in creating, for at least num pixels, at worst the full number of pixels, 2 conses, and 3 times walking the array. Well, the map is redundant - it's sufficient to just use filter. Second, because these are lazy sequences, we're only walking the array once, and not storing any more data than we need to. - 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: breaking early from a tight loop
2009/6/13 CuppoJava patrickli_2...@hotmail.com: Hi Laurent, I like how you distilled the problem down to a reduce with an early- exit. I'm interested in what you said about my suggestion: using map then filter then take then count, which will result in creating, for at least num pixels, at worst the full number of pixels, 2 conses, and 3 times walking the array. map filter and take are all lazy. so doesn't the array only get iterated through once? by count? Hi, Well, the array is iterated once by map, the new seq created by map is iterated once by filter, and the new seq created by filter is iterated once by count, so right, I should have written : 3 walks of seqs of the size of the array. While reduce would create no new seq, and one walk ? --~--~-~--~~~---~--~~ 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: breaking early from a tight loop
On Jun 13, 7:02 pm, Wrexsoul d2387...@bsnow.net wrote: Nice, but user= (count-more-than? 0 ()) true (defn count-more-than? [n xs] (if (seq xs) (or (zero? n) (recur (dec n) (rest xs) True enough. My code didn't take into account that edge case. - 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: breaking early from a tight loop
On Jun 13, 9:39 pm, Laurent PETIT laurent.pe...@gmail.com wrote: Well, the array is iterated once by map, the new seq created by map is iterated once by filter, and the new seq created by filter is iterated once by count, so right, I should have written : 3 walks of seqs of the size of the array. The filter and map functions produce lazy seqs, so the sequence is only walked once. - 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: breaking early from a tight loop
Hi, This thread is interesting because we have a solution that is suggested : using map then filter then take then count, which will result in creating, for at least num pixels, at worst the full number of pixels, 2 conses, and 3 times walking the array. What's more interesting to me is that the ultimate result is not to get a transformation of the input preserving the structure (a collection of pixels), but a reduced value. So it really seems to me that the missing abstraction, here, is being able to do a reduce over the list of pixels, and being able, from the reduction function, to quit the reduction early. If we had this function, then there would be no new cons, and just one walk of the list, while still being very functional. Here is how the enhanced version of reduce could work : (defn interesting? [pixels c] (reduce (fn [counter pixel] (if (in-interval? pixel) (inc counter) counter)) 0 pixels (partial c))) The new optional argument to reduce would be a function applied to the accumulated value before each invocation of the reducing function, and if it returns true, then reduce would quit and return the currently accumulated value. Another way to implement the new version of reduce would be by having the 4th parameter be an explicit early-return value, and let the do we return early ? test be part of the reduction function ? Do you see a value in implementing such a new function (or extension to existing reduce) ? Of course, if one does not want to implement the general problem solving solution, a good old walk via 'loop seems appealing to this exact problem (I presume walking over pixels would have to be as fast as possible) : (defn interesting? [pixels interest-threshold] (loop [count 0 pixels (seq pixels)] (cond (= count interest-threshold) true pixels (recur (if (in-interval? (first pixels)) (inc count) count) (next pixels)) :else false))) OK, ok, this one is rather verbose :-) Regards, -- Laurent 2009/6/13 CuppoJava patrickli_2...@hotmail.com: I'm glad I was helpful. You can try this approach first, and see if it meets your requirements. If it's still too slow you can drop down to loop/recur to eliminate the boxing overhead at the expense of some extra verbosity. -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: catching exception error
On Thu, Jun 11, 2009 at 7:12 PM, pegphilippe.gi...@gmail.com wrote: Hi clojurians, I was happily clojure-coding whent I tried to catch a exception in a thrown deeply in a function. After looking for the fact that the IllegalArgumentException wasn't catch, I added a catch RuntimeException to my catch list ... and that worked of course. Have a look at this thread: http://groups.google.com/group/clojure/browse_thread/thread/b719861006c7e52c/?lnk=gstq=wrap+RuntimeException -- Michael Wood esiot...@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: breaking early from a tight loop
2009/6/13 James Reeves weavejes...@googlemail.com: On Jun 13, 9:39 pm, Laurent PETIT laurent.pe...@gmail.com wrote: Well, the array is iterated once by map, the new seq created by map is iterated once by filter, and the new seq created by filter is iterated once by count, so right, I should have written : 3 walks of seqs of the size of the array. The filter and map functions produce lazy seqs, so the sequence is only walked once. Well, isn't walking 3 different sequences 1 time almost equivalent (in terms of computer work) to walking 3 times one sequence ? And nevertheless, if I insist, it's not really because there *could* be a performance problem (though I guess there will, but only benchmark would tell), but rather because the essence of the problem seems to be needing a simple reduction with early break capability, and no more :-) - James -- Cordialement, Laurent PETIT --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
EDT interaction
Now I'm working on some Swing code and came up with these, which are obviously going to be useful: (defmacro do-on-edt [ body] `(SwingUtilities/invokeLater #(do ~...@body))) (defmacro get-on-edt [ body] `(let [ret# (atom nil)] (SwingUtilities/invokeLater #(reset! ret# [(do ~...@body)])) (loop [] (let [r# @ret#] (if r# (first r#) (recur)) (defmacro future-on-edt [ body] `(future (get-on-edt ~...@body))) The do-on-edt macro executes its body on the EDT and returns nil. The get-on-edt macro does similarly, but returns whatever the body returns. It blocks until the body has returned, though, which you may not want, though since it executes on the EDT it should execute fast. The future-on-edt macro avoids this blocking behavior. It behaves as if you scheduled its body to run as a future on the EDT instead of on whatever thread(s) futures usually run on. In actual fact, the future it returns is executing the blocking get-on-edt. :) Action listener code can assume it will run on the edt, but plenty of other things do not; notably, REPL expressions do not, as well as anything explicitly launched into another thread and anything executed as a result of load-file or via a main class. This code, which I offer to the public domain, also furnishes some simple examples of macro design, as well as of the use of an atom to move information between threads, plus a recurrence of the one-cell- vector idiom for having both nil and meta-nil, distinguishing not- set-yet from actually-returned-nil. This also showed up in super-lazy- seq where ultimately one var could end up holding either a boxed return value or *two* out-of-band values, nil and :skip. (Another trick for returning out-of-band values is to return a two-element vector with a value in one cell and an accompanying bit of meta-data in the other, for example [item found] distinguishing [nil false] from [nil true]. Other lisps admit of the same trick, using a cons cell (item . found) for instance, or using nil vs. (item . nil) or any-atom vs. (item . nil). Don't know if anyone else here is familiar with dotted-pair notation though, except clojure's author.) --~--~-~--~~~---~--~~ 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: EDT interaction
Thank you so much for giving us your light, master of the dotted pair notation ;-) 2009/6/13 Wrexsoul d2387...@bsnow.net: Now I'm working on some Swing code and came up with these, which are obviously going to be useful: (defmacro do-on-edt [ body] `(SwingUtilities/invokeLater #(do ~...@body))) (defmacro get-on-edt [ body] `(let [ret# (atom nil)] (SwingUtilities/invokeLater #(reset! ret# [(do ~...@body)])) (loop [] (let [r# @ret#] (if r# (first r#) (recur)) (defmacro future-on-edt [ body] `(future (get-on-edt ~...@body))) The do-on-edt macro executes its body on the EDT and returns nil. The get-on-edt macro does similarly, but returns whatever the body returns. It blocks until the body has returned, though, which you may not want, though since it executes on the EDT it should execute fast. The future-on-edt macro avoids this blocking behavior. It behaves as if you scheduled its body to run as a future on the EDT instead of on whatever thread(s) futures usually run on. In actual fact, the future it returns is executing the blocking get-on-edt. :) Action listener code can assume it will run on the edt, but plenty of other things do not; notably, REPL expressions do not, as well as anything explicitly launched into another thread and anything executed as a result of load-file or via a main class. This code, which I offer to the public domain, also furnishes some simple examples of macro design, as well as of the use of an atom to move information between threads, plus a recurrence of the one-cell- vector idiom for having both nil and meta-nil, distinguishing not- set-yet from actually-returned-nil. This also showed up in super-lazy- seq where ultimately one var could end up holding either a boxed return value or *two* out-of-band values, nil and :skip. (Another trick for returning out-of-band values is to return a two-element vector with a value in one cell and an accompanying bit of meta-data in the other, for example [item found] distinguishing [nil false] from [nil true]. Other lisps admit of the same trick, using a cons cell (item . found) for instance, or using nil vs. (item . nil) or any-atom vs. (item . nil). Don't know if anyone else here is familiar with dotted-pair notation though, except clojure's author.) --~--~-~--~~~---~--~~ 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: A few suggestions and useful things
On Jun 13, 4:11 pm, Jarkko Oranen chous...@gmail.com wrote: Also, try using (find-doc foo) and (doc foo) in a repl for documentation searches. For this function, you might want to check out if-let. Find-doc seems to give about the same results as searching through the API page, only also cluttering up the REPL transcript. :) (defmacro with-stack-trace [ body] `(try (eval (quote (do ~...@body))) (catch Throwable ex# (. (get-ultimate-cause ex#) printStackTrace The golden rule: eval is almost always wrong. Why not simply `(try ~...@body (catch ...))? Doesn't catch exceptions thrown by the compiler, only ones thrown by the evaluator. The code I wrote nabs both. maps also are sequenceable into a seq of [k v] pairs so instead of explicitly looping it's possible to do (into {} (map (fn [[k v]] [(if keys? (f k) k) (f v)]) coll) Yeah, that might work well. I don't see why you do (apply f [k])... That's equivalent to (f k) Sometimes I forget the first item in a function-call form can be anything that evaluates to a function, and not just a symbol bound to one. :) I also personally dislike functions that take a boolean parameter; if you must, at least make it optional, with default to false The -raw ending is one I use on functions that tend to have ugly call semantics, and are mainly used to implement other more specialized functions. I had a map-preserve that called map-preserve-raw with keys? false, in particular, which would be the function usually used. (defn map-preserve [f coll] (map-preserve-raw f coll false)) There it is. (defn map-code [f code] (if (coll? code) (map-preserve-raw #(map-code f %) code true) (apply f [code]))) This makes with-derefs (part of super-lazy-seq) simpler: I didn't quite get your super-lazy-seq, but then again I didn't look at it in detail yet. It seems like it might make constructing lazy seqs easier, but I'd need more examples. The use of atoms feels dubious. It seems to me that you're emulating mutability with them. I might be wrong, but if there's any way to get rid of the atoms, it's worth the effort :) Yeah, it's a little bit dodgy-seeming, but making any form of lazy loop/recur pretty much demands some sort of mutable bindings. Not to mention file-seq already exists in core Eh. There's no files section in the navigation pane at the site. A complete category-page based version of the api docs would be useful, with all the file-interaction stuff on one page, all the atom-stuff on another, and so on, with nothing omitted (and maybe some things in two or more places). --~--~-~--~~~---~--~~ 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: EDT interaction
Hi, Am 13.06.2009 um 23:02 schrieb Wrexsoul: Now I'm working on some Swing code and came up with these, which are obviously going to be useful: And which are partly in clojure.contrib.swing-utils :) (defmacro do-on-edt [ body] `(SwingUtilities/invokeLater #(do ~...@body))) (defmacro get-on-edt [ body] `(let [ret# (atom nil)] (SwingUtilities/invokeLater #(reset! ret# [(do ~...@body)])) (loop [] (let [r# @ret#] (if r# (first r#) (recur)) And while we are talking about macro design and transferring return values between threads: (defn get-on-edt* [thunk] (let [ret (atom nil)] (SwingUtitilities/invokeAndWait #(reset! ret (thunk))) @ret)) (defmacro get-on-edt [ body] `(get-on-edt* (fn [] ~body))) Don't know if anyone else here is familiar with dotted-pair notation though, except clojure's author. And please tune down the rhetoric. This is not the level on which things are discussed in this group. Sincerely Meikel smime.p7s Description: S/MIME cryptographic signature
Re: EDT interaction
On Sat, Jun 13, 2009 at 2:02 PM, Wrexsould2387...@bsnow.net wrote: Now I'm working on some Swing code and came up with these, which are obviously going to be useful: (defmacro do-on-edt [ body] `(SwingUtilities/invokeLater #(do ~...@body))) (defmacro get-on-edt [ body] `(let [ret# (atom nil)] (SwingUtilities/invokeLater #(reset! ret# [(do ~...@body)])) (loop [] (let [r# @ret#] (if r# (first r#) (recur)) (defmacro future-on-edt [ body] `(future (get-on-edt ~...@body))) The do-on-edt macro executes its body on the EDT and returns nil. The get-on-edt macro does similarly, but returns whatever the body returns. It blocks until the body has returned, though, which you may not want, though since it executes on the EDT it should execute fast. The future-on-edt macro avoids this blocking behavior. It behaves as if you scheduled its body to run as a future on the EDT instead of on whatever thread(s) futures usually run on. In actual fact, the future it returns is executing the blocking get-on-edt. :) Action listener code can assume it will run on the edt, but plenty of other things do not; notably, REPL expressions do not, as well as anything explicitly launched into another thread and anything executed as a result of load-file or via a main class. This code, which I offer to the public domain, also furnishes some simple examples of macro design, as well as of the use of an atom to move information between threads, plus a recurrence of the one-cell- vector idiom for having both nil and meta-nil, distinguishing not- set-yet from actually-returned-nil. This also showed up in super-lazy- seq where ultimately one var could end up holding either a boxed return value or *two* out-of-band values, nil and :skip. (Another trick for returning out-of-band values is to return a two-element vector with a value in one cell and an accompanying bit of meta-data in the other, for example [item found] distinguishing [nil false] from [nil true]. Other lisps admit of the same trick, using a cons cell (item . found) for instance, or using nil vs. (item . nil) or any-atom vs. (item . nil). Don't know if anyone else here is familiar with dotted-pair notation though, except clojure's author.) get-on-edt uses a busy loop, which is icky. I would use a blockingqueue. if you are not constrained by 1.0 compatibility promise/deliver just hit the new git repo. a promise is a new kind of reference type that provides a blocking deref. http://github.com/richhickey/clojure/blob/1a0e23d0e78ef3d3a3a6267a68adcfc414d3fb56/src/clj/clojure/core.clj#L4152 -- And what is good, Phaedrus, And what is not good— Need we ask anyone to tell us these things? --~--~-~--~~~---~--~~ 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: EDT interaction
Hi, Am 13.06.2009 um 23:29 schrieb Meikel Brandmeyer: (defmacro get-on-edt [ body] `(get-on-edt* (fn [] ~body))) Of course ~...@body instead of ~body... Sincerely Meikel smime.p7s Description: S/MIME cryptographic signature
Re: EDT interaction
On Sat, Jun 13, 2009 at 2:55 PM, Meikel Brandmeyerm...@kotka.de wrote: Hi, Am 13.06.2009 um 23:29 schrieb Meikel Brandmeyer: (defmacro get-on-edt [ body] `(get-on-edt* (fn [] ~body))) Of course ~...@body instead of ~body... Sincerely Meikel I know you (Meikel) already fixed it, but I guess it is a good idea to explain that have a macro expand to a #() form is a bad idea. the original do-on-edt macro did expand to a #() form, which means if you passed in another #() form you would end up with nested #() forms, which causes an exception. -- And what is good, Phaedrus, And what is not good— Need we ask anyone to tell us these things? --~--~-~--~~~---~--~~ 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: A few suggestions and useful things
On Sat, Jun 13, 2009 at 10:11 PM, Jarkko Oranenchous...@gmail.com wrote: [...] I think something like this is in clojure-contrib as well. It's a semi- official add-on library for Clojure (You need a CA to contribute), so you should take a look at it :) Wrexsoul: Since you don't seem to have stumbled across clojure-contrib yet, here is where you can find it: http://code.google.com/p/clojure-contrib/ :) Also it has documentation available here: http://code.google.com/p/clojure-contrib/w/list Also, try using (find-doc foo) and (doc foo) in a repl for documentation searches. For this function, you might want to check out if-let. I have no idea how the docs on the website are generated. I don't like them much either, and they seem to fall off sync occasionally. :/ The thing that most often seems to have tripped people up wrt. the docs being out of sync is that the docs refer to the latest released version of clojure, and not to the latest version available via Subversion. I think that's less of a problem now that 1.0 has been released, because for production code you should probably stick to 1.0 anyway. -- Michael Wood esiot...@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: A few suggestions and useful things
On Sat, Jun 13, 2009 at 11:27 PM, Wrexsould2387...@bsnow.net wrote: On Jun 13, 4:11 pm, Jarkko Oranen chous...@gmail.com wrote: [...] I also personally dislike functions that take a boolean parameter; if you must, at least make it optional, with default to false The -raw ending is one I use on functions that tend to have ugly call semantics, and are mainly used to implement other more specialized functions. I had a map-preserve that called map-preserve-raw with keys? false, in particular, which would be the function usually used. (defn map-preserve [f coll] (map-preserve-raw f coll false)) There it is. It seems to me that it is more idiomatic to use map-preserve* instead of map-preserve-raw in Clojure code. Or at least I've seen others use that convention. -- Michael Wood esiot...@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: EDT interaction
Isn't this a case of wrapping a Java API needlessly? What's so bad about: (SwingUtilities/invokeLater my-func) ? -- Aaron On Sat, Jun 13, 2009 at 5:59 PM, Kevin Downeyredc...@gmail.com wrote: On Sat, Jun 13, 2009 at 2:55 PM, Meikel Brandmeyerm...@kotka.de wrote: Hi, Am 13.06.2009 um 23:29 schrieb Meikel Brandmeyer: (defmacro get-on-edt [ body] `(get-on-edt* (fn [] ~body))) Of course ~...@body instead of ~body... Sincerely Meikel I know you (Meikel) already fixed it, but I guess it is a good idea to explain that have a macro expand to a #() form is a bad idea. the original do-on-edt macro did expand to a #() form, which means if you passed in another #() form you would end up with nested #() forms, which causes an exception. -- And what is good, Phaedrus, And what is not good— Need we ask anyone to tell us these things? --~--~-~--~~~---~--~~ 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: EDT interaction
it depends how often you are pushing stuff onto the EDT. I have a similar macro called EDT so I can do stuff like (EDT (.setText foo bar)) alternatively I would need to type (SwingUtilities/invokeLater #(.setText foo bar)) or even (SwingUtilities/invokeLater (fn [] (.setText foo bar))) On Sat, Jun 13, 2009 at 5:23 PM, Aaron Cohenremled...@gmail.com wrote: Isn't this a case of wrapping a Java API needlessly? What's so bad about: (SwingUtilities/invokeLater my-func) ? -- Aaron On Sat, Jun 13, 2009 at 5:59 PM, Kevin Downeyredc...@gmail.com wrote: On Sat, Jun 13, 2009 at 2:55 PM, Meikel Brandmeyerm...@kotka.de wrote: Hi, Am 13.06.2009 um 23:29 schrieb Meikel Brandmeyer: (defmacro get-on-edt [ body] `(get-on-edt* (fn [] ~body))) Of course ~...@body instead of ~body... Sincerely Meikel I know you (Meikel) already fixed it, but I guess it is a good idea to explain that have a macro expand to a #() form is a bad idea. the original do-on-edt macro did expand to a #() form, which means if you passed in another #() form you would end up with nested #() forms, which causes an exception. -- And what is good, Phaedrus, And what is not good— Need we ask anyone to tell us these things? -- And what is good, Phaedrus, And what is not good— Need we ask anyone to tell us these things? --~--~-~--~~~---~--~~ 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: breaking early from a tight loop
On Jun 13, 9:57 pm, Laurent PETIT laurent.pe...@gmail.com wrote: The filter and map functions produce lazy seqs, so the sequence is only walked once. Well, isn't walking 3 different sequences 1 time almost equivalent (in terms of computer work) to walking 3 times one sequence ? Well, I guess there's the overhead of wrapping it in multiple seqs, but the logic calculations will be the same regardless of which method is used. And nevertheless, if I insist, it's not really because there *could* be a performance problem (though I guess there will, but only benchmark would tell), but rather because the essence of the problem seems to be needing a simple reduction with early break capability, and no more :-) Well, I kinda disagree here. It seems to me that this: (defn interesting? [pixels c] ( c (count (take c (filter in-interval? pixels Is more straightforward than: (defn interesting? [pixels c] (reduce (fn [counter pixel] (if (in-interval? pixel) (inc counter) counter)) 0 pixels (partial c))) - 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: super-lazy-seq
On Jun 13, 4:18 am, Wrexsoul d2387...@bsnow.net wrote: Between files-and-dirs and file-lines-seq I think I have saved as many lines of code as are in the macro+helper fns, so those are at break- even. I'm not completely sure what benefit super-lazy-seq is meant to have. Could you perhaps give an example written with lazy-seq, and show how super-lazy-seq improves on it? Also, how does files-and-dirs differ from clojure.core/file-seq? - 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: super-lazy-seq
On Jun 13, 9:24 pm, James Reeves weavejes...@googlemail.com wrote: On Jun 13, 4:18 am, Wrexsoul d2387...@bsnow.net wrote: Between files-and-dirs and file-lines-seq I think I have saved as many lines of code as are in the macro+helper fns, so those are at break- even. I'm not completely sure what benefit super-lazy-seq is meant to have. Could you perhaps give an example written with lazy-seq, and show how super-lazy-seq improves on it? It lets you write the generator in a style similar to loop/recur, and generally in half the code. And, it demonstrates the kinds of things you can do with macros. Also, how does files-and-dirs differ from clojure.core/file-seq? Is file-seq recursive? I'd figured it just returned the flat contents of a directory. --~--~-~--~~~---~--~~ 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: A few suggestions and useful things
On Jun 13, 6:20 pm, Michael Wood esiot...@gmail.com wrote: On Sat, Jun 13, 2009 at 10:11 PM, Jarkko Oranenchous...@gmail.com wrote: [...] I think something like this is in clojure-contrib as well. It's a semi- official add-on library for Clojure (You need a CA to contribute), so you should take a look at it :) Wrexsoul: Since you don't seem to have stumbled across clojure-contrib yet, here is where you can find it:http://code.google.com/p/clojure-contrib/ :) Went there earlier. http://code.google.com/p/clojure-contrib/downloads/list This project currently has no downloads. Nothing to download and install, so apparently nothing yet in a releasable state. I'm not about to make my own code dependent on stuff that's from some other project's svn and probably still very changeable. :) The thing that most often seems to have tripped people up wrt. the docs being out of sync is that the docs refer to the latest released version of clojure, and not to the latest version available via Subversion. I think that's less of a problem now that 1.0 has been released, because for production code you should probably stick to 1.0 anyway. As I am doing. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Primitive char Type
I'm writing some simple code, and I believe I'm running into trouble getting a primitive char. user= (def s (new StringBuilder aaa)) #'user/s ; Java method signature is setCharAt(int index, char ch) user= (. s setCharAt (int 0) (char \a)) java.lang.IllegalArgumentException: No matching method found: setCharAt for class java.lang.StringBuilder (NO_SOURCE_FILE:0) user= (type (char \a)) java.lang.Character ; should be char? --~--~-~--~~~---~--~~ 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: Primitive char Type
user= (def s (StringBuilder. aaa)) #'user/s user= (. s setCharAt 0 \b) nil user= s #StringBuilder baa user= (. s setCharAt (int 0) (char \b)) nil user= (. s setCharAt (int 0) (char \e)) nil user= s #StringBuilder eaa user= works for me On Sat, Jun 13, 2009 at 7:28 PM, tmountaintinymount...@gmail.com wrote: I'm writing some simple code, and I believe I'm running into trouble getting a primitive char. user= (def s (new StringBuilder aaa)) #'user/s ; Java method signature is setCharAt(int index, char ch) user= (. s setCharAt (int 0) (char \a)) java.lang.IllegalArgumentException: No matching method found: setCharAt for class java.lang.StringBuilder (NO_SOURCE_FILE:0) user= (type (char \a)) java.lang.Character ; should be char? -- And what is good, Phaedrus, And what is not good— Need we ask anyone to tell us these things? --~--~-~--~~~---~--~~ 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: Primitive char Type
On Jun 13, 2009, at 7:37 PM, Kevin Downey wrote: works for me It's working for me in Java 6, but not Java 5. It looks like something changed there. In Java 5, I'm getting: user= (.setCharAt s 0 \c) java.lang.IllegalArgumentException: Can't call public method of non- public class: public void java.lang.AbstractStringBuilder.setCharAt(int,char) (NO_SOURCE_FILE:0) I'm not sure why. --Steve smime.p7s Description: S/MIME cryptographic signature
Re: super-lazy-seq
On Jun 14, 3:21 am, Wrexsoul d2387...@bsnow.net wrote: It lets you write the generator in a style similar to loop/recur, and generally in half the code. And, it demonstrates the kinds of things you can do with macros. Ahh, I see. That could be useful under some circumstances. However, most Clojure functions that deal with lists return lazy seqs, so a lot of the time you don't need to call lazy-seq directly. For instance, lets say I want to return a lazy list of all the lines in all the files in a directory tree: (use '(clojure.contrib java-utils duck-streams)) (defn all-line-seq [dir] (mapcat read-lines (file-seq (file dir Since file-seq, read-lines and mapcat all lazy, my final result is lazy as well. Is file-seq recursive? I'd figured it just returned the flat contents of a directory. Yep, it's recursive. If you just want the flat list you could just use the .listFiles method, which I guess is why there isn't an explicit function for it in clojure.core. - 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: super-lazy-seq
On Jun 13, 11:07 pm, James Reeves weavejes...@googlemail.com wrote: For instance, lets say I want to return a lazy list of all the lines in all the files in a directory tree: (use '(clojure.contrib java-utils duck-streams)) When clojure.contrib releases version 1.0, that might be an option. (defn all-line-seq [dir] (mapcat read-lines (file-seq (file dir Since file-seq, read-lines and mapcat all lazy, my final result is lazy as well. Seems to me that unless you completely consume the sequence, it will leak a file handle. Is file-seq recursive? I'd figured it just returned the flat contents of a directory. Yep, it's recursive. OK. Even so, the implementation in terms of super-lazy-seq shows the power of that macro. Mostly, I'm doing quite a few things with I/O that require custom next-item-in-seq generators for the records or other objects returned, for which it's coming in real handy. In those circumstances lazy-seq saves the bother of doing a loop/recur in everyplace that consumes some records, and super-lazy-seq in turn lets me still use a loop/recur style in the one place where the code extracts and grovels over the records one by one. --~--~-~--~~~---~--~~ 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: Primitive char Type
On Jun 13, 10:46 pm, Stephen C. Gilardi squee...@mac.com wrote: On Jun 13, 2009, at 7:37 PM, Kevin Downey wrote: works for me It's working for me in Java 6, but not Java 5. It looks like something changed there. Autoboxing. What I miss is foo-array for foo not in #{int long float double}, particularly for (= foo byte). I'm resorting to Java for the lowest- level I/O code for binary files, which is a pain because to reload changes to a Java class at the REPL means restarting the REPL, which in turn means losing any testing-purposes defs, defns, and the like I'd entered there, as well as the history. --~--~-~--~~~---~--~~ 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: breaking early from a tight loop
I actually really do like the reduce with early exit abstraction. Because ultimately, that's what the question is. It's a reduce with optimization. However, I feel that Laurence's reduce is a little too specific. The early exit condition is very likely to *not* depend on the reduce accumulator, but rather on some intermediate calculation in the reduce function. It is possible to write something like this. But some people might be concerned with how idiomatic this is. (my_reduce (fn [a b c] (if bla-bla (break))) initial_value collection) where (break) exits the immediate surrounding reduce. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---