Re: Insertion - The clojure way
Hi All, It is amazing what a discussion inserstion sort (still) can kick off :) My intention was to play with algorithms in clojure and be made aware of the little traps one has to look out for coming from scheme for instance. Therefore, translating the htdp version to clojure and playing with it a little more was the intention. I have one more question, though. My initial implementation looked like this: > (defn insert-into [sorted-vec element] >(loop [i (count sorted-vec)] >(if (and (> i 0) (> (nth sorted-vec (dec i)) element)) >(recur (dec i)) >(into (conj (subvec sorted-vec 0 i) element) (subvec > sorted-vec i) Now the discussion evolved around vectors not being suitable for this task. Can someone explain why this holds in this context? In my understanding subvec is a constant time operation. So maybe vector is not that unsuitable for this task after all? On 30/12/2010, at 2:31 PM, Mark Engelberg wrote: >> On Wed, Dec 29, 2010 at 8:13 PM, Mark Engelberg >>> However, it should be pointed out that even this latest version >>> doesn't share all the performance characteristics of the classic >>> functional insertion sort given at the Htdp link. Specifically, one >>> of the (few) great things about insertion sort is that it is blazingly >>> fast on input lists that are already sorted, or nearly sorted. As a >>> challenge (to you or Andreas, or anyone who is interested in this >>> thread), figure out why the original insertion sort works so quickly >>> on sorted lists, why the above code does not, and then try to >>> duplicate that performance characteristic with an insertion sort >>> algorithm in Clojure. > > So here's the answer to the puzzle I posed earlier, for anyone who's > still following along. The reason the other implementation is fast on > already sorted lists is because the insert function only needs to > traverse as far as the insertion point, and then can share the > structure of the remainder of the list. This is handled transparently > by the recursive process, with the stack accumulating the conses that > need to be done. To simulate this in Clojure, you need some way to > manually accumulate the list of things you traversed on the way to the > insertion point, and then non-lazily stick them on the front of the > remainder of the list. > > Here's one way to do that: > ; (append l1 l2) is equivalent to a non-lazy (concat (reverse l1) l2) > (defn append [l1 l2] > (loop [l1 (seq l1) result l2] >(if l1 > (recur (next l1) (cons (first l1) result)) > result))) > > (defn insert [n alon] > (loop [alon (seq alon), traversed nil] >(cond > (nil? alon) (append traversed (list n)) > (<= n (first alon)) (append traversed (cons n alon)) > (> n (first alon)) (recur (next alon) (conj traversed (first alon)) > > Then, do the actual insertion sort either using Ken's reduce technique > (on the reverse of the list if stability is desired), or manually > implementing the equivalent pattern: > > (defn isort [alon] > (loop [alon (seq (reverse alon)), sorted nil] >(if alon > (recur (next alon) (insert (first alon) sorted)) > sorted))) > > This is really fast on sorted lists and as fast as any of the other > versions we've batted around on random data. I believe this is the > closest Clojurian equivalent to the Racket version. Sadly, it loses > much of its simplicity. I have students write insertion sort in > Racket after only a dozen or so lessons, but writing the equivalent in > Clojure requires some significant machinations. (If anyone sees a > simpler way to accomplish the same thing in Clojure, please let me > know!) > > Still, I hope this helps explain how to transform stack-consuming > patterns into Clojure's loop/recur construct. It can be a bit of > work, but it's necessary in Clojure to implement many functional > algorithms. > > -- > 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 -- “There is a strong correlation between being smart and being a nerd, and an even stronger inverse correlation between being a nerd and being popular” (Paul Graham) -- ** Andreas Koestler, Software Engineer Leica Geosystems Pty Ltd 270 Gladstone Road, Dutton Park QLD 4102 Main: +61 7 3891 9772 Direct: +61 7 3117 8808 Fax: +61 7 3891 9336 Email: andreas.koest...@leica-geosystems.com www.leica-geosystems.com* when it has to be right, Leica Geosystems Please consider the environment before printing this email. -- You received
Re: Insertion - The clojure way
On Thu, Dec 30, 2010 at 12:51 AM, Andreas Kostler wrote: > Now the discussion evolved around vectors not being suitable for this task. > Can someone explain why this holds in this context? In my understanding > subvec is a constant time operation. So maybe vector is not that unsuitable > for this task after all? I agree. vector seems like a perfectly reasonable choice, especially in light of the difficulties that sequences present in implementing this algorithm. Your implementation of insert-into looks okay to me. I was mainly balking at your implementation of insertion-sort, which still seems a bit strange to me, but you can probably mix something like Ken's reduce technique with your vector-based insert-into with good results. So combining the two, you get something like: (defn insert-into [sorted-vec element] (loop [i (count sorted-vec)] (if (and (> i 0) (> (nth sorted-vec (dec i)) element)) (recur (dec i)) (into (conj (subvec sorted-vec 0 i) element) (subvec sorted-vec i) (defn insertion-sort [s] (reduce insert-into [] s)) which is a perfectly reasonable implementation. By my benchmarking, it's slightly slower than my complicated sequence-based version, but it's in the same ballpark. It's easy to understand and furthermore, it doesn't blow the stack and it's quick on already sorted lists. -- 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: Insertion - The clojure way
On Wed, Dec 29, 2010 at 11:31 PM, David Nolen wrote: > The original algorithm is simply wrong for very large inputs, it cannot be > TCO'ed. Pick a ridiculously large list size and the Scheme/Racket program > will barf *immediately*. > David Have you tried it? I tried this particular algorithm, in Racket, on rather large lists. It runs seemingly forever (it is a quadratic algorithm, of course), but I was unable to make Racket "barf immediately". In my experience, Racket's more likely to fall over from trying to create such a large input to begin with (simply because there's not enough memory to hold a list that large) than it is to barf from stack size while executing a non-TCO recursive function over a list. My understanding is that Racket's key to handling non-TCO recursion so gracefully is that it traps errors from stack overflows, and swaps the stack out to memory to make room on the stack to continue. So in essence, you get a stack that is bounded only by your computer's memory (or whatever memory threshold you've enabled in the settings). What size input is barfing for you? -- 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: Insertion - The clojure way
Oh, vectors are indeed bad since vector concatenation is a linear time operation. My apologies to Meikel, I simply missed your remark about finger trees. I guess a version that swaps the values "in place" would be the way to go. On 30/12/2010, at 7:34 PM, Mark Engelberg wrote: > On Wed, Dec 29, 2010 at 11:31 PM, David Nolen wrote: >> The original algorithm is simply wrong for very large inputs, it cannot be >> TCO'ed. Pick a ridiculously large list size and the Scheme/Racket program >> will barf *immediately*. >> David > > Have you tried it? I tried this particular algorithm, in Racket, on > rather large lists. It runs seemingly forever (it is a quadratic > algorithm, of course), but I was unable to make Racket "barf > immediately". In my experience, Racket's more likely to fall over > from trying to create such a large input to begin with (simply because > there's not enough memory to hold a list that large) than it is to > barf from stack size while executing a non-TCO recursive function over > a list. My understanding is that Racket's key to handling non-TCO > recursion so gracefully is that it traps errors from stack overflows, > and swaps the stack out to memory to make room on the stack to > continue. So in essence, you get a stack that is bounded only by your > computer's memory (or whatever memory threshold you've enabled in the > settings). > > What size input is barfing for you? > > -- > 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 -- “There is a strong correlation between being smart and being a nerd, and an even stronger inverse correlation between being a nerd and being popular” (Paul Graham) -- ** Andreas Koestler, Software Engineer Leica Geosystems Pty Ltd 270 Gladstone Road, Dutton Park QLD 4102 Main: +61 7 3891 9772 Direct: +61 7 3117 8808 Fax: +61 7 3891 9336 Email: andreas.koest...@leica-geosystems.com www.leica-geosystems.com* when it has to be right, Leica Geosystems Please consider the environment before printing this email. -- 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: Insertion - The clojure way
On Thu, Dec 30, 2010 at 3:24 AM, Andreas Kostler wrote: > Oh, vectors are indeed bad since vector concatenation is a linear time > operation. > My apologies to Meikel, I simply missed your remark about finger trees. > I guess a version that swaps the values "in place" would be the way to go. When you perform (into v1 v2), the length of the time it takes is proportional to the length of v2. This is similar to the amount of work done when doing a list insertion (must rebuild the portion of the list up to the insertion point, but not the entire list. As for finger trees, I have not found them to be useful. Although they have good theoretical bounds, they are very slow in practice. For example, if you try splitting, concatenating, and traversing lists of, say, 10 elements, these operations on finger trees are still many times slower than just using a naive take/drop/concat/seq on a regular list. How many millions of elements do you need to have for the so-called "fast" finger tree operations to be worth the overhead? I think it is highly unlikely that you will see any speed improvement by converting insertion sort to finger trees, but feel free to try. [Note: This is just based on my own personal benchmarking, and I would love to be proven wrong about finger trees], -- 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: Insertion - The clojure way
On 30/12/2010, at 8:40 PM, Mark Engelberg wrote: > On Thu, Dec 30, 2010 at 3:24 AM, Andreas Kostler > wrote: >> Oh, vectors are indeed bad since vector concatenation is a linear time >> operation. >> My apologies to Meikel, I simply missed your remark about finger trees. >> I guess a version that swaps the values "in place" would be the way to go. > > When you perform (into v1 v2), the length of the time it takes is > proportional to the length of v2. > This is similar to the amount of work done when doing a list insertion > (must rebuild the portion of the list up to the insertion point, but > not the entire list. Isn't that the problem though? This will make the best case inefficient since the work performed by into is proportional to the length of v2 (or v1 if you swap them around). Therefore, even thought the list is sorted you still need to traverse v2. A simple fix would be checking (= i 0) but that's kinda ugly. > > As for finger trees, I have not found them to be useful. Although > they have good theoretical bounds, they are very slow in practice. > For example, if you try splitting, concatenating, and traversing lists > of, say, 10 elements, these operations on finger trees are still > many times slower than just using a naive take/drop/concat/seq on a > regular list. How many millions of elements do you need to have for > the so-called "fast" finger tree operations to be worth the overhead? I have no experience with finger trees what so ever. I only understand Meikels comment now :) > > I think it is highly unlikely that you will see any speed improvement > by converting insertion sort to finger trees, but feel free to try. > > [Note: This is just based on my own personal benchmarking, and I would > love to be proven wrong about finger trees], > > -- > 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 -- “There is a strong correlation between being smart and being a nerd, and an even stronger inverse correlation between being a nerd and being popular” (Paul Graham) -- ** Andreas Koestler, Software Engineer Leica Geosystems Pty Ltd 270 Gladstone Road, Dutton Park QLD 4102 Main: +61 7 3891 9772 Direct: +61 7 3117 8808 Fax: +61 7 3891 9336 Email: andreas.koest...@leica-geosystems.com www.leica-geosystems.com* when it has to be right, Leica Geosystems Please consider the environment before printing this email. -- 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: Insertion - The clojure way
On Wed, Dec 29, 2010 at 9:31 PM, Mark Engelberg wrote: > So here's the answer to the puzzle I posed earlier I just realized that the "append" function in my code was unnecessary, since into serves the same purpose. Thus my solution could be rewritten as: (defn insert [n alon] (loop [alon (seq alon), traversed nil] (cond (nil? alon) (into (list n) traversed) (<= n (first alon)) (into (cons n alon) traversed) (> n (first alon)) (recur (next alon) (conj traversed (first alon)) (defn isort [alon] (loop [alon (seq (reverse alon)), sorted nil] (if alon (recur (next alon) (insert (first alon) sorted)) sorted))) -- 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: Insertion - The clojure way
On Thu, Dec 30, 2010 at 3:49 AM, Andreas Kostler wrote: > Isn't that the problem though? This will make the best case inefficient since > the work performed by into is proportional to the length of v2 (or v1 if you > swap them around). > Therefore, even thought the list is sorted you still need to traverse v2. A > simple fix would be > checking (= i 0) but that's kinda ugly. No, v2 in your algorithm is only the portion you've scanned over to find the insertion (since you scan from the back). Your algorithm is fast for sorted lists, I checked. I think the only way you can beat that (using insertion sort) is if you have a data structure that allows for both a binary search to quickly find the insertion point, and then allows for fast insertion at that point. So maybe if finger trees can give you both the fast search and the fast insertion, that might pay off, but I still speculate it's unlikely to be any faster. -- 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: Insertion - The clojure way
On 30/12/2010, at 8:54 PM, Mark Engelberg wrote: > On Thu, Dec 30, 2010 at 3:49 AM, Andreas Kostler > wrote: >> Isn't that the problem though? This will make the best case inefficient since >> the work performed by into is proportional to the length of v2 (or v1 if you >> swap them around). >> Therefore, even thought the list is sorted you still need to traverse v2. A >> simple fix would be >> checking (= i 0) but that's kinda ugly. > > No, v2 in your algorithm is only the portion you've scanned over to > find the insertion (since you scan from the back). Your algorithm is > fast for sorted lists, I checked. Oh of course. I apologise. Mark do you mind to lay out how you perform your benchmarks. On my system (insertion-sort (into [] (range 1))) runs for an unacceptable amount of time (talking ~10s) That seems to be quite long for sorting an already sorted vector of 10k elements. > I think the only way you can beat that (using insertion sort) is if > you have a data structure that allows for both a binary search to > quickly find the insertion point, and then allows for fast insertion > at that point. So maybe if finger trees can give you both the fast > search and the fast insertion, that might pay off, but I still > speculate it's unlikely to be any faster. With the initial implementation, using binary search to find the insertion point should still result in a speed up, right? > > -- > 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 -- 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: Insertion - The clojure way
On Thu, Dec 30, 2010 at 4:01 AM, Andreas Kostler wrote: > Oh of course. I apologise. Mark do you mind to lay out how you perform your > benchmarks. > On my system (insertion-sort (into [] (range 1))) runs for an > unacceptable amount of time (talking ~10s) > That seems to be quite long for sorting an already sorted vector of 10k > elements. Maybe you're still using your original version with the good insert, but the bad sort? Try this: (defn insert-into [sorted-vec element] (loop [i (count sorted-vec)] (if (and (> i 0) (> (nth sorted-vec (dec i)) element)) (recur (dec i)) (into (conj (subvec sorted-vec 0 i) element) (subvec sorted-vec i) (defn insertion-sort [s] (reduce insert-into [] s)) (time (last (insertion-sort (range 1 I get 30ms. -- 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: Insertion - The clojure way
On Thu, Dec 30, 2010 at 4:01 AM, Andreas Kostler wrote: > With the initial implementation, using binary search to find the insertion > point should still result in a speed up, right? Sure, that should help, although it doesn't change the overall quadratic bound unless you can also do the insertion in logarithmic time. It might be worth trying a binary search in your vector-based insert, and see how much of a difference it makes. -- 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: From Binary Search Trees to the Dining Philosopher
Gist updated to use watchers for table state reporting, instead of coupling the reporting with the transaction. Also, as cgrand pointed to me, note that this implementation using the STM is somehow related to the "Monitor solution" described in : http://en.wikipedia.org/wiki/Dining_philosophers_problem#Monitor_solution https://gist.github.com/759364 Feedback appreciated, -- Laurent 2010/12/30 Laurent PETIT > of course there's a little rampant bug, (take) should read (take (count > phils) ..) not (take (* 3 (count phils)...), gist updated. > > > 2010/12/30 Laurent PETIT > >> And here's the gist, if it's more readable : >> https://gist.github.com/759364 >> >> 2010/12/30 Laurent PETIT >> >> Here's my attempt at providing a simple solution to this problem: >>> >>> 18 lines of code, not too bad if it's not buggy ;-) >>> >>> ;;; Dining philosophers. Solution using Clojure STM. >>> ;;; What are our identities? >>> ;;; The problem talks about forks, and philosophers. >>> ;;; Conceptually, forks have a "taken-by" property which can have one >>> ;;; of three values: :left-philosopher, :righ-philosopher, :nobody. >>> ;;; Conceptually, philosophers have a "state" property which can be >>> ;;; :eating or :thinking. >>> ;;; Note that with an approach using STM for getting both forks at once >>> ;;; atomically or none, and synchronizing the philosopher's value, we >>> ;;; will always have the "taken-by" property of the forks and the >>> "state" >>> ;;; property of the philosopher synchronized. >>> ;;; So we can altogether get rid of the fork concept, use refs for >>> ;;; representing philosophers, and allow the change of the state of a >>> ;;; philosopher to :eating by ensuring that his neighbours have the >>> ;;; :thinking value in the same transaction >>> ;;; For simulating true concurrent independent philosophers, we will have >>> >>> ;;; one thread per philosopher. Using "future" is just an easy trick >>> for >>> ;;; starting a new thread, and we do not really want to use "future" >>> beyond >>> ;;; its "will run the code in a separate thread" feature. >>> ;;; Implementation notes: >>> ;;; * philosopher "behaviour" is basic : thinks for a while, tries to >>> eat, >>> ;;;thinks for a while, stops eating, thinks for a while, tries to >>> eat, >>> ;;;thinkgs for a while, etc. >>> ;;; * could be enhanced for graceful shutdown of the dinner, etc., but >>> this >>> ;;;would clutter with no real value to the essence of the solution >>> >>> (def phils (repeatedly 5 #(ref :thinking))) >>> >>> (defn snapshot [] (->> phils (map deref) doall dosync)) >>> >>> (def printer (agent nil)) >>> >>> (defn react [val neighbours-vals] >>> (cond >>> (= :eating val) :thinking >>> (some (partial = :eating) neighbours-vals) val >>> :else :eating)) >>> >>> (defn phil-fn [p neighbours] >>> (Thread/sleep (rand-int 100)) >>> (dosync >>> (let [old @p >>> new (alter p react (map deref neighbours))] >>> (when-not (= old new) (send printer (fn [_] (prn (snapshot >>> >>> (defn start-lunch [] >>> (doseq [[left-phil phil right-phil] (take (* 3 (count phils)) >>> (partition 3 1 (cycle >>> phils)))] >>> (future (while true (phil-fn phil [left-phil right-phil]) >>> >>> ;(start-lunch) >>> >>> 2010/12/29 Laurent PETIT >>> >>> Hi Todd, 2010/12/29 Todd Thanks Ken, Mark, David and Alex for your comments regarding Binary > Search trees. I've read that thread several times, and ordered Okasaki's > Purely Functional Data Structures, too. I'll return to this a bit later. > > Meanwhile, I decided to tackle learning Clojure from a different > angle...in this case, implementing a solution for the Dining Philosopher > problem. > > I've posted my code here: > > https://gist.github.com/757925 > > General comments/questions: > > 1. I suppose it's from years of OO programming, but it still feels so > weird not to be creating objects and then hanging methods off those > objects. > In fact, my first approach was to create protocols and records for each of > the 'objects': chopsticks, philosophers, even the table. But this started > to > get painful, so I shifted gears... > > 2. I'm using a number of symbols (:tablestate, :seats, :chopsticks, > :servings, etc). Shouldn't these be defined somewhere? It feels like I'm > driving w/o a seatbelt. I'm so used to encapsulating this sort of thing in > an enum or something, and then relying on java typing to enforce the > allowed > values. > > 3. Starting a thread with (future ... This couldn't be easier. Very > cool. > > 4. I tried making the table an agent instead of a ref. Then I was > sending methods to the table like, start-tableservice or > stop-tabelservice... I'll investigate further, but is it idiomatic to > s
an object of class created using defrecord does not implement IFn .. while it behaves very similar to map otherwise ..
Hello everybody, An object of class created using defrecord does not implement IFn .. while it behaves very similar to map otherwise .. Is this way by design? can it be made to behave like a hash-map without any performance penalty in terms of behaving like a function? Thanks, Sunil. -- 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: type hinting the arguments of a function ..
thanks David and Ben for you responses.. Sunil. On Wed, Dec 29, 2010 at 9:47 PM, David Nolen wrote: > On Wed, Dec 29, 2010 at 10:48 AM, B Smith-Mannschott < > bsmith.o...@gmail.com> wrote: > >> - (defn f [[^double x]] x) >> The compiler (1.3) does not complain about this, though I can't say >> what kind of code it generates. (I suspect it boxes x, but I don't >> know.) >> What did you mean by "You can't cast the contents of a sequence to a >> primitive type"? >> >> // Ben > > > Sorry what I meant was that you won't be taking advantage of 1.3.0's fn > support for primitive arguments. That's a function that takes an object, > destructures it and compiler hints a double. > > David > > -- > 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 > -- 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: Insertion - The clojure way
On Thu, Dec 30, 2010 at 5:34 AM, Mark Engelberg wrote: > On Wed, Dec 29, 2010 at 11:31 PM, David Nolen > wrote: > > The original algorithm is simply wrong for very large inputs, it cannot > be > > TCO'ed. Pick a ridiculously large list size and the Scheme/Racket program > > will barf *immediately*. > > David > > Have you tried it? I tried this particular algorithm, in Racket, on > rather large lists. It runs seemingly forever (it is a quadratic > algorithm, of course), but I was unable to make Racket "barf > immediately". In my experience, Racket's more likely to fall over > from trying to create such a large input to begin with (simply because > there's not enough memory to hold a list that large) than it is to > barf from stack size while executing a non-TCO recursive function over > a list. My understanding is that Racket's key to handling non-TCO > recursion so gracefully is that it traps errors from stack overflows, > and swaps the stack out to memory to make room on the stack to > continue. So in essence, you get a stack that is bounded only by your > computer's memory (or whatever memory threshold you've enabled in the > settings). > > What size input is barfing for you? 2e6. Racket can easily create a list of that size. Calling sort on it however fails fast. David -- 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: Insertion - The clojure way
@Mark: applause. A nice pedagogical exercise, and your step-by-step approach --- so reminiscent of HTDP --- was very effective. Your final solution reminds me of an undergraduate data structures and algorithms final I took (too) many years ago on which, after weeks of doing recursive sorts and traversals, the professor asked us to walk a tree with three pointer variables and a loop. As an old (ancient, really) lisp lover who's just discovered Clojure, this thread feels like a great intro to what's the same and what's different. Thanks! -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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: Argument is not an array, in a function inside deftype
I don't get any errors when I run your code. This is the output: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 Are you sure you are using the latest Clojure 1.2 version and not an early beta, etc.? Process finished with exit code 0 On Dec 29, 11:25 pm, Jarl Haggerty wrote: > What is wrong with my code(bottom of post)? I keep getting this > error. Line 24 is "(get-cell [x r c] 1))" in the Matrix deftype and > 36 is "(print (get-cell one r c) " "))" in the first nested "doseq"s. > I'm on Windows 7 with Clojure 1.2. > > Exception in thread "main" java.lang.IllegalArgumentException: > Argument is not an array (core.clj:0) > at clojure.lang.Compiler.eval(Compiler.java:5440) > at clojure.lang.Compiler.load(Compiler.java:5857) > at clojure.lang.Compiler.loadFile(Compiler.java:5820) > at clojure.main$load_script.invoke(main.clj:221) > at clojure.main$script_opt.invoke(main.clj:273) > at clojure.main$main.doInvoke(main.clj:354) > at clojure.lang.RestFn.invoke(RestFn.java:409) > at clojure.lang.Var.invoke(Var.java:365) > at clojure.lang.AFn.applyToHelper(AFn.java:163) > at clojure.lang.Var.applyTo(Var.java:482) > at clojure.main.main(main.java:37) > Caused by: java.lang.IllegalArgumentException: Argument is not an > array > at java.lang.reflect.Array.get(Native Method) > at clojure.core$aget.invoke(core.clj:2994) > at clojure.lang.AFn.applyToHelper(AFn.java:165) > at clojure.lang.RestFn.applyTo(RestFn.java:133) > at clojure.core$apply.invoke(core.clj:542) > at clojure.core$aget.doInvoke(core.clj:2996) > at clojure.lang.RestFn.invoke(RestFn.java:443) > at com.curious.scratch.core.Matrix2D.get_cell(core.clj:24) > at com.curious.scratch.core$eval122.invoke(core.clj:36) > at clojure.lang.Compiler.eval(Compiler.java:5424) > ... 10 more > > (def float-array-class (class (float-array 1))) > (defprotocol Matrix > (matrix-data [x]) > (matrix-height [x]) > (matrix-width [x]) > (matrix-add [x] [x y] [x y & args]) > (get-cell [x r] [x r c])) > > (deftype Matrix2D [data height width] > Matrix > (matrix-data [x] data) > (matrix-height [x] height) > (matrix-width [x] width) > (matrix-add [x] x) > (matrix-add [x y] > (let [x-data (matrix-data x) > y-data (matrix-data y) > z-data (amap ^floats x-data index z-data (+ (aget > ^floats x-data index) (aget ^floats y-data index)))] > (Matrix2D. z-data (matrix-width x) (matrix-height > x > (matrix-add [x y & args] (reduce matrix-add (matrix-add x y) args)) > (get-cell [x r] (get-cell x r 0)) > (get-cell [x r c] 1)) > > (defn matrix [data height width] > (if (instance? float-array-class data) > (Matrix2D. data height width) > (Matrix2D. (float-array data) height width))) > > (def one (matrix (range 10) 5 2)) > (def two (matrix-add one one)) > > (doseq [r (range (matrix-height one))] > (doseq [c (range (matrix-width one))] > (print (get-cell one r c) " ")) > (println)) > > (doseq [r (range (matrix-height two))] > (doseq [c (range (matrix-width two))] > (print (get-cell two r c) " ")) > (println)) -- 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: an object of class created using defrecord does not implement IFn .. while it behaves very similar to map otherwise ..
Yes, that's intentional – implementing IFn is (as you can see) orthogonal to implementing IPersistentMap, IPersistentCollection, etc. Of course, keyword access of record slots is most idiomatic, e.g. (:my-slot some-record) If you'd like to pass around a function that accesses a record, there's always get, e.g. ((partial get some-record) :my-slot) - Chas On Dec 30, 2010, at 8:08 AM, Sunil S Nandihalli wrote: > Hello everybody, > An object of class created using defrecord does not implement IFn .. while > it behaves very similar to map otherwise .. Is this way by design? can it be > made to behave like a hash-map without any performance penalty in terms of > behaving like a function? > > Thanks, > Sunil. -- 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
Trick to getting bindings in a repl
I'm doing something kind of tricky...I'm running a REPL in my Java Swing application. I do something like: public class MyConsoleClass extends OurEmbeddedInterpreterClass { // ... // inner class private class ReplRunner extends Thread { public void run() { Namespace MYNS = Namespace.findOrCreate(Symbol.create("myns")); Var ACCESS_ME = Var.intern(MYNS, Symbol.create("*me*")); Var.pushThreadBindings(RT.map(RT.IN, myIn, RT.OUT, myOut, RT.ERR, myErr, ACCESS_ME, MyConsoleClass.this); BufferedReader script = getMagicInitScript(); Compiler.load(script, getScriptPath(), getScriptFile()); } } // ...somewhere, make a ReplRunner and launch it when you're supposed to } The "magic init script" is what runs the repl. The ins and outs are mapped into Swing components so you can type commands, it passes to the repl, and then output comes back to a text pane or the equivalent. Now, my GUI app puts a KeyListener on the input component so that when the TAB key is pressed, it runs a completion routine (Java callback) to try to complete your command. I wrote a function (in Clojure, inside the magic init script) that returns all the completions based on the current command. My Java callback looks like: // a method in MyConsoleClass...CodeCompletion is our own little helper struct... public List getCompletions(String cmd) { Var getFn = RT.var("myns", "get-completions"); try { List result = (List) getFn.invoke(cmd); return result; catch(Exception e) { /* handle e omitted */ } return null; } The problem is, get-completions uses dir-fn and ns-map to gather bindings based on the context of the command. But it's being invoked in the AWT event thread (which calls this getCompletions method), NOT the ReplRunner thread that I launch (which is of course just looping infinitely waiting on input). So all the local bindings (including *me* that I bound in ReplRunner.run()) are missing from the results. Does anybody have any ideas how I can jack into the repl thread to grab the bindings from it? I don't think any of Clojure's concurrency constructs will help me here, because I need to interfere with a thread that's essentially blocked at the time of the (synchronous) completion call. Sorry if this isn't fully specified and hurried...I can't paste the code directly here because of NDA. If you need more details I can provide them. Thanks in advance for any ideas... Mike -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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
Interesting challenge
>From the Qi mailing list: http://groups.google.com/group/qilang/browse_thread/thread/e4a2f534fad5032a "I contend that this kind of problem cannot be solved (efficiently) in any pure functional programming language. You may disagree" :D David -- 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: Interesting challenge
On Thu, 30 Dec 2010 12:03:14 -0500 David Nolen wrote: > From the Qi mailing list: > > http://groups.google.com/group/qilang/browse_thread/thread/e4a2f534fad5032a > > "I contend that this kind of problem cannot be solved (efficiently) in any > pure functional programming language. You may disagree" Do you know if his C++ version available for examination? thanks, http://www.mired.org/consulting.html Independent Network/Unix/Perforce consultant, email for more information. O< ascii ribbon campaign - stop html mail - www.asciiribbon.org -- 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: Argument is not an array, in a function inside deftype
I'm using the maven plugin so I think I'm using the lastest 1.2, and I've tried every 1.3 version, but I just got a hold of my laptop, and I am having no problems on there. I was having several other problems too(I started another discussion complaining about a whittled down version of this program that doesn't work either), maybe when I get home I'll try a reboot. On Dec 30, 8:33 am, Bob Shock wrote: > I don't get any errors when I run your code. This is the output: > > 1 1 > 1 1 > 1 1 > 1 1 > 1 1 > 1 1 1 1 1 > 1 1 1 1 1 > > Are you sure you are using the latest Clojure 1.2 version and not an > early beta, etc.? > > Process finished with exit code 0 > > On Dec 29, 11:25 pm, Jarl Haggerty wrote: > > > What is wrong with my code(bottom of post)? I keep getting this > > error. Line 24 is "(get-cell [x r c] 1))" in the Matrix deftype and > > 36 is "(print (get-cell one r c) " "))" in the first nested "doseq"s. > > I'm on Windows 7 with Clojure 1.2. > > > Exception in thread "main" java.lang.IllegalArgumentException: > > Argument is not an array (core.clj:0) > > at clojure.lang.Compiler.eval(Compiler.java:5440) > > at clojure.lang.Compiler.load(Compiler.java:5857) > > at clojure.lang.Compiler.loadFile(Compiler.java:5820) > > at clojure.main$load_script.invoke(main.clj:221) > > at clojure.main$script_opt.invoke(main.clj:273) > > at clojure.main$main.doInvoke(main.clj:354) > > at clojure.lang.RestFn.invoke(RestFn.java:409) > > at clojure.lang.Var.invoke(Var.java:365) > > at clojure.lang.AFn.applyToHelper(AFn.java:163) > > at clojure.lang.Var.applyTo(Var.java:482) > > at clojure.main.main(main.java:37) > > Caused by: java.lang.IllegalArgumentException: Argument is not an > > array > > at java.lang.reflect.Array.get(Native Method) > > at clojure.core$aget.invoke(core.clj:2994) > > at clojure.lang.AFn.applyToHelper(AFn.java:165) > > at clojure.lang.RestFn.applyTo(RestFn.java:133) > > at clojure.core$apply.invoke(core.clj:542) > > at clojure.core$aget.doInvoke(core.clj:2996) > > at clojure.lang.RestFn.invoke(RestFn.java:443) > > at com.curious.scratch.core.Matrix2D.get_cell(core.clj:24) > > at com.curious.scratch.core$eval122.invoke(core.clj:36) > > at clojure.lang.Compiler.eval(Compiler.java:5424) > > ... 10 more > > > (def float-array-class (class (float-array 1))) > > (defprotocol Matrix > > (matrix-data [x]) > > (matrix-height [x]) > > (matrix-width [x]) > > (matrix-add [x] [x y] [x y & args]) > > (get-cell [x r] [x r c])) > > > (deftype Matrix2D [data height width] > > Matrix > > (matrix-data [x] data) > > (matrix-height [x] height) > > (matrix-width [x] width) > > (matrix-add [x] x) > > (matrix-add [x y] > > (let [x-data (matrix-data x) > > y-data (matrix-data y) > > z-data (amap ^floats x-data index z-data (+ (aget > > ^floats x-data index) (aget ^floats y-data index)))] > > (Matrix2D. z-data (matrix-width x) (matrix-height > > x > > (matrix-add [x y & args] (reduce matrix-add (matrix-add x y) args)) > > (get-cell [x r] (get-cell x r 0)) > > (get-cell [x r c] 1)) > > > (defn matrix [data height width] > > (if (instance? float-array-class data) > > (Matrix2D. data height width) > > (Matrix2D. (float-array data) height width))) > > > (def one (matrix (range 10) 5 2)) > > (def two (matrix-add one one)) > > > (doseq [r (range (matrix-height one))] > > (doseq [c (range (matrix-width one))] > > (print (get-cell one r c) " ")) > > (println)) > > > (doseq [r (range (matrix-height two))] > > (doseq [c (range (matrix-width two))] > > (print (get-cell two r c) " ")) > > (println)) > > -- 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
Time/size bounded cache?
Hello, I'm wring a service that polls RSS feeds (using feedme). And I'd like to act only on the new entries in each feed. So far I have something like: (defn get-new-entries [seen] (let [seen? (complement seen)] (filter #(seen? (:id %)) (get-entries (defn poll [sleep-time] (loop [seen #{}] (let [entries (get-new-entries seen)] (doall (map process-entry entries)) (println "") (Thread/sleep sleep-time) (recur (union seen (set (map :id entries))) (Full demo code at https://gist.github.com/760094) The problem is that "seen" will grow without bounds. Is there a built in way to have some sort of LRU cache or should I use external libraries (like plru)? Thanks, -- Miki -- 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
Boston meetup Jan 11?
10 of us from Sonian are going to converge on Boston the week of Jan 9. It's always awesome to meet other Clojure hackers. I propose we meet up somewhere central(ish) Jan 11 @ 7-9pm-ish. We have room at our company headquarters in Dedham but that might be a hike for some people. Any other places we could meet/greet & hack for an hour or two central to Boston? -- 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: Insertion - The clojure way
On Thu, Dec 30, 2010 at 6:40 AM, Mark Engelberg wrote: > As for finger trees, I have not found them to be useful. Although > they have good theoretical bounds, they are very slow in practice. > For example, if you try splitting, concatenating, and traversing lists > of, say, 10 elements, these operations on finger trees are still > many times slower than just using a naive take/drop/concat/seq on a > regular list. I hope that didn't include a naive benchmarking of take/drop/concat/seq. Because three of those are lazy, you need to wrap the output of an algorithm using them in a (doall ...) and then in your timing function to get an accurate read on the amount of time it actually takes to perform the full algorithm. -- 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: Time/size bounded cache?
Java's LinkedHashMap provides the hook necessary to implement a simple LRU cache. Here's some code where we use LHM in as an LRU cache, in service of providing a variation on the memoization concept: https://gist.github.com/747395 Whether what's there is sufficient for your needs is another story. :-) - Chas On Dec 30, 2010, at 1:35 PM, Miki wrote: > Hello, > > I'm wring a service that polls RSS feeds (using feedme). And I'd like to act > only on the new entries in each feed. > So far I have something like: > > (defn get-new-entries [seen] > (let [seen? (complement seen)] > (filter #(seen? (:id %)) (get-entries > > (defn poll [sleep-time] > (loop [seen #{}] > (let [entries (get-new-entries seen)] > (doall (map process-entry entries)) > (println "") > (Thread/sleep sleep-time) > (recur (union seen (set (map :id entries))) > > (Full demo code at https://gist.github.com/760094) > > The problem is that "seen" will grow without bounds. > Is there a built in way to have some sort of LRU cache or should I use > external libraries (like plru)? > > Thanks, > -- > Miki > > -- > 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 -- 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: Time/size bounded cache?
I've been working on a simple Clojure library for bounded caching and memoization. It's not quite ready for prime-time, but the simple case that you need is usable. I'll throw it up on github when I get home tonight and post the URL here. On Dec 30, 1:35 pm, Miki wrote: > Hello, > > I'm wring a service that polls RSS feeds (using feedme). And I'd like to act > only on the new entries in each feed. > So far I have something like: > > (defn get-new-entries [seen] > (let [seen? (complement seen)] > (filter #(seen? (:id %)) (get-entries > > (defn poll [sleep-time] > (loop [seen #{}] > (let [entries (get-new-entries seen)] > (doall (map process-entry entries)) > (println "") > (Thread/sleep sleep-time) > (recur (union seen (set (map :id entries))) > > (Full demo code athttps://gist.github.com/760094) > > The problem is that "seen" will grow without bounds. > Is there a built in way to have some sort of LRU cache or should I use > external libraries (like plru)? > > Thanks, > -- > Miki -- 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: Insertion - The clojure way
On Thu, Dec 30, 2010 at 11:01 AM, Ken Wesson wrote: > I hope that didn't include a naive benchmarking of > take/drop/concat/seq. Because three of those are lazy, you need to > wrap the output of an algorithm using them in a (doall ...) and then > in your timing function to get an accurate read on the amount of time > it actually takes to perform the full algorithm. Yes, I compared with doall. Try it and let me know if you get different results, but I find that traversing a finger tree is so much slower than traversing a sequence, it all but nullifies any advantages you get from other operations (even assuming the other operations are way faster, which they typically are not). -- 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 can't see a method in my protocol
Am 30.12.2010 07:54, schrieb Jarl Haggerty: This code, (defprotocol Matrix (matrix-get [this c r])) (deftype Matrix2D [data height width] Matrix (matrix-get [this r c] 1)) Gives me this error Exception in thread "main" java.lang.IllegalArgumentException: Can't define method not in interfaces: matrix_get (core.clj:6) […] Simply changing the name of the function to get-cell removed this problem, but I feel a need to know what is wrong with this. Do you observe this in a fresh Clojure? I ran into something similar, but with definterface. I had a definterface form and later added new functions to it, which I could not implement before restarting the JVM, as the interface has already been created the way I specified it in the first place. -- 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: Compiling dynamically created namespaces, without on-disk source code?
You might try `(binding [*compile-files* true] ...)` around whatever code creates the namespace. Can't promise that will work. This still won't let you save definitions entered at the REPL. Once they're compiled and loaded into the JVM, the bytecode is no longer accessible. -Stuart Sierra clojure.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: an object of class created using defrecord does not implement IFn .. while it behaves very similar to map otherwise ..
You can make it implement IFn easily enough: (defrecord Foo [a b c] clojure.lang.IFn (invoke [this key] (get this key))) It has been debated whether or not this is a good idea, design-wise, but it should not be a performance penalty. -Stuart Sierra clojure.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: an object of class created using defrecord does not implement IFn .. while it behaves very similar to map otherwise ..
I've been playing with making a macro to encapsulate Stuart's post, like this: (defmacro defrecord-ifn [name & args] `(defrecord ~name ~...@args clojure.lang.IFn (invoke [this key] (get this key (defrecord-ifn Foo [a b c]) (def foo (Foo. "A" "B" "C")) (prn (map foo [:a :c])) => ("A", "C") I get the error: "No such var: user/this". I guess this is because it is expanding 'this' to 'user/this'. What is the proper way to get a macro like this to expand properly? Alex -- 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: Boston meetup Jan 11?
Hi! You would be more than welcome at the Boston Coding Dojo (http:// www.meetup.com/boston-coding-dojo/). We meet every other Thursday at First Church in Boston, in Boston's Back Bay on Marlborough St. In January, we are meeting on 1/6 and 1/20, so nothing on the week of 1/9, I'm afraid. What kind of meeting do you have in mind? I could certainly recommend some restaurants that are more conducive to conversation. If you are looking for a space to hack, I can certainly check with the church for availability; we meet in a lovely chapel with plenty of room. It would cost $75 for the space for the night. There's also the Workbar (http://www.workbarboston.com), which is pricier and a little more cramped... :). Everyone on the list should also check out Boston Software Craftsmanship (http://groups.google.com/group/boston-software- craftsmanship/). Their next meeting is on 1/24 and is on monads (http://gathers.us/events/jan-boston-software-craftsmanship-meeting). Thanks! Alyssa On Dec 30, 1:52 pm, dysinger wrote: > 10 of us from Sonian are going to converge on Boston the week of Jan > 9. It's always awesome to meet other Clojure hackers. I propose we > meet up somewhere central(ish) Jan 11 @ 7-9pm-ish. We have room at > our company headquarters in Dedham but that might be a hike for some > people. Any other places we could meet/greet & hack for an hour or > two central to Boston? -- 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: an object of class created using defrecord does not implement IFn .. while it behaves very similar to map otherwise ..
Alex Baranosky writes: > I've been playing with making a macro to encapsulate Stuart's post, like this: > > (defmacro defrecord-ifn [name & args] > `(defrecord ~name ~...@args > clojure.lang.IFn > (invoke [this key] (get this key > > (defrecord-ifn Foo [a b c]) > > (def foo (Foo. "A" "B" "C")) > > (prn (map foo [:a :c])) => ("A", "C") > > I get the error: > > "No such var: user/this". I guess this is because it is expanding > 'this' to 'user/this'. What is the proper way to get a macro like > this to expand properly? Use autogensym. Stick a # on the end of bindings you declare inside syntax-quote: this# and key#. (defmacro defrecord-ifn [name & args] `(defrecord ~name ~...@args clojure.lang.IFn (invoke [this# key#] (get this# key# -- 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: an object of class created using defrecord does not implement IFn .. while it behaves very similar to map otherwise ..
Worked like a charm. Thanks Alex. -- 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: an object of class created using defrecord does not implement IFn .. while it behaves very similar to map otherwise ..
Technically, there's no possibility of variable capture, but you should use gensyms: (defmacro defrecord-ifn [name & args] `(defrecord ~name ~...@args clojure.lang.IFn (invoke [this# key#] (get this# key# Thanks, Alyssa On Dec 30, 9:29 pm, Alex Baranosky wrote: > I've been playing with making a macro to encapsulate Stuart's post, like > this: > > (defmacro defrecord-ifn [name & args] > `(defrecord ~name ~...@args > clojure.lang.IFn > (invoke [this key] (get this key > > (defrecord-ifn Foo [a b c]) > > (def foo (Foo. "A" "B" "C")) > > (prn (map foo [:a :c])) => ("A", "C") > > I get the error: > > "No such var: user/this". I guess this is because it is expanding 'this' to > 'user/this'. What is the proper way to get a macro like this to expand > properly? > > Alex -- 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: Boston meetup Jan 11?
I'll also be at the Boston Coding Dojo sessions on the 6th and 20th, and would be willing to split the room price if you all wanted to meet during the week of the 9th-16th. Alex -- 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 in Small Pieces -- Literate Clojure
Well, I previously commented that Advocacy is Volunteering and then I managed to advocate moving clojure to literate form. Since I'm studying the details of the inner workings of Clojure this seemed to be the right time to experiment with a literate form. I have put together the beginnings of a Clojure in Small Pieces book. The PDF of the books is at: http://daly.axiom-developer.org/clojure.pdf and the literate program sources are at: http://daly.axiom-developer.org/clojure.pamphlet The book is in pure latex and requires a single style file at: http://daly.axiom-developer.org/clojure.sty The book is hyperlinked so if your pdf reader supports it you can go to the index and find pieces of code or move from the table of contents to the appropriate code chunks. Chunking is very coarse-grained at the moment but will become smaller as more code is explained. The literate chunk machinery uses the previously posted code. The code has been lightly modified to fit into the page format. Clearly some of the developers have very wide screens. When rendered on a page in raw form the code runs off the side of the page. The book sources are 1.3.0-alpha4 (so far). There is almost no prose in the book yet as the initial format process has taken up most of the time so far. You can see from the outline that there is much to discuss. The goal is to break out the code that implements various features into sections organized around the ideas, making it easier to get a "conceptual view" of the code. Suggestions for other sections are welcome. Feel free to pick a section that interests you and we can coordinate adding it to the book. I'm "Acting Editor-in-Chief" at the moment so I get to choose the final form (mostly for style, flow, clarity, etc). The aim of the book is to enable anyone to study and contribute their understanding of portions of Clojure. I am beginning to study the PersistentTreeMap which is based on Red-Black trees. In the book you can see that I've split out portions of the code into the Red-Black section, the Seq section, and the Iterator section. I am also experimenting with parallel programming using both MPI and MapReduce (Hadoop). The idea is to build a multiple node Ants demo that has N independent ant colonies, one per parallel node, all being displayed on a single ant field. I would like the parallel form to be very close in spirit to Rich's original version so I'll have to document that in detail first. Note that the people named on the front cover are from the author tags in the source code. I have no idea who else might have worked on portions of the code. If you know, please let me know. Literature references are especially welcome. I have a few, such as the Multi-Version Concurrency Control papers, which will be added when I get to the STM section. In any case, this is purely an experiment in literate clojure. Feedback is welcome. Tim Daly -- 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: an object of class created using defrecord does not implement IFn .. while it behaves very similar to map otherwise ..
Argh! Six minutes! :P On Dec 30, 9:42 pm, Alyssa Kwan wrote: > Technically, there's no possibility of variable capture, but you > should use gensyms: > > (defmacro defrecord-ifn [name & args] > `(defrecord ~name ~...@args > clojure.lang.IFn > (invoke [this# key#] (get this# key# > > Thanks, > Alyssa > > On Dec 30, 9:29 pm, Alex Baranosky > wrote: > > > > > I've been playing with making a macro to encapsulate Stuart's post, like > > this: > > > (defmacro defrecord-ifn [name & args] > > `(defrecord ~name ~...@args > > clojure.lang.IFn > > (invoke [this key] (get this key > > > (defrecord-ifn Foo [a b c]) > > > (def foo (Foo. "A" "B" "C")) > > > (prn (map foo [:a :c])) => ("A", "C") > > > I get the error: > > > "No such var: user/this". I guess this is because it is expanding 'this' to > > 'user/this'. What is the proper way to get a macro like this to expand > > properly? > > > Alex -- 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 can't see a method in my protocol
On Thu, Dec 30, 2010 at 7:41 PM, André Thieme wrote: > Do you observe this in a fresh Clojure? > I ran into something similar, but with definterface. > I had a definterface form and later added new functions to it, which I > could not implement before restarting the JVM, as the interface has > already been created the way I specified it in the first place. Tangent: this incident is the one I was referring to earlier in another thread regarding some of the defprotocol-related features combining poorly with in-REPL development, which I had trouble locating when I wanted to use it as an example. (And now that other thread where the topic came up is, of course, the one I can't seem to locate!) -- 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 can't see a method in my protocol
I didn't think it was a problem with the clojure version because I was using the maven plugin and tried several versions, but when I got to my laptop the next day and ran the exact same programs and everything worked just fine. At this point my plan is to delete my maven repositories and if that doesn't work reboot, if that doesn't work I'll just use it for computer games like I did before. On Dec 30, 5:41 pm, André Thieme wrote: > Am 30.12.2010 07:54, schrieb Jarl Haggerty: > > > > > This code, > > > (defprotocol Matrix > > (matrix-get [this c r])) > > > (deftype Matrix2D [data height width] > > Matrix > > (matrix-get [this r c] 1)) > > > Gives me this error > > > Exception in thread "main" java.lang.IllegalArgumentException: Can't > > define method not in interfaces: matrix_get (core.clj:6) > > [ ] > > > Simply changing the name of the function to get-cell removed this > > problem, but I feel a need to know what is wrong with this. > > Do you observe this in a fresh Clojure? > I ran into something similar, but with definterface. > I had a definterface form and later added new functions to it, which I > could not implement before restarting the JVM, as the interface has > already been created the way I specified it in the first place. -- 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
Do type hints cause auto casting?
I have this function (defn floor ^int [^float x] x) and (floor 1.5) returns 1.5 which confuses me as to how type hints work, I was expecting the result to be truncated or for the program to spit out some exception about expecting an int and getting a float. -- 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: an object of class created using defrecord does not implement IFn .. while it behaves very similar to map otherwise ..
thanks everybody for the responses .. with macros around ... you just have to wish for it to get it .. but we need to be careful what we wish for :) Sunil. On Fri, Dec 31, 2010 at 8:18 AM, Alyssa Kwan wrote: > Argh! Six minutes! :P > > On Dec 30, 9:42 pm, Alyssa Kwan wrote: > > Technically, there's no possibility of variable capture, but you > > should use gensyms: > > > > (defmacro defrecord-ifn [name & args] > > `(defrecord ~name ~...@args > > clojure.lang.IFn > > (invoke [this# key#] (get this# key# > > > > Thanks, > > Alyssa > > > > On Dec 30, 9:29 pm, Alex Baranosky > > wrote: > > > > > > > > > I've been playing with making a macro to encapsulate Stuart's post, > like > > > this: > > > > > (defmacro defrecord-ifn [name & args] > > > `(defrecord ~name ~...@args > > > clojure.lang.IFn > > > (invoke [this key] (get this key > > > > > (defrecord-ifn Foo [a b c]) > > > > > (def foo (Foo. "A" "B" "C")) > > > > > (prn (map foo [:a :c])) => ("A", "C") > > > > > I get the error: > > > > > "No such var: user/this". I guess this is because it is expanding > 'this' to > > > 'user/this'. What is the proper way to get a macro like this to expand > > > properly? > > > > > Alex > > -- > 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 > -- 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: Do type hints cause auto casting?
I don't think type hints lead to auto casting .. May be somebody else can throw more light on it. And it is this way by design. Sunil. On Fri, Dec 31, 2010 at 9:35 AM, Jarl Haggerty wrote: > I have this function > > (defn floor > ^int [^float x] x) > > and (floor 1.5) returns 1.5 which confuses me as to how type hints > work, I was expecting the result to be truncated or for the program to > spit out some exception about expecting an int and getting a float. > > -- > 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 -- 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
vsClojure Release
The first release of vsClojure is now available in the Visual Studio Gallery. You can download it using the extension manager in Visual Studio 2010 and searching for "vsClojure". There should be no manual setup and the extension will work with the Visual Studio 2010 Shell. This release focused on implementing basic features, laying the plumbing for more advanced features and creating a packaging strategy. For a complete list of features please visit http://github.com/jmis/vsClojure. Future releases depend on your feedback. Feel free to open issues in the issue tracker or post suggestions in the discussion group at http://groups.google.com/group/vsclojure-extension. Thanks, jmis -- 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: an object of class created using defrecord does not implement IFn .. while it behaves very similar to map otherwise ..
Am 31.12.2010 03:29, schrieb Alex Baranosky: I've been playing with making a macro to encapsulate Stuart's post, like this: (defmacro defrecord-ifn [name & args] `(defrecord ~name ~...@args clojure.lang.IFn (invoke [this key] (get this key (defrecord-ifn Foo [a b c]) (def foo (Foo. "A" "B" "C")) (prn (map foo [:a :c])) => ("A", "C") I get the error: "No such var: user/this". I guess this is because it is expanding 'this' to 'user/this'. What is the proper way to get a macro like this to expand properly? Others have already pointed to “this#”. I just would like to add that you can as well use “~'this” in some cases, where your macros generate defns. The advantage is that some editors (like emacs) will show you the parameter vector and that would show a useful name and not “this_auto_foobarbaz123456”. -- 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: Do type hints cause auto casting?
I think I asked the wrong question, not only that but I guess I answered the question I asked, what I want to know is what exactly is a type hint. I think I've failed to understand exactly what a type hint is, I assumed to give a hint was to statically type something but that doesn't seem to be what happens here. On Dec 30, 9:18 pm, Sunil S Nandihalli wrote: > I don't think type hints lead to auto casting .. May be somebody else can > throw more light on it. And it is this way by design. > Sunil. > > On Fri, Dec 31, 2010 at 9:35 AM, Jarl Haggerty wrote: > > > I have this function > > > (defn floor > > ^int [^float x] x) > > > and (floor 1.5) returns 1.5 which confuses me as to how type hints > > work, I was expecting the result to be truncated or for the program to > > spit out some exception about expecting an int and getting a float. > > > -- > > 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 > > -- 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
Chunking is making my life more difficult.
I spent a long time debugging some Clojure code yesterday. The essence of it looked similar to this: (defn items [] (mapcat expensive-function (range 0 4000 100))) . . . (take 5 (items)) . . . expensive-function is a function that issues an HTTP GET to retrieve a vector of data. Since range's docstring says it returns a lazy sequence, and since mapcat is defined in terms of map and concat, which are both supposed to return lazy sequences, I expected (take 5 (items)) to cause only one HTTP GET. In reality, it causes 32 GETs. That's kind of costly in time and space, considering I merely wanted the first 5 of the 100 items returned in the response to the first GET. This behavior was baffling to me at first, but after some research I found section 12.3 of _The Joy of Clojure_, which mentions that ever since Clojure 1.1 some functions (such as range) which are advertised as lazy are actually moderately eager, realizing chunks of up to 32 elements at a time. I retrieved the release notes for Clojure 1.1. In the section about chunking, it says, "Please share any use cases where chunked processing has resulted in behavioral differences that matter to you on the Clojure Google group." That's why I posted this. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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: Chunking is making my life more difficult.
On Fri, Dec 31, 2010 at 12:25 AM, ehanneken wrote: > I spent a long time debugging some Clojure code yesterday. The > essence of it looked similar to this: > > (defn items [] > (mapcat expensive-function (range 0 4000 100))) > > . . . (take 5 (items)) . . . > > expensive-function is a function that issues an HTTP GET to retrieve a > vector of data. Since range's docstring says it returns a lazy > sequence, and since mapcat is defined in terms of map and concat, > which are both supposed to return lazy sequences, I expected (take 5 > (items)) to cause only one HTTP GET. In reality, it causes 32 GETs. > That's kind of costly in time and space, considering I merely wanted > the first 5 of the 100 items returned in the response to the first > GET. > > This behavior was baffling to me at first, but after some research I > found section 12.3 of _The Joy of Clojure_, which mentions that ever > since Clojure 1.1 some functions (such as range) which are advertised > as lazy are actually moderately eager, realizing chunks of up to 32 > elements at a time. Interesting. I find it odd, though, that that would result in expensive-function being called 32 times. I'd expect mapcat to cause it to be called once; so you'd realize the first 32 elements of (range 0 4000 100) and consume one, and realize the first 100 elements of (mapcat expensive-function (range 0 4000 100)) and consume five. Is mapcat also semi-eager, then? -- 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: Insertion - The clojure way
On Thu, Dec 30, 2010 at 4:19 PM, Mark Engelberg wrote: > On Thu, Dec 30, 2010 at 11:01 AM, Ken Wesson wrote: >> I hope that didn't include a naive benchmarking of >> take/drop/concat/seq. Because three of those are lazy, you need to >> wrap the output of an algorithm using them in a (doall ...) and then >> in your timing function to get an accurate read on the amount of time >> it actually takes to perform the full algorithm. > > Yes, I compared with doall. Try it and let me know if you get > different results, but I find that traversing a finger tree is so much > slower than traversing a sequence, it all but nullifies any advantages > you get from other operations (even assuming the other operations are > way faster, which they typically are not). Are these searches, which should be log n? Or full (e.g. in-order) traversals? Traversals of persistent trees can be tricky, since there won't be a parent pointer on each node. But I'd think a judicious use of tree-seq would be effective in traversing one decently. I can test this when I have more time: implement a red-black finger tree, say, and check the speeds of various operations including a tree-seq based in-order traversal. -- 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: Chunking is making my life more difficult.
On Fri, Dec 31, 2010 at 12:25 AM, ehanneken wrote: > I spent a long time debugging some Clojure code yesterday. The > essence of it looked similar to this: > > (defn items [] > (mapcat expensive-function (range 0 4000 100))) > > . . . (take 5 (items)) . . . > > expensive-function is a function that issues an HTTP GET to retrieve a > vector of data. Since range's docstring says it returns a lazy > sequence, and since mapcat is defined in terms of map and concat, > which are both supposed to return lazy sequences, I expected (take 5 > (items)) to cause only one HTTP GET. In reality, it causes 32 GETs. > That's kind of costly in time and space, considering I merely wanted > the first 5 of the 100 items returned in the response to the first > GET. > > This behavior was baffling to me at first, but after some research I > found section 12.3 of _The Joy of Clojure_, which mentions that ever > since Clojure 1.1 some functions (such as range) which are advertised > as lazy are actually moderately eager, realizing chunks of up to 32 > elements at a time. Chunking is dependent upon the type of seq being traversed, which is in turn dependent upon the type of collection underlying the seq. Ranges always produce chunked seqs, as do non-empty vectors for example. If chunking is a concern, you can always fall back to seqs "grounded" in lists, which are always unchunked (and therefore yield one-at-a-time behaviour with e.g. map): => (->> (range 50) (map println) first) 0 1 2 ... 31 nil vs… => (->> (range 50) (mapcat list) (map println) first) 0 nil I'm not sure that this means that map, concat, etc are eager in practical terms. I view the chunking in much the same light as transients vis á vis immutability of persistent data structures -- the result is a relative perf improvement that doesn't impact semantics in the vast majority of cases. In my experience, chunking is only detrimental when mapping side-effecting (usually IO-related) functions across collections, as you're doing. Given that, using a (mapcat list) interstitial to get unchunked seqs is inconsequential w.r.t. perf, etc. I'd be interested in hearing any different perspectives. FYI, chunked-seq? can be used to determine if a seq supports chunking or not. - 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: Insertion - The clojure way
On Thu, Dec 30, 2010 at 9:50 PM, Ken Wesson wrote: > Are these searches, which should be log n? Or full (e.g. in-order) traversals? I'm talking about full traversals. Finger trees are sequences, and after building the sequence, splitting, concatenating, or whatever, I find I eventually need to visit all the elements. This is something like a hundred times slower on a large finger tree than a basic sequence. I had tried a couple years back to implement finger trees in Racket, and found it too slow to be of use. Recently, when I saw chouser had developed an implementation in Clojure (https://github.com/clojure/data.finger-tree), I eagerly checked it out to see if his implementation worked better than my own effort. It's definitely faster than my Racket attempt, but I still found it to be quite slow. I hope I'm incorrect and someone can show me a good demonstration of an application where finger trees outperform Clojure's built-in sequences. But my impression is that even though they are "asymptotically fast", the constant factors are too large, and even for lists of hundreds of thousands of elements, you'd be better off, for example, doing an "inefficient" concatenation of Clojure's vectors than the "efficient" concatenation of a finger tree. Play around with chouser's implementation and let me know what you find. -- 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 in Small Pieces -- Literate Clojure
I find this exciting! Thanks for starting this. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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: How to Build "Slim" Version of clojure-contrib
Hello. Thank you for response, Stuart Sierra. I'm looking forward to complete new build configuration work and I'll use little build script for a while :-) Thank you. 2010/12/30, Stuart Sierra : > Currently, clojure-contrib's pom.xml is configured to build source-only JARs > for all libraries except those four that require ahead-of-time compilation. > > We are in the process of developing a unified build configuration for > clojure-contrib projects, including new libraries such as core.unify and > tools.nrepl. See http://dev.clojure.org/display/design/Common+Contrib+Build > for details. I will see if we can make "slim" JARs an available target in > this new configuration. > > In the mean time, you can manually construct a "slim" JAR by calling > `compile` at the REPL and packaging up the resultant .class files yourself. > > -Stuart Sierra > clojure.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 -- Name: OGINO Masanori (荻野 雅紀) E-mail: masanori.og...@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
java/Clojure MPI ..
Hello everybody, I am looking for parallel programming libraries in Clojure. I found JavaMPI but its website does not seem to be updated since 2003. I would love to hear anything about where Java stands in distributed parallel computing. I get the feeling that the Parallel colt libraries are just for shared memory parallelism. I am primarily interested in large matrix computations.. . I currently need something that can do CGLS (conjugate Gradient Least squares ) in a distributed way. It is available in parallel colt libraries .. but it is only shared-memory parallel. I am sorry this is not directly related to Clojure but would love to hear what you all have to say. Thanks, Sunil. -- 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