Re: Update multiple values in vector at once
(defn upd-vec [input-vector ids new-values] (apply assoc input-vector (interleave ids new-values))) (upd-vec [0 0 0 0 0] [1 3] [1.44 1.45]) ;= [0 1.44 0 1.45 0] On Monday, March 30, 2015 at 8:05:44 PM UTC+2, Alexandr wrote: Hello everybody, How can I update values in the vector given vector of id-s and new values? For example (defn upd-vec [input-vector ids new-values] ) (upd-vec [0 0 0 0 0] [1 3] [1.44 1.45]) Output: [0 1.44 0 1.45 0] (1st and 3rd elements are replaced) -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Update multiple values in vector at once
(defn upd-vec [input-vector ids new-values] (reduce-kv #(assoc %1 %3 (new-values %2)) input-vector ids)) (upd-vec [0 0 0 0 0] [1 3] [1.44 1.45]) ;= [0 1.44 0 1.45 0] On 30 March 2015 at 20:05, Alexandr updates...@gmail.com wrote: Hello everybody, How can I update values in the vector given vector of id-s and new values? For example (defn upd-vec [input-vector ids new-values] ) (upd-vec [0 0 0 0 0] [1 3] [1.44 1.45]) Output: [0 1.44 0 1.45 0] (1st and 3rd elements are replaced) -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout. -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Update multiple values in vector at once
Thanks a lot! On Monday, March 30, 2015 at 8:11:25 PM UTC+2, Michał Marczyk wrote: (defn upd-vec [input-vector ids new-values] (reduce-kv #(assoc %1 %3 (new-values %2)) input-vector ids)) (upd-vec [0 0 0 0 0] [1 3] [1.44 1.45]) ;= [0 1.44 0 1.45 0] On 30 March 2015 at 20:05, Alexandr updat...@gmail.com javascript: wrote: Hello everybody, How can I update values in the vector given vector of id-s and new values? For example (defn upd-vec [input-vector ids new-values] ) (upd-vec [0 0 0 0 0] [1 3] [1.44 1.45]) Output: [0 1.44 0 1.45 0] (1st and 3rd elements are replaced) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.com javascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com javascript:. For more options, visit https://groups.google.com/d/optout. -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Update
Why are Clojure features defined in terms of Java classes, instead of as bytecode primitives? For eg: Cons is a class containing two objects: first and rest. Is this only to achieve Java interoperability, or is there more to it? -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Update
Well, why write it in primitives when there is a perfectly good compiler from java to primitives? I dont quite understand why you think there would be benefit from manually writing everything with java bytecode. The JVM works with classes, thats how its designed, Clojure itself is just a java library. On Tuesday, April 29, 2014 8:25:01 PM UTC+12, Divyansh Prakash wrote: Why are Clojure features defined in terms of Java classes, instead of as bytecode primitives? For eg: Cons is a class containing two objects: first and rest. Is this only to achieve Java interoperability, or is there more to it? -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Update
The JVM is very class-oriented. It is basically designed for Java, and corresponds pretty much to the things you can do in Java. Code belongs to methods which belong to classes, and calls are made using java method calling conventions. Data has to be stored in primitives, arrays, or objects; and arrays aren't particularly to-the-metal in Java anyway. The Byte Code Verifier keeps what you do fairly simple - eg you can't just leave things in the stack and jump to another method. Even if you wanted to do anything a bit different, the performance of the JVM all comes from the assumptions made while executing the bytecodes at runtime. If you did anything very weird, you'd probably find that these optimizations didn't kick in. On Tue, Apr 29, 2014 at 9:25 AM, Divyansh Prakash divyanshprakas...@gmail.com wrote: Why are Clojure features defined in terms of Java classes, instead of as bytecode primitives? For eg: Cons is a class containing two objects: first and rest. Is this only to achieve Java interoperability, or is there more to it? -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout. -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Update
Thank you for the explanation. What if I target a non-OO-centric VM (like Parrot or LLVM)? I've noticed that most Lisp implementations define lambda calculus primitives, and then use those as the core. I wonder what would be if we had bytecode primitives, and defined everything else on top of that. I don't know to what end, this is just an exercise. Do you know if this has been done before? -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Update
I looked into a port of Clojure to Parrot, and it basically does the same thinghttps://github.com/ayardley/ClojurePVM/blob/master/src/c/lisp/microlisp/lisp.c . -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Update
Why not emit bytecode directly from the language? Couldn't this potentially lead to tons of specialized optimizing macros? -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Update
The hard part with other runtimes will be details around things like garbage collection for the implementation of persistent data structures. Clojurescript is a better example of how this is done since most of the impls are implemented in the language itself, different from clojure-proper. Granted, printed-text compiler output sucks, but it all seems to work. Here's the javascript emission stage: https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/compiler.clj#L206 It's been ported to gambit-scheme: https://github.com/takeoutweight/clojure-scheme/blob/rewrite/src/clj/cljscm/compiler.clj On Tue, Apr 29, 2014 at 10:45 AM, Divyansh Prakash divyanshprakas...@gmail.com wrote: I looked into a port of Clojure to Parrot, and it basically does the same thinghttps://github.com/ayardley/ClojurePVM/blob/master/src/c/lisp/microlisp/lisp.c . -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout. -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Update
Check out my previous reply. The parrot vm provides gc and everything, But still the author defines lambda primitives in c, and then builds over it. -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Update
For the llvm based approach you can look at vmkit. On Wednesday, April 30, 2014 3:39:21 AM UTC+12, Divyansh Prakash wrote: Check out my previous reply. The parrot vm provides gc and everything, But still the author defines lambda primitives in c, and then builds over it. -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Update
Jasmin would be a much better choice, btw, because it could be used as a dependency in Clojure. -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Update
Seen: https://github.com/clojure/tools.emitter.jvm ? Here's the actual ASM emit: https://github.com/clojure/tools.emitter.jvm/blob/master/src/main/clojure/clojure/tools/emitter/jvm/transform.clj On Mon, Apr 28, 2014 at 5:43 PM, Divyansh Prakash divyanshprakas...@gmail.com wrote: ---IDEA--- I was wondering if we could have a bytecode DSL that would map directly to JVM assembler, using either Jasmin http://jasmin.sourceforge.net/ or Krakatau https://github.com/Storyyeller/Krakatau. Then we could define primitives using these bytecode instructions. For eg: (defroutine + [a b] (push! a) (push! b) add! pop!) that could be used to call: (+ 2 3) ;= 5 -- We could define the lambda calculus primitives in the same way. This would be awesome because bottlenecks could be optimized by embedding assembly inside Lisp itself. We could do efficient bit-manipulation, write shader routines, and what not. -- Thoughts? -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout. -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Update
Thanks! Exactly what I was looking for. -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Update to downloads page?
Or perhaps something like this: Although it is possible to download Clojure directly here link, for a more complete package management system please see Leiningen. But yes, I agree, we need a big fat notice that says don't download directly unless you know what you're doing. Timothy On Thu, Jun 21, 2012 at 1:11 PM, John Gabriele jmg3...@gmail.com wrote: Hi, It appears to me that, at the top of http://clojure.org/downloads , it should say, Though, for typical use, install [Leiningen](http://leiningen.org/index.html) and have it take care of getting Clojure for you. Would it be possible to change this? I've sent in my CA, but don't know if Rich got it yet. Thanks, ---John -- 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 -- “One of the main causes of the fall of the Roman Empire was that–lacking zero–they had no way to indicate successful termination of their C programs.” (Robert Firth) -- 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: (update-in) and getting the new value at the leaf efficiently
Here is one way to do it called update-in+. It returns a vector consisting of the new udpated value, like update-in does, followed by the original value (in case you might want to see that for some reason), followed by the updated value. (defn update-in+ ([m [k ks] f args] (if ks (let [[new-map old-val new-val] (apply update-in+ (get m k) ks f args)] [(assoc m k new-map) old-val new-val]) (let [old-val (get m k) new-val (apply f old-val args)] [(assoc m k new-val) old-val new-val] Andy On Thu, Apr 26, 2012 at 9:19 AM, Ambrose Bonnaire-Sergeant abonnaireserge...@gmail.com wrote: Hi, You shouldn't need mutation for such a function. If you look at the source of update-in, it's fairly straightforward. (defn update-in ([m [k ks] f args] (if ks (assoc m k (apply update-in (get m k) ks f args)) (assoc m k (apply f (get m k) args) Just create another function that returns a vector of the result of applying f, and the update-in result. It should be easy starting from update-in's source. (I'm not aware of an existing solution) Thanks, Ambrose On Fri, Apr 27, 2012 at 12:00 AM, blais goo...@furius.ca wrote: Hi, I have this use-case for (update-in) which keeps showing up in my code which I don't have a solution for and I'm wondering if there isn't a solution. How do I _efficiently_ obtain the new value created by an invocation of (update-in), that is, without having to get the modified value by lookups in the new map? Simplified example: (def m {:planet {:country {:state {:city {:borough 4}) (let [mm (update-in m [:planet :country :state :city :borough] (fn [old] (if (nil? old) 0 (inc old] (get-in mm [:planet :country :state :city :borough])) (update-in) returns the new/modified map, but what I want is to obtain the new count returned by the anonymous function. Having to call (get-in) right after is inefficient. This is obviously a contrived example for this question, but I have a lot of real use cases for this (where at the top level of my app I have a ref for a deep structure which changes as a response to network events). Is there an idiomatic way to do this without having to resort to mutability? (The only solution that comes to my mind is to wrap up update-in and the modifier function with a special version that updates a local mutable and return both the new map and the new object.) Nasty? Thank 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 -- 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: (update-in) and getting the new value at the leaf efficiently
I would have written the fn like this, if I was following what you've been doing: (def m {:planet {:country {:state {:city {:borough 4}) (let [mm (update-in m [:planet :country :state :city :borough ] (fnil inc -1))] (get-in mm [:planet :country :state :city :borough ])) However, when I run into this pattern I usually (let [v ((fnil inc -1) (get-in m [:planet :country :state :city :borough ]))] (assoc-in m [:planet :country :state :city :borough ] v)) The update in does a get, and I do a get-in, so I'm guessing the performance is pretty similar, though I haven't tested it. Cheers, Jay On Thu, Apr 26, 2012 at 12:00 PM, blais goo...@furius.ca wrote: Hi, I have this use-case for (update-in) which keeps showing up in my code which I don't have a solution for and I'm wondering if there isn't a solution. How do I _efficiently_ obtain the new value created by an invocation of (update-in), that is, without having to get the modified value by lookups in the new map? Simplified example: (def m {:planet {:country {:state {:city {:borough 4}) (let [mm (update-in m [:planet :country :state :city :borough] (fn [old] (if (nil? old) 0 (inc old] (get-in mm [:planet :country :state :city :borough])) (update-in) returns the new/modified map, but what I want is to obtain the new count returned by the anonymous function. Having to call (get-in) right after is inefficient. This is obviously a contrived example for this question, but I have a lot of real use cases for this (where at the top level of my app I have a ref for a deep structure which changes as a response to network events). Is there an idiomatic way to do this without having to resort to mutability? (The only solution that comes to my mind is to wrap up update-in and the modifier function with a special version that updates a local mutable and return both the new map and the new object.) Nasty? Thank 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 -- 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: (update-in) and getting the new value at the leaf efficiently
Thanks Andy, Two comments: 1. Your version does not use a transient/mutable, which is great, but it does create one vector for each level. I thought that since this would be wrapped and hidden from external view, a mutable would have been more appropriate. More generally, I still don't know yet where to position myself when I code in Clojure, in terms of performance: I'm used to coding in C where I care a lot about every little detail, like cache coherency, or in Python for glue code where I really don't worry about such minute optimizations. Perhaps I tend to eagerly overoptimize in Clojure? Don't know. I like your version in any case, thank you. 2. More importantly: I don't understand why I'm often having to add some functionality which I think of as something that everyone would need everywhere, and that makes me think I'm thinking about it the wrong way. For example, when I'm being careful about not using any mutable objects anywehre I end up with code that essentially recreates a new path to the root application every time I need to modify/store something in memory (i.e., I get a new version of the world on every update). So I wonder... isn't anybody else in dire need for something like update-in+? How come not? Isn't it a really common case that you need to modify some object far from the root object of your application, and if so, that you may need to do multiple things with that new object, beyond storing it by recreating all the intervening objects? (e.g. (dosync (alter update-in ...))) ) (Generally I find I get too little cultural osmosis when it comes to practical application of Clojure, so questions like this one come up all the time while I'm coding. Meetups and books touch on topics I understand well but rarely do people talk about the kinds of issues I'm encountering, like the one above. Libraries and other people's code often doesn't help all that much because it's fairly easy to do away with mutability in a library context. I'll just read more OPC for now I guess.) -- 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: (update-in) and getting the new value at the leaf efficiently
On Thu, Apr 26, 2012 at 4:30 PM, blais goo...@furius.ca wrote: (Generally I find I get too little cultural osmosis when it comes to practical application of Clojure, so questions like this one come up all the time while I'm coding. Meetups and books touch on topics I understand well but rarely do people talk about the kinds of issues I'm encountering, like the one above. Libraries and other people's code often doesn't help all that much because it's fairly easy to do away with mutability in a library context. I'll just read more OPC for now I guess.) Do you need to represent your data with that much nesting? (def m {:planet ... :country ... :state ... :city ... :borough 4}) What's wrong with this representation? 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: (update-in) and getting the new value at the leaf efficiently
On Thursday, April 26, 2012 4:36:52 PM UTC-4, David Nolen wrote: On Thu, Apr 26, 2012 at 4:30 PM, blais goo...@furius.ca wrote: (Generally I find I get too little cultural osmosis when it comes to practical application of Clojure, so questions like this one come up all the time while I'm coding. Meetups and books touch on topics I understand well but rarely do people talk about the kinds of issues I'm encountering, like the one above. Libraries and other people's code often doesn't help all that much because it's fairly easy to do away with mutability in a library context. I'll just read more OPC for now I guess.) Do you need to represent your data with that much nesting? (def m {:planet ... :country ... :state ... :city ... :borough 4}) What's wrong with this representation? Well this was just to simplify my original question; the real application has a root instance that is a networked application class, which contains some list of clients, each of which has a mapping of orders (per exchange / market, this is a trading application) which themselves map to events related to those orders. So it's more like application - client-handler - feed - market - order-id - event. These aren't necessarily pure data classes--some of these may be records with implementations of protocols. I suppose I could elect to move refs for modifiable things towards the leaves, but that seems to me like going against the grain and may have implications for concurrency (there are few but some threads running in parallel in this application). In this specific example of an application tree, where would you recommend the mutable objects be placed? 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: (update-in) and getting the new value at the leaf efficiently
On Thu, Apr 26, 2012 at 4:52 PM, blais goo...@furius.ca wrote: I suppose I could elect to move refs for modifiable things towards the leaves, but that seems to me like going against the grain and may have implications for concurrency (there are few but some threads running in parallel in this application). In this specific example of an application tree, where would you recommend the mutable objects be placed? Why do you need refs at leaves? 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: (update-in) and getting the new value at the leaf efficiently
On Thursday, April 26, 2012 4:59:31 PM UTC-4, David Nolen wrote: On Thu, Apr 26, 2012 at 4:52 PM, blais goo...@furius.ca wrote: I suppose I could elect to move refs for modifiable things towards the leaves, but that seems to me like going against the grain and may have implications for concurrency (there are few but some threads running in parallel in this application). In this specific example of an application tree, where would you recommend the mutable objects be placed? Why do you need refs at leaves? I receive events from a network. My application calls for storing these events and doing different things based on the changing status of orders attached to these events. I need to store them somewhere, I need to track this state in my app. At one extreme, I could store the changing state near the leaves (i.e. a list of events by order-id by ...). At another extreme, I could recreate the entire path of immutable objects all the way to the root application on every update (using update-in, and with a single ref for the root application). And then there's all the other options in between, I could have refs are every level if I chose to (but that seems very, very wrong, somehow). Java would call for mutability at the leaves. Clojure makes it easy to build it one way or another, but the language is calling for refs at the root. Isn't this a really common case of every type of application out there which has to store some changing state somewhere? -- 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: (update-in) and getting the new value at the leaf efficiently
On Thu, Apr 26, 2012 at 5:08 PM, blais goo...@furius.ca wrote: I receive events from a network. My application calls for storing these events and doing different things based on the changing status of orders attached to these events. I need to store them somewhere, I need to track this state in my app. At one extreme, I could store the changing state near the leaves (i.e. a list of events by order-id by ...). At another extreme, I could recreate the entire path of immutable objects all the way to the root application on every update (using update-in, and with a single ref for the root application). And then there's all the other options in between, I could have refs are every level if I chose to (but that seems very, very wrong, somehow). Java would call for mutability at the leaves. Clojure makes it easy to build it one way or another, but the language is calling for refs at the root. Isn't this a really common case of every type of application out there which has to store some changing state somewhere? You've already stated that your multithreaded needs are modest. Why not one atom wrapping all your data, each piece indexed by the most relevant key, and each actual piece of data is flat. 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: (update-in) and getting the new value at the leaf efficiently
I think you are too concerned with micro optimizations. get-in is probably just as efficient as attempting to bubble the state change back up and certainly simpler to work with. In practice, optimizations like this do not have a significant impact on the overall performace. Measure before you optimize. I might also add, parrelize before you optimize. Immutable data structures often makes it much easier to parrelize the algorithm, so even if you do have slow spots if the applications critical path is not affected you still may not need to optimize. There probably are several methods in clojure that can be significantly optimized and eventually someone will, but the best optimizations will come from real world performance problems not theoretical ones. Do some research on clojures vector implementation and you'll see the fastest implementation in theory is comparitively slow in practice due to the way the caching works. -- 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: Update an item from a list of maps in STM transaction
On Sat, 2012-03-31 at 11:00 -0700, Marcelo Macedo de Melo Silva wrote: I'm running multiple threads using this same list and need to update the value of an item inside a STM transaction. If you mean by value of an item the value in the database: I suggest you create an updater agent instead, shared by all the threads. While each thread is in a transaction, it can `send' an action to update the database to this agent. Agent sends are queued by the STM, so you can be sure only one update happens, and only if a transaction succeeds. If you mean to mutate the list of maps, you can't do that. I tried using one FUTURE for a REF but is not working. Not sure what this means. Futures are IDerefs... -- Stephen Compall ^aCollection allSatisfy: [:each|aCondition]: less is better -- 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: Update swank classpath on the fly?
I've noticed that swank (which I run in emacs using M-x clojure-jack- in) doesn't pickup changes to the classpath on-the-fly. For example, if I update my leiningen project.clj with a new dependency and run lein deps, I need to restart swank to have it use the library. Is there a way to load something into a running swank without restarting it (which causes loss of state in the slime-repl). I have the same project, which I suspect is a limitation of the JVM. I'd settle for a fast way to restart the session. jack. -- 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: Update swank classpath on the fly?
On Nov 4, 2011, at 11:53 AM, AndyK wrote: I've noticed that swank (which I run in emacs using M-x clojure-jack- in) doesn't pickup changes to the classpath on-the-fly. For example, if I update my leiningen project.clj with a new dependency and run lein deps, I need to restart swank to have it use the library. Is there a way to load something into a running swank without restarting it (which causes loss of state in the slime-repl). thx This is part of what pomegranate provides: https://github.com/cemerick/pomegranate It won't pick up changes from your project.clj, but it does provide an `add-dependencies` function that works with leiningen-style dependency notation (and an improved `add-classpath` if you just have jars available on disk you want to dynamically add to your classpath). However, I have at least one report that pomegranate fails under swank: https://github.com/cemerick/pomegranate/issues/1 It'd be great to get confirmation or not of that issue (or, even better, a patch to make it work under swank!). FWIW, it works fine in a command-line REPL and with nREPL (jark, counterclockwise). I've yet to test it with swank/slime myself. Cheers, - 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: update to clojure.tools.cli
It's strange that it hasn't made it to central yet. This is normally a few hours on the high end and it's been over 12 now. I double checked that the release hit sonatype https://oss.sonatype.org/content/repositories/public/org/clojure/tools.cli/0.2.0/ We might need to summon the all mighty Stuart Sierra to see if he knows what could have happened. Cheers, Aaron Bedra -- Clojure/core http://clojure.com On Tue, Nov 1, 2011 at 1:59 PM, gaz jones gareth.e.jo...@gmail.com wrote: Hi, I have made some changes to tools.cli to fix an annoying bug arround boolean flags and the inability to collect 'trailing arguments'. Whilst gathering opinions on these changes, a few other suggestions were made such as removing all magic functions and System/exit calls. The update is therefore going to break the existing API which you obviously need to be aware of if you are currently using 0.1.0 and intend to upgrade to 0.2.0. The release has been cut, but the last time I checked it still hadn't hit maven central, so this is slightly advanced notice. To see details of the new api please see: https://github.com/clojure/tools.cli. There are a few things worth mentioning... support for grouped options has been removed, and the result of the call to cli is now a vector of [options, trailing arguments, usage banner] (originally it was just a hash of options). Automatic help is also no longer provided, an example of how to roll your own is at the bottom of the aforementioned page. a brief example of the differences (see the site for full details though): 0.1.0: (cli [-p 8080 -v --foo bar some-filename] (optional [-p --port The port] #(Integer. %)) (optional [-f --foo Some foos]) (optional [-v --[no-]verbose Be chatty]) = {:port 8080, :foo bar, :verbose true} 0.2.0: (cli [-p 8080 --foo bar -v some-filename] [-p --port The port :parse-fn #(Integer. %)] [-f --foo Some foos] [-v --[no-]verbose Be chatty :default false]) = [{:port 8080, :foo bar, :verbose true}, [some-filename], *the usage banner*] Apologies for anyone upset by the timing / notification of the changes -- I will give greater advanced notice in future if there are any more breaking changes (hopefully there wont be :D) -- 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: update to clojure.tools.cli
It's on Maven Central now... On Tue, Nov 1, 2011 at 11:59 AM, Aaron Bedra aaron.be...@gmail.com wrote: It's strange that it hasn't made it to central yet. ... On Tue, Nov 1, 2011 at 1:59 PM, gaz jones gareth.e.jo...@gmail.com wrote: The release has been cut, but the last time I checked it still hadn't hit maven central, so this is slightly advanced notice. To see details of the new api please see: https://github.com/clojure/tools.cli. -- 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: update to clojure.tools.cli
On Tue, Nov 1, 2011 at 10:59 AM, gaz jones gareth.e.jo...@gmail.com wrote: The update is therefore going to break the existing API which you obviously need to be aware of if you are currently using 0.1.0 and intend to upgrade to 0.2.0. ... Apologies for anyone upset by the timing / notification of the changes -- I will give greater advanced notice in future if there are any more breaking changes (hopefully there wont be :D) FWIW, I really like the changes and will be upgrading a number of utilities to 0.2.0 shortly at World Singles (even tho' every one of them needs changes!). -- Sean A Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ World Singles, LLC. -- http://worldsingles.com/ Perfection is the enemy of the good. -- Gustave Flaubert, French realist novelist (1821-1880) -- 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: update xml attribute value
Does anyone know how to update xml element attribute value on the zipper data structure? I have something like root element1 name=x1 description=d1/ element2 name=x2 description=d2/ /root (:require (clojure [xml :as xml] [zip :as zip]) [clojure.contrib.zip-filter.xml :as zf]) (let [src (- c:/my.xml io/file xml/parse zip/xml-zip) edf (zf/xml1- src :root :element1) n (- (zf/attr :description) (zip/replace ))]) and this is giving me java.lang.ClassCastException: java.lang.Character cannot be cast to clojure.lang.Associative (test-xml-zip.clj:0) Given that 'loc is the proper location in your zipper: (zip/edit loc assoc-in [:attrs :description] new value) Allen -- 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: update xml attribute value
Thanks Allen, it works, I did not know the loc can be treated like a hash. siyu -- 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: update xml attribute value
Thanks Allen, it works, I did not know the loc can be treated like a hash. 'loc itself isn't a map even though zip/edit makes it seem that way. Behind the scenes zip/edit calls (zip/node loc) which will return a map, at least in the case of this xml example. zip/edit then applies the function you provided (assoc-in) to this map plus any supplied args. The result of this replaces the node at loc. https://github.com/clojure/clojure/blob/59b65669860a1f33825775494809e5d500c19c63/src/clj/clojure/zip.clj#L210 Allen -- 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: update-in oddness
On Jun 4, 7:37 am, Heinz N. Gies he...@licenser.net wrote: Update-in behaves oddly when getting an empty path. (update-in [] {1 2} (constantly {2 3})) returns {nil {2 3} 1 2} not {2 3} as I'd expect. get-in works well with empty pathes so I think this isn't a good behavior. I don't know why you expect that to do anything - first of all, the second argument to update-in should be a seq of keys. In any case, it throws nth not supported on this type: PersistentArrayMap [Thrown class java.lang.UnsupportedOperationException] -- 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: update-in oddness
On Jun 4, 2010, at 11:15 , Joost wrote: On Jun 4, 7:37 am, Heinz N. Gies he...@licenser.net wrote: Update-in behaves oddly when getting an empty path. (update-in [] {1 2} (constantly {2 3})) returns {nil {2 3} 1 2} not {2 3} as I'd expect. get-in works well with empty pathes so I think this isn't a good behavior. I don't know why you expect that to do anything - first of all, the second argument to update-in should be a seq of keys. In any case, it throws nth not supported on this type: PersistentArrayMap [Thrown class java.lang.UnsupportedOperationException] Sorry I mixed arguments, it should be (update-in {1 2} [] (constantly {2 3})) -- 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: update-in oddness
On Jun 4, 1:42 pm, Heinz N. Gies he...@licenser.net wrote: Sorry I mixed arguments, it should be (update-in {1 2} [] (constantly {2 3})) Yes, that gives {nil {2 3}, 1 2} You're not giving any key in the key list, so that is the reason there's a nil key now, and {2 3} is just the value that you give it, since that's what ((constantly {2 3}) nil) returns. Seems correct as far as the documentation of update-in is concerned. Joost. -- 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: update-in oddness
On Jun 4, 2:03 pm, Joost jo...@zeekat.nl wrote: Seems correct as far as the documentation of update-in is concerned. Addendum: though I think you've got a point in that inserting a nil key is unexpected. Personally, I don't really know what to expect from that expression. Joost. -- 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: update-in oddness
On Jun 4, 2010, at 14:03 , Joost wrote: On Jun 4, 1:42 pm, Heinz N. Gies he...@licenser.net wrote: Sorry I mixed arguments, it should be (update-in {1 2} [] (constantly {2 3})) Yes, that gives {nil {2 3}, 1 2} You're not giving any key in the key list, so that is the reason there's a nil key now, and {2 3} is just the value that you give it, since that's what ((constantly {2 3}) nil) returns. Seems correct as far as the documentation of update-in is concerned. I'd expect that a empty key works on the entire map, just as get-in with en empty key returns the entire map, this is kind of very important if you work with automatically with keys since otherwise you always have to handle the special case []. This is very annoying :( here an example: (if-let [r (butlast @path)] (do (alter m update-in r dissoc (last @path)) (alter m update-in r assoc {:name @sr} c)) (do (alter m dissoc (last @path)) (alter m assoc {:name @sr} c))) -- 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: update-in oddness
On Jun 4, 2010, at 14:11 , Heinz N. Gies wrote: On Jun 4, 2010, at 14:03 , Joost wrote: On Jun 4, 1:42 pm, Heinz N. Gies he...@licenser.net wrote: Sorry I mixed arguments, it should be (update-in {1 2} [] (constantly {2 3})) Yes, that gives {nil {2 3}, 1 2} You're not giving any key in the key list, so that is the reason there's a nil key now, and {2 3} is just the value that you give it, since that's what ((constantly {2 3}) nil) returns. Seems correct as far as the documentation of update-in is concerned. So for how I'd expect it to work: (defn update-in* ([m [k ks] f args] (if ks (assoc m k (apply update-in* (get m k) ks f args)) (if k (assoc m k (apply f (get m k) args)) (apply f m args) user (get-in {1 2} []) {1 2} user (update-in* {1 2} [] assoc 1 3) {1 3} In opposite of how it works: user (update-in {1 2} [] assoc 1 3) {nil {1 3}, 1 2} -- 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: update-in oddness
On Fri, Jun 4, 2010 at 10:04 AM, Heinz N. Gies he...@licenser.net wrote: On Jun 4, 2010, at 14:11 , Heinz N. Gies wrote: On Jun 4, 2010, at 14:03 , Joost wrote: On Jun 4, 1:42 pm, Heinz N. Gies he...@licenser.net wrote: Sorry I mixed arguments, it should be (update-in {1 2} [] (constantly {2 3})) Yes, that gives {nil {2 3}, 1 2} You're not giving any key in the key list, so that is the reason there's a nil key now, and {2 3} is just the value that you give it, since that's what ((constantly {2 3}) nil) returns. Seems correct as far as the documentation of update-in is concerned. So for how I'd expect it to work: (defn update-in* ([m [k ks] f args] (if ks (assoc m k (apply update-in* (get m k) ks f args)) (if k (assoc m k (apply f (get m k) args)) (apply f m args) user (get-in {1 2} []) {1 2} user (update-in* {1 2} [] assoc 1 3) {1 3} I agree with the spirit of your argument, but not your implementation: (update-in* {nil 2} [nil] (constantly 3)) ;= 3 Perhaps: (defn update-in* [m ks f args] (if-let [[k mk] ks] (if mk (assoc m k (apply update-in* (get m k) mk f args)) (assoc m k (apply f (get m k) args))) (apply f m args))) (update-in* {nil 2} [nil] (constantly 3)) ;= {nil 3} --Chouser http://joyofclojure.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: update-in oddness
On Jun 4, 2010, at 16:23 , Chouser wrote: I agree with the spirit of your argument, but not your implementation: (update-in* {nil 2} [nil] (constantly 3)) ;= 3 As so often Chouser, you are of cause totally right :). I just realized the flaw when I was about to open a ticket but you were faster ;) well this are good news so since I don't have a CA signed yet (actually I do just not send it :P) so one could use your code as a fix. Regards, Heinz -- 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: update-in and get-in why no default?
On 2 February 2010 17:55, Richard Newman holyg...@gmail.com wrote: If you view 'get-in' as an unwrapping operation, unwrapping by zero steps should return the existing collection, no? Thanks for that description I completely agree. Can you explain why you think the result should be nil? I was not thinking very clearly :) Loosely 'oh there is nothing to look up'. Thanks for setting me straight. As above: I equate nil with the empty sequence. Yup. Ok patch updated - salient part is: + ([m ks not-found] + (if (seq ks) + (if-let [l (reduce get m (butlast ks))] + (get l (last ks) not-found) + not-found) + m))) Which preserves all the desired behavior so far :) http://www.assembla.com/spaces/clojure/tickets/256-get-in-optional-default-value Regards, Tim. -- 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: update-in and get-in why no default?
Hi, On Feb 2, 1:48 pm, Timothy Pratley timothyprat...@gmail.com wrote: If you view 'get-in' as an unwrapping operation, unwrapping by zero steps should return the existing collection, no? Thanks for that description I completely agree. Hmm.. I thought of get-in as a recursive application of get. get-in now diverges from get. Maybe this version should be called unwrap instead? Sincerely Meikel -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: update-in and get-in why no default?
Hi, On Feb 2, 2:31 pm, Timothy Pratley timothyprat...@gmail.com wrote: Hmm.. I thought of get-in as a recursive application of get. get-in now diverges from get. Maybe this version should be called unwrap instead? Zero applications of get to a map might be thought of as the map itself. Are you thinking of a particular scenario where throwing an exception would be better? Ok. One could see this like that: (get-in m [:a :b]) = (get (get m :a) :b) (get-in m [:a])= (get m :a) (get-in m []) = m In so far I understand the picture of what happens. But does it make sense? get-in does a lookup of a key sequence in a nested structure of associative things. I think nil/[] are simply not in the domain of get- in. However it can be extended to nil/[] as the identity. So in the end it will probably boil down to some suitable definition argument of the domain of get-in. And I see some applications, where just returning the original thing might be handy. I'm persuaded. :) Sincerely Meikel -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: update-in and get-in why no default?
Am 31.01.2010 um 18:29 schrieb Daniel Werner: If I understand this arity version of get-in correctly, won't the default also be used if the value stored in the nested data structure evaluates to something false-y? Thanks for spotting that early! On 1 February 2010 05:46, Meikel Brandmeyer m...@kotka.de wrote: (if-let [l (reduce get m (pop ks))] (get l (peek ks) not-found) not-found)) Good idea, but peek and pop work differently on vectors and sequences, seeing get-in is not constrained to use vectors this could lead to an unexpected behavior: user= (def m {:a 1, :b 2, :c {:d 3, :e 4}, :f nil}) #'user/m user= (get-in3 m '(:c :e) 2) ;peek-pop keys applied in unexpected order 2 user= (get-in2 m '(:c :e) 2) ;expected result 4 I've replaced the patch on assembla with this: (reduce #(get %1 %2 not-found) m ks))) And added test cases for the falsey returns and seq args Regards, Tim. -- 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: update-in and get-in why no default?
Hi, On Feb 1, 1:57 pm, Timothy Pratley timothyprat...@gmail.com wrote: Good idea, but peek and pop work differently on vectors and sequences, seeing get-in is not constrained to use vectors this could lead to an unexpected behavior: user= (def m {:a 1, :b 2, :c {:d 3, :e 4}, :f nil}) #'user/m user= (get-in3 m '(:c :e) 2) ;peek-pop keys applied in unexpected order 2 user= (get-in2 m '(:c :e) 2) ;expected result 4 o.O Ok... 100% of my use-cases for get-in were with vectors up to now. Didn't think about the allowing lists also. I've replaced the patch on assembla with this: (reduce #(get %1 %2 not-found) m ks))) And added test cases for the falsey returns and seq args Consider this (admittedly constructed) case: (get-in {:a {:b 1}} [:x :c] {:c :uhoh}) I would not mind only allowing vectors in the interface. I would expect the length of such a chain sufficiently short for easy conversion if necessary. Or to use butlast/last instead of peek/pop. Again the damage would be limited by the short keychain length. (Of course it would have to be considered: is the usual keychain really short?) Sincerely Meikel -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: update-in and get-in why no default?
On 2 February 2010 00:18, Meikel Brandmeyer m...@kotka.de wrote: Consider this (admittedly constructed) case: (get-in {:a {:b 1}} [:x :c] {:c :uhoh}) Excellent point! Or to use butlast/last instead of peek/pop. I think this is the best approach. butlast/last have linear time so the overhead is small. There are still some sharp edges I'm not sure about: (A) user= (get-in {:a 1} []) {:a 1} ;; this is existing behavior, but I feel the result should be nil (B) user= (get-in {:a 1} nil) {:a 1} ;; this is existing behavior, but I feel the result should be nil (nil is a seq so not an exception) (C) user= (get-in {:a 1} 5) java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer (NO_SOURCE_FILE:0) ;; existing behavior, seems sensible to throw an exception here rather than return nil (D) user= (get-in {nil {:a 1}} [] 2) {:a 1} ;; new behavior ;; using last/butlast only - this is wrong... need to check the seq size ;; the solution depends upon what is correct for the preceding cases so need to establish those first Alternatively one could take the view that [] and nil are illegal key sequences, in which case should get-in enforce that (via preconditions or just a check) or should it just be added to the doc-string that using those values is undefined, or both? I've marked the ticket back to new in the meantime... will update once resolved. For reference here is a version that behaves most like existing get-in: (defn get-in Returns the value in a nested associative structure, where ks is a sequence of keys. Returns nil if the key is not present, or the not-found value if supplied. ([m ks] (reduce get m ks)) ([m ks not-found] (if (empty? ks) m (if-let [l (reduce get m (butlast ks))] (get l (last ks) not-found) not-found I'm not convinced returning the map when given an empty key sequence is the right thing to do, I'd prefer it to return nil or throw an exception in both arity cases. Regards, Tim. -- 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: update-in and get-in why no default?
Hi Timothy, On Feb 2, 1:19 am, Timothy Pratley timothyprat...@gmail.com wrote: There are still some sharp edges I'm not sure about: (A) user= (get-in {:a 1} []) {:a 1} ;; this is existing behavior, but I feel the result should be nil +1 for nil (B) user= (get-in {:a 1} nil) {:a 1} ;; this is existing behavior, but I feel the result should be nil (nil is a seq so not an exception) +1 for nil (C) user= (get-in {:a 1} 5) java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer (NO_SOURCE_FILE:0) ;; existing behavior, seems sensible to throw an exception here rather than return nil +1 for exception (D) user= (get-in {nil {:a 1}} [] 2) {:a 1} ;; new behavior ;; using last/butlast only - this is wrong... need to check the seq size ;; the solution depends upon what is correct for the preceding cases so need to establish those first Alternatively one could take the view that [] and nil are illegal key sequences, in which case should get-in enforce that (via preconditions or just a check) or should it just be added to the doc-string that using those values is undefined, or both? I'm not sure about this too. I tend to an exception. (get m) will also throw an exception... For reference here is a version that behaves most like existing get-in: (defn get-in Returns the value in a nested associative structure, where ks is a sequence of keys. Returns nil if the key is not present, or the not-found value if supplied. ([m ks] (reduce get m ks)) ([m ks not-found] (if (empty? ks) m (if-let [l (reduce get m (butlast ks))] (get l (last ks) not-found) not-found I would get rid of the if-let. Together with throwing an exception in case of an empty key sequence we get: (defn get-in Returns the value in a nested associative structure, where ks is a sequence of keys. Returns nil if the key is not present, or the not-found value if supplied. ([m ks] (get-in m ks nil)) ([m ks not-found] (if-let [ks (seq ks)] (get (reduce get m (butlast ks)) (last ks) not-found) (throw (Exception. key sequence must not be empty) Sincerely Meikel -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: update-in and get-in why no default?
There are still some sharp edges I'm not sure about: (A) user= (get-in {:a 1} []) {:a 1} ;; this is existing behavior, but I feel the result should be nil +1 for nil I think I disagree. If you view 'get-in' as an unwrapping operation, unwrapping by zero steps should return the existing collection, no? {:foo {:bar {:baz 1}}} [] = {:foo ... [:foo] = {:bar ... [:foo :bar]= {:baz ... This maps trivially to a sophisticated user's recursive mental model of get-in: (defn get-in [m ks] (loop [looking-at m first-key (first ks) remaining-keys (rest ks)] (if-not first-key looking-at (recur (get looking-at first-key) (first remaining-keys) (rest remaining-keys) ... if there are no keys, it returns m. That's intuitive to me, at least. Can you explain why you think the result should be nil? (B) user= (get-in {:a 1} nil) {:a 1} ;; this is existing behavior, but I feel the result should be nil (nil is a seq so not an exception) +1 for nil As above: I equate nil with the empty sequence. -- 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: update-in and get-in why no default?
Hi, On Feb 2, 7:55 am, Richard Newman holyg...@gmail.com wrote: I think I disagree. Can you explain why you think the result should be nil? Woops. I got confused. I didn't mean nil for empty key sequences. I meant throwing an exception as does get. Sincerely Meikel -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: update-in and get-in why no default?
([m ks not-found] (if-let [v (reduce get m ks)] v not-found))) If I understand this arity version of get-in correctly, won't the default also be used if the value stored in the nested data structure evaluates to something false-y? Anyway, thanks for creating the patches! -- 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: update-in and get-in why no default?
Hi, Am 31.01.2010 um 18:29 schrieb Daniel Werner: ([m ks not-found] (if-let [v (reduce get m ks)] v not-found))) If I understand this arity version of get-in correctly, won't the default also be used if the value stored in the nested data structure evaluates to something false-y? Yes. It should probably read: (if-let [l (reduce get m (pop ks))] (get l (peek ks) not-found) not-found)) Sincerely Meikel -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: update-in and get-in why no default?
On Dec 30 2009, 6:18 am, Timothy Pratley timothyprat...@gmail.com wrote: On Dec 13, 1:24 am, Rich Hickey richhic...@gmail.com wrote: fnil seems to me to have greater utility than patching all functions that apply functions with default-supplying arguments. Neat :) I like it. The get-in function could be enhanced, and would mirror get. Should I interpret 'could' as 'patch welcome' or 'let me think about it'? Patches welcome for get-in, and my fnil. Thanks, Rich -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: update-in and get-in why no default?
Rich, Your example didn't support a variadic signature. Is that the long term plan? Sean On Jan 29, 8:48 am, Rich Hickey richhic...@gmail.com wrote: On Dec 30 2009, 6:18 am, Timothy Pratley timothyprat...@gmail.com wrote: On Dec 13, 1:24 am, Rich Hickey richhic...@gmail.com wrote: fnil seems to me to have greater utility than patching all functions that apply functions with default-supplying arguments. Neat :) I like it. The get-in function could be enhanced, and would mirror get. Should I interpret 'could' as 'patch welcome' or 'let me think about it'? Patches welcome for get-in, and my fnil. Thanks, Rich -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: update-in and get-in why no default?
On Jan 29, 9:04 am, Sean Devlin francoisdev...@gmail.com wrote: Rich, Your example didn't support a variadic signature. Is that the long term plan? It's the short term plan. Let's see if there's any real need for more than three. I've never needed more than one. Rich -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: update-in and get-in why no default?
2010/1/30 Rich Hickey richhic...@gmail.com: Patches welcome for get-in, and my fnil. Groovy! uploaded to: https://www.assembla.com/spaces/clojure/tickets/256-get-in-optional-default-value https://www.assembla.com/spaces/clojure/tickets/257-add-fnil-for-wrapping-functions-to-handle-nil Regards, Tim. -- 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: update-in! (?)
I don't think zipper would help in this case On Jan 21, 12:40 am, brianh brian.h.w...@gmail.com wrote: Any chance you could rethink your approach use a zipper? On Jan 20, 9:32 am, Gabi bugspy...@gmail.com wrote: I posted a question on SO about it. Interesting discussion:http://stackoverflow.com/questions/2102606/algorithm-to-implement-non... On Jan 20, 5:39 pm, Christophe Grand christo...@cgrand.net wrote: I concur: a map (or a sorted map if you need to emulate access to a subtree) can be an option. [[1 2] [3 4]] is represented by {[0 0] 1, [0 1] 2, [1 0] 3, [1 1] 4} On Wed, Jan 20, 2010 at 4:24 PM, Sean Devlin francoisdev...@gmail.com wrote: How about a sorted set w/ a custom comparator? Of course, this rules out transients, but maybe the flatness will make up for it? On Jan 20, 10:15 am, Gabi bugspy...@gmail.com wrote: I need to add/delete much more frequently than just updating actually. On Jan 20, 4:59 pm, Sean Devlin francoisdev...@gmail.com wrote: Gabi, A similar technique is used with sparse matrices. You usually have severals arrays, one for the non-zero elements, and another one for indexing the column and a third for indexing the rows. http://pasadena.wr.usgs.gov/office/baagaard/research/papers/thesis/fi... This should be fast as long as you're only updating. If you're inserting/deleting, you might be able to get away with using a collection of 1D trees. Sean On Jan 20, 9:18 am, Gabi bugspy...@gmail.com wrote: These vectors represent trees which need to updated very frequently. So If there was an efficient way to use transients to represent transient trees the whole process would be much more efficient (so each update to a tree would be done in place instead of creating new one.) As discussed above, naive usage of transients won't help. Another approach would be implement in Java, but I wish there would some way to achieve this directly from Clojure. Now that I think about it, maybe the solution is to represent the tree as one dimensional vector instead of nested one (any good clojure algorithm for this ? Representing and traversing non binary trees as one dimensional vector?) Jan 20, 12:53 pm, Christophe Grand christo...@cgrand.net wrote: Hi Gabi! Can you tell us more about your problem, what do those deeply nested vectors represent and how are you going to update them? (are all updates batched in one part of your program?) With transients current implementation you can't write an efficient update-in! Christophe On Wed, Jan 20, 2010 at 9:15 AM, Gabi bugspy...@gmail.com wrote: Guys, I really need your expertise here. I have lots of deeply nested vectors, which i need to manipulate frequently (thousands of times) What is the most effective way to do this ? On Jan 17, 4:27 pm, Gabi bugspy...@gmail.com wrote: Right. I thought that transient performing deep 'transientivity'. Here is a fixed version. It takes a regular coll converts whatever it can to transient and update the stuff. The problem is that doing persistent!(assoc!(transient m)) on each level probably misses the whole point of performance. So while it work, it probably slower than the regular update-in. I need a better solution. (defn update-in!! modified version of core/update-in that works on, and return transiants ([m [k ks] f args] (if ks (persistent!(assoc! (transient m) k (apply update-in!! (get m k) ks f args))) (persistent!(assoc! (transient m) k (apply f (get m k) args)) On Jan 17, 3:57 pm, Chouser chou...@gmail.com wrote: On Sun, Jan 17, 2010 at 8:25 AM, Gabi bugspy...@gmail.com wrote: user= (persistent!(update-in!(transient v) [0] reverse)) Forgot to mention that v in the example is defined to [[1 2] [3 4]] So you've got a transient vector of persistent vectors of numbers. The problem is your update-in! then calls assoc! on each level, but of course assoc! on the inner persistent vector fails. You either need to make the inner vectors transient (and then call persist! on them when you're done) or use assoc! only at the outer level. --Chouserhttp://joyofclojure.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
Re: update-in! (?)
Guys, I really need your expertise here. I have lots of deeply nested vectors, which i need to manipulate frequently (thousands of times) What is the most effective way to do this ? On Jan 17, 4:27 pm, Gabi bugspy...@gmail.com wrote: Right. I thought that transient performing deep 'transientivity'. Here is a fixed version. It takes a regular coll converts whatever it can to transient and update the stuff. The problem is that doing persistent!(assoc!(transient m)) on each level probably misses the whole point of performance. So while it work, it probably slower than the regular update-in. I need a better solution. (defn update-in!! modified version of core/update-in that works on, and return transiants ([m [k ks] f args] (if ks (persistent!(assoc! (transient m) k (apply update-in!! (get m k) ks f args))) (persistent!(assoc! (transient m) k (apply f (get m k) args)) On Jan 17, 3:57 pm, Chouser chou...@gmail.com wrote: On Sun, Jan 17, 2010 at 8:25 AM, Gabi bugspy...@gmail.com wrote: user= (persistent!(update-in!(transient v) [0] reverse)) Forgot to mention that v in the example is defined to [[1 2] [3 4]] So you've got a transient vector of persistent vectors of numbers. The problem is your update-in! then calls assoc! on each level, but of course assoc! on the inner persistent vector fails. You either need to make the inner vectors transient (and then call persist! on them when you're done) or use assoc! only at the outer level. --Chouserhttp://joyofclojure.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: update-in! (?)
Hi Gabi! Can you tell us more about your problem, what do those deeply nested vectors represent and how are you going to update them? (are all updates batched in one part of your program?) With transients current implementation you can't write an efficient update-in! Christophe On Wed, Jan 20, 2010 at 9:15 AM, Gabi bugspy...@gmail.com wrote: Guys, I really need your expertise here. I have lots of deeply nested vectors, which i need to manipulate frequently (thousands of times) What is the most effective way to do this ? On Jan 17, 4:27 pm, Gabi bugspy...@gmail.com wrote: Right. I thought that transient performing deep 'transientivity'. Here is a fixed version. It takes a regular coll converts whatever it can to transient and update the stuff. The problem is that doing persistent!(assoc!(transient m)) on each level probably misses the whole point of performance. So while it work, it probably slower than the regular update-in. I need a better solution. (defn update-in!! modified version of core/update-in that works on, and return transiants ([m [k ks] f args] (if ks (persistent!(assoc! (transient m) k (apply update-in!! (get m k) ks f args))) (persistent!(assoc! (transient m) k (apply f (get m k) args)) On Jan 17, 3:57 pm, Chouser chou...@gmail.com wrote: On Sun, Jan 17, 2010 at 8:25 AM, Gabi bugspy...@gmail.com wrote: user= (persistent!(update-in!(transient v) [0] reverse)) Forgot to mention that v in the example is defined to [[1 2] [3 4]] So you've got a transient vector of persistent vectors of numbers. The problem is your update-in! then calls assoc! on each level, but of course assoc! on the inner persistent vector fails. You either need to make the inner vectors transient (and then call persist! on them when you're done) or use assoc! only at the outer level. --Chouserhttp://joyofclojure.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 -- Professional: http://cgrand.net/ (fr) On Clojure: http://clj-me.cgrand.net/ (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: update-in! (?)
These vectors represent trees which need to updated very frequently. So If there was an efficient way to use transients to represent transient trees the whole process would be much more efficient (so each update to a tree would be done in place instead of creating new one.) As discussed above, naive usage of transients won't help. Another approach would be implement in Java, but I wish there would some way to achieve this directly from Clojure. Now that I think about it, maybe the solution is to represent the tree as one dimensional vector instead of nested one (any good clojure algorithm for this ? Representing and traversing non binary trees as one dimensional vector?) Jan 20, 12:53 pm, Christophe Grand christo...@cgrand.net wrote: Hi Gabi! Can you tell us more about your problem, what do those deeply nested vectors represent and how are you going to update them? (are all updates batched in one part of your program?) With transients current implementation you can't write an efficient update-in! Christophe On Wed, Jan 20, 2010 at 9:15 AM, Gabi bugspy...@gmail.com wrote: Guys, I really need your expertise here. I have lots of deeply nested vectors, which i need to manipulate frequently (thousands of times) What is the most effective way to do this ? On Jan 17, 4:27 pm, Gabi bugspy...@gmail.com wrote: Right. I thought that transient performing deep 'transientivity'. Here is a fixed version. It takes a regular coll converts whatever it can to transient and update the stuff. The problem is that doing persistent!(assoc!(transient m)) on each level probably misses the whole point of performance. So while it work, it probably slower than the regular update-in. I need a better solution. (defn update-in!! modified version of core/update-in that works on, and return transiants ([m [k ks] f args] (if ks (persistent!(assoc! (transient m) k (apply update-in!! (get m k) ks f args))) (persistent!(assoc! (transient m) k (apply f (get m k) args)) On Jan 17, 3:57 pm, Chouser chou...@gmail.com wrote: On Sun, Jan 17, 2010 at 8:25 AM, Gabi bugspy...@gmail.com wrote: user= (persistent!(update-in!(transient v) [0] reverse)) Forgot to mention that v in the example is defined to [[1 2] [3 4]] So you've got a transient vector of persistent vectors of numbers. The problem is your update-in! then calls assoc! on each level, but of course assoc! on the inner persistent vector fails. You either need to make the inner vectors transient (and then call persist! on them when you're done) or use assoc! only at the outer level. --Chouserhttp://joyofclojure.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 -- Professional:http://cgrand.net/(fr) On Clojure:http://clj-me.cgrand.net/(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: update-in! (?)
Gabi, A similar technique is used with sparse matrices. You usually have severals arrays, one for the non-zero elements, and another one for indexing the column and a third for indexing the rows. http://pasadena.wr.usgs.gov/office/baagaard/research/papers/thesis/figs/methods/sparseMatrix.gif This should be fast as long as you're only updating. If you're inserting/deleting, you might be able to get away with using a collection of 1D trees. Sean On Jan 20, 9:18 am, Gabi bugspy...@gmail.com wrote: These vectors represent trees which need to updated very frequently. So If there was an efficient way to use transients to represent transient trees the whole process would be much more efficient (so each update to a tree would be done in place instead of creating new one.) As discussed above, naive usage of transients won't help. Another approach would be implement in Java, but I wish there would some way to achieve this directly from Clojure. Now that I think about it, maybe the solution is to represent the tree as one dimensional vector instead of nested one (any good clojure algorithm for this ? Representing and traversing non binary trees as one dimensional vector?) Jan 20, 12:53 pm, Christophe Grand christo...@cgrand.net wrote: Hi Gabi! Can you tell us more about your problem, what do those deeply nested vectors represent and how are you going to update them? (are all updates batched in one part of your program?) With transients current implementation you can't write an efficient update-in! Christophe On Wed, Jan 20, 2010 at 9:15 AM, Gabi bugspy...@gmail.com wrote: Guys, I really need your expertise here. I have lots of deeply nested vectors, which i need to manipulate frequently (thousands of times) What is the most effective way to do this ? On Jan 17, 4:27 pm, Gabi bugspy...@gmail.com wrote: Right. I thought that transient performing deep 'transientivity'. Here is a fixed version. It takes a regular coll converts whatever it can to transient and update the stuff. The problem is that doing persistent!(assoc!(transient m)) on each level probably misses the whole point of performance. So while it work, it probably slower than the regular update-in. I need a better solution. (defn update-in!! modified version of core/update-in that works on, and return transiants ([m [k ks] f args] (if ks (persistent!(assoc! (transient m) k (apply update-in!! (get m k) ks f args))) (persistent!(assoc! (transient m) k (apply f (get m k) args)) On Jan 17, 3:57 pm, Chouser chou...@gmail.com wrote: On Sun, Jan 17, 2010 at 8:25 AM, Gabi bugspy...@gmail.com wrote: user= (persistent!(update-in!(transient v) [0] reverse)) Forgot to mention that v in the example is defined to [[1 2] [3 4]] So you've got a transient vector of persistent vectors of numbers. The problem is your update-in! then calls assoc! on each level, but of course assoc! on the inner persistent vector fails. You either need to make the inner vectors transient (and then call persist! on them when you're done) or use assoc! only at the outer level. --Chouserhttp://joyofclojure.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 -- Professional:http://cgrand.net/(fr) On Clojure:http://clj-me.cgrand.net/(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: update-in! (?)
I need to add/delete much more frequently than just updating actually. On Jan 20, 4:59 pm, Sean Devlin francoisdev...@gmail.com wrote: Gabi, A similar technique is used with sparse matrices. You usually have severals arrays, one for the non-zero elements, and another one for indexing the column and a third for indexing the rows. http://pasadena.wr.usgs.gov/office/baagaard/research/papers/thesis/fi... This should be fast as long as you're only updating. If you're inserting/deleting, you might be able to get away with using a collection of 1D trees. Sean On Jan 20, 9:18 am, Gabi bugspy...@gmail.com wrote: These vectors represent trees which need to updated very frequently. So If there was an efficient way to use transients to represent transient trees the whole process would be much more efficient (so each update to a tree would be done in place instead of creating new one.) As discussed above, naive usage of transients won't help. Another approach would be implement in Java, but I wish there would some way to achieve this directly from Clojure. Now that I think about it, maybe the solution is to represent the tree as one dimensional vector instead of nested one (any good clojure algorithm for this ? Representing and traversing non binary trees as one dimensional vector?) Jan 20, 12:53 pm, Christophe Grand christo...@cgrand.net wrote: Hi Gabi! Can you tell us more about your problem, what do those deeply nested vectors represent and how are you going to update them? (are all updates batched in one part of your program?) With transients current implementation you can't write an efficient update-in! Christophe On Wed, Jan 20, 2010 at 9:15 AM, Gabi bugspy...@gmail.com wrote: Guys, I really need your expertise here. I have lots of deeply nested vectors, which i need to manipulate frequently (thousands of times) What is the most effective way to do this ? On Jan 17, 4:27 pm, Gabi bugspy...@gmail.com wrote: Right. I thought that transient performing deep 'transientivity'. Here is a fixed version. It takes a regular coll converts whatever it can to transient and update the stuff. The problem is that doing persistent!(assoc!(transient m)) on each level probably misses the whole point of performance. So while it work, it probably slower than the regular update-in. I need a better solution. (defn update-in!! modified version of core/update-in that works on, and return transiants ([m [k ks] f args] (if ks (persistent!(assoc! (transient m) k (apply update-in!! (get m k) ks f args))) (persistent!(assoc! (transient m) k (apply f (get m k) args)) On Jan 17, 3:57 pm, Chouser chou...@gmail.com wrote: On Sun, Jan 17, 2010 at 8:25 AM, Gabi bugspy...@gmail.com wrote: user= (persistent!(update-in!(transient v) [0] reverse)) Forgot to mention that v in the example is defined to [[1 2] [3 4]] So you've got a transient vector of persistent vectors of numbers. The problem is your update-in! then calls assoc! on each level, but of course assoc! on the inner persistent vector fails. You either need to make the inner vectors transient (and then call persist! on them when you're done) or use assoc! only at the outer level. --Chouserhttp://joyofclojure.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 -- Professional:http://cgrand.net/(fr) On Clojure:http://clj-me.cgrand.net/(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: update-in! (?)
How about a sorted set w/ a custom comparator? Of course, this rules out transients, but maybe the flatness will make up for it? On Jan 20, 10:15 am, Gabi bugspy...@gmail.com wrote: I need to add/delete much more frequently than just updating actually. On Jan 20, 4:59 pm, Sean Devlin francoisdev...@gmail.com wrote: Gabi, A similar technique is used with sparse matrices. You usually have severals arrays, one for the non-zero elements, and another one for indexing the column and a third for indexing the rows. http://pasadena.wr.usgs.gov/office/baagaard/research/papers/thesis/fi... This should be fast as long as you're only updating. If you're inserting/deleting, you might be able to get away with using a collection of 1D trees. Sean On Jan 20, 9:18 am, Gabi bugspy...@gmail.com wrote: These vectors represent trees which need to updated very frequently. So If there was an efficient way to use transients to represent transient trees the whole process would be much more efficient (so each update to a tree would be done in place instead of creating new one.) As discussed above, naive usage of transients won't help. Another approach would be implement in Java, but I wish there would some way to achieve this directly from Clojure. Now that I think about it, maybe the solution is to represent the tree as one dimensional vector instead of nested one (any good clojure algorithm for this ? Representing and traversing non binary trees as one dimensional vector?) Jan 20, 12:53 pm, Christophe Grand christo...@cgrand.net wrote: Hi Gabi! Can you tell us more about your problem, what do those deeply nested vectors represent and how are you going to update them? (are all updates batched in one part of your program?) With transients current implementation you can't write an efficient update-in! Christophe On Wed, Jan 20, 2010 at 9:15 AM, Gabi bugspy...@gmail.com wrote: Guys, I really need your expertise here. I have lots of deeply nested vectors, which i need to manipulate frequently (thousands of times) What is the most effective way to do this ? On Jan 17, 4:27 pm, Gabi bugspy...@gmail.com wrote: Right. I thought that transient performing deep 'transientivity'. Here is a fixed version. It takes a regular coll converts whatever it can to transient and update the stuff. The problem is that doing persistent!(assoc!(transient m)) on each level probably misses the whole point of performance. So while it work, it probably slower than the regular update-in. I need a better solution. (defn update-in!! modified version of core/update-in that works on, and return transiants ([m [k ks] f args] (if ks (persistent!(assoc! (transient m) k (apply update-in!! (get m k) ks f args))) (persistent!(assoc! (transient m) k (apply f (get m k) args)) On Jan 17, 3:57 pm, Chouser chou...@gmail.com wrote: On Sun, Jan 17, 2010 at 8:25 AM, Gabi bugspy...@gmail.com wrote: user= (persistent!(update-in!(transient v) [0] reverse)) Forgot to mention that v in the example is defined to [[1 2] [3 4]] So you've got a transient vector of persistent vectors of numbers. The problem is your update-in! then calls assoc! on each level, but of course assoc! on the inner persistent vector fails. You either need to make the inner vectors transient (and then call persist! on them when you're done) or use assoc! only at the outer level. --Chouserhttp://joyofclojure.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 -- Professional:http://cgrand.net/(fr) On Clojure:http://clj-me.cgrand.net/(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: update-in! (?)
Can you elaborate more ? How can trees be represented in sorted sets? On Jan 20, 5:24 pm, Sean Devlin francoisdev...@gmail.com wrote: How about a sorted set w/ a custom comparator? Of course, this rules out transients, but maybe the flatness will make up for it? On Jan 20, 10:15 am, Gabi bugspy...@gmail.com wrote: I need to add/delete much more frequently than just updating actually. On Jan 20, 4:59 pm, Sean Devlin francoisdev...@gmail.com wrote: Gabi, A similar technique is used with sparse matrices. You usually have severals arrays, one for the non-zero elements, and another one for indexing the column and a third for indexing the rows. http://pasadena.wr.usgs.gov/office/baagaard/research/papers/thesis/fi... This should be fast as long as you're only updating. If you're inserting/deleting, you might be able to get away with using a collection of 1D trees. Sean On Jan 20, 9:18 am, Gabi bugspy...@gmail.com wrote: These vectors represent trees which need to updated very frequently. So If there was an efficient way to use transients to represent transient trees the whole process would be much more efficient (so each update to a tree would be done in place instead of creating new one.) As discussed above, naive usage of transients won't help. Another approach would be implement in Java, but I wish there would some way to achieve this directly from Clojure. Now that I think about it, maybe the solution is to represent the tree as one dimensional vector instead of nested one (any good clojure algorithm for this ? Representing and traversing non binary trees as one dimensional vector?) Jan 20, 12:53 pm, Christophe Grand christo...@cgrand.net wrote: Hi Gabi! Can you tell us more about your problem, what do those deeply nested vectors represent and how are you going to update them? (are all updates batched in one part of your program?) With transients current implementation you can't write an efficient update-in! Christophe On Wed, Jan 20, 2010 at 9:15 AM, Gabi bugspy...@gmail.com wrote: Guys, I really need your expertise here. I have lots of deeply nested vectors, which i need to manipulate frequently (thousands of times) What is the most effective way to do this ? On Jan 17, 4:27 pm, Gabi bugspy...@gmail.com wrote: Right. I thought that transient performing deep 'transientivity'. Here is a fixed version. It takes a regular coll converts whatever it can to transient and update the stuff. The problem is that doing persistent!(assoc!(transient m)) on each level probably misses the whole point of performance. So while it work, it probably slower than the regular update-in. I need a better solution. (defn update-in!! modified version of core/update-in that works on, and return transiants ([m [k ks] f args] (if ks (persistent!(assoc! (transient m) k (apply update-in!! (get m k) ks f args))) (persistent!(assoc! (transient m) k (apply f (get m k) args)) On Jan 17, 3:57 pm, Chouser chou...@gmail.com wrote: On Sun, Jan 17, 2010 at 8:25 AM, Gabi bugspy...@gmail.com wrote: user= (persistent!(update-in!(transient v) [0] reverse)) Forgot to mention that v in the example is defined to [[1 2] [3 4]] So you've got a transient vector of persistent vectors of numbers. The problem is your update-in! then calls assoc! on each level, but of course assoc! on the inner persistent vector fails. You either need to make the inner vectors transient (and then call persist! on them when you're done) or use assoc! only at the outer level. --Chouserhttp://joyofclojure.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 -- Professional:http://cgrand.net/(fr) On Clojure:http://clj-me.cgrand.net/(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: update-in! (?)
I concur: a map (or a sorted map if you need to emulate access to a subtree) can be an option. [[1 2] [3 4]] is represented by {[0 0] 1, [0 1] 2, [1 0] 3, [1 1] 4} On Wed, Jan 20, 2010 at 4:24 PM, Sean Devlin francoisdev...@gmail.com wrote: How about a sorted set w/ a custom comparator? Of course, this rules out transients, but maybe the flatness will make up for it? On Jan 20, 10:15 am, Gabi bugspy...@gmail.com wrote: I need to add/delete much more frequently than just updating actually. On Jan 20, 4:59 pm, Sean Devlin francoisdev...@gmail.com wrote: Gabi, A similar technique is used with sparse matrices. You usually have severals arrays, one for the non-zero elements, and another one for indexing the column and a third for indexing the rows. http://pasadena.wr.usgs.gov/office/baagaard/research/papers/thesis/fi... This should be fast as long as you're only updating. If you're inserting/deleting, you might be able to get away with using a collection of 1D trees. Sean On Jan 20, 9:18 am, Gabi bugspy...@gmail.com wrote: These vectors represent trees which need to updated very frequently. So If there was an efficient way to use transients to represent transient trees the whole process would be much more efficient (so each update to a tree would be done in place instead of creating new one.) As discussed above, naive usage of transients won't help. Another approach would be implement in Java, but I wish there would some way to achieve this directly from Clojure. Now that I think about it, maybe the solution is to represent the tree as one dimensional vector instead of nested one (any good clojure algorithm for this ? Representing and traversing non binary trees as one dimensional vector?) Jan 20, 12:53 pm, Christophe Grand christo...@cgrand.net wrote: Hi Gabi! Can you tell us more about your problem, what do those deeply nested vectors represent and how are you going to update them? (are all updates batched in one part of your program?) With transients current implementation you can't write an efficient update-in! Christophe On Wed, Jan 20, 2010 at 9:15 AM, Gabi bugspy...@gmail.com wrote: Guys, I really need your expertise here. I have lots of deeply nested vectors, which i need to manipulate frequently (thousands of times) What is the most effective way to do this ? On Jan 17, 4:27 pm, Gabi bugspy...@gmail.com wrote: Right. I thought that transient performing deep 'transientivity'. Here is a fixed version. It takes a regular coll converts whatever it can to transient and update the stuff. The problem is that doing persistent!(assoc!(transient m)) on each level probably misses the whole point of performance. So while it work, it probably slower than the regular update-in. I need a better solution. (defn update-in!! modified version of core/update-in that works on, and return transiants ([m [k ks] f args] (if ks (persistent!(assoc! (transient m) k (apply update-in!! (get m k) ks f args))) (persistent!(assoc! (transient m) k (apply f (get m k) args)) On Jan 17, 3:57 pm, Chouser chou...@gmail.com wrote: On Sun, Jan 17, 2010 at 8:25 AM, Gabi bugspy...@gmail.com wrote: user= (persistent!(update-in!(transient v) [0] reverse)) Forgot to mention that v in the example is defined to [[1 2] [3 4]] So you've got a transient vector of persistent vectors of numbers. The problem is your update-in! then calls assoc! on each level, but of course assoc! on the inner persistent vector fails. You either need to make the inner vectors transient (and then call persist! on them when you're done) or use assoc! only at the outer level. --Chouserhttp://joyofclojure.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 -- Professional:http://cgrand.net/(fr) On Clojure:http://clj-me.cgrand.net/(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 -- Professional: http://cgrand.net/ (fr) On Clojure:
Re: update-in! (?)
I posted a question on SO about it. Interesting discussion: http://stackoverflow.com/questions/2102606/algorithm-to-implement-non-binary-trees-using-1-dimensional-vector On Jan 20, 5:39 pm, Christophe Grand christo...@cgrand.net wrote: I concur: a map (or a sorted map if you need to emulate access to a subtree) can be an option. [[1 2] [3 4]] is represented by {[0 0] 1, [0 1] 2, [1 0] 3, [1 1] 4} On Wed, Jan 20, 2010 at 4:24 PM, Sean Devlin francoisdev...@gmail.com wrote: How about a sorted set w/ a custom comparator? Of course, this rules out transients, but maybe the flatness will make up for it? On Jan 20, 10:15 am, Gabi bugspy...@gmail.com wrote: I need to add/delete much more frequently than just updating actually. On Jan 20, 4:59 pm, Sean Devlin francoisdev...@gmail.com wrote: Gabi, A similar technique is used with sparse matrices. You usually have severals arrays, one for the non-zero elements, and another one for indexing the column and a third for indexing the rows. http://pasadena.wr.usgs.gov/office/baagaard/research/papers/thesis/fi... This should be fast as long as you're only updating. If you're inserting/deleting, you might be able to get away with using a collection of 1D trees. Sean On Jan 20, 9:18 am, Gabi bugspy...@gmail.com wrote: These vectors represent trees which need to updated very frequently. So If there was an efficient way to use transients to represent transient trees the whole process would be much more efficient (so each update to a tree would be done in place instead of creating new one.) As discussed above, naive usage of transients won't help. Another approach would be implement in Java, but I wish there would some way to achieve this directly from Clojure. Now that I think about it, maybe the solution is to represent the tree as one dimensional vector instead of nested one (any good clojure algorithm for this ? Representing and traversing non binary trees as one dimensional vector?) Jan 20, 12:53 pm, Christophe Grand christo...@cgrand.net wrote: Hi Gabi! Can you tell us more about your problem, what do those deeply nested vectors represent and how are you going to update them? (are all updates batched in one part of your program?) With transients current implementation you can't write an efficient update-in! Christophe On Wed, Jan 20, 2010 at 9:15 AM, Gabi bugspy...@gmail.com wrote: Guys, I really need your expertise here. I have lots of deeply nested vectors, which i need to manipulate frequently (thousands of times) What is the most effective way to do this ? On Jan 17, 4:27 pm, Gabi bugspy...@gmail.com wrote: Right. I thought that transient performing deep 'transientivity'. Here is a fixed version. It takes a regular coll converts whatever it can to transient and update the stuff. The problem is that doing persistent!(assoc!(transient m)) on each level probably misses the whole point of performance. So while it work, it probably slower than the regular update-in. I need a better solution. (defn update-in!! modified version of core/update-in that works on, and return transiants ([m [k ks] f args] (if ks (persistent!(assoc! (transient m) k (apply update-in!! (get m k) ks f args))) (persistent!(assoc! (transient m) k (apply f (get m k) args)) On Jan 17, 3:57 pm, Chouser chou...@gmail.com wrote: On Sun, Jan 17, 2010 at 8:25 AM, Gabi bugspy...@gmail.com wrote: user= (persistent!(update-in!(transient v) [0] reverse)) Forgot to mention that v in the example is defined to [[1 2] [3 4]] So you've got a transient vector of persistent vectors of numbers. The problem is your update-in! then calls assoc! on each level, but of course assoc! on the inner persistent vector fails. You either need to make the inner vectors transient (and then call persist! on them when you're done) or use assoc! only at the outer level. --Chouserhttp://joyofclojure.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 -- Professional:http://cgrand.net/(fr) On Clojure:http://clj-me.cgrand.net/(en) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to
Re: update-in! (?)
Any chance you could rethink your approach use a zipper? On Jan 20, 9:32 am, Gabi bugspy...@gmail.com wrote: I posted a question on SO about it. Interesting discussion:http://stackoverflow.com/questions/2102606/algorithm-to-implement-non... On Jan 20, 5:39 pm, Christophe Grand christo...@cgrand.net wrote: I concur: a map (or a sorted map if you need to emulate access to a subtree) can be an option. [[1 2] [3 4]] is represented by {[0 0] 1, [0 1] 2, [1 0] 3, [1 1] 4} On Wed, Jan 20, 2010 at 4:24 PM, Sean Devlin francoisdev...@gmail.com wrote: How about a sorted set w/ a custom comparator? Of course, this rules out transients, but maybe the flatness will make up for it? On Jan 20, 10:15 am, Gabi bugspy...@gmail.com wrote: I need to add/delete much more frequently than just updating actually. On Jan 20, 4:59 pm, Sean Devlin francoisdev...@gmail.com wrote: Gabi, A similar technique is used with sparse matrices. You usually have severals arrays, one for the non-zero elements, and another one for indexing the column and a third for indexing the rows. http://pasadena.wr.usgs.gov/office/baagaard/research/papers/thesis/fi... This should be fast as long as you're only updating. If you're inserting/deleting, you might be able to get away with using a collection of 1D trees. Sean On Jan 20, 9:18 am, Gabi bugspy...@gmail.com wrote: These vectors represent trees which need to updated very frequently. So If there was an efficient way to use transients to represent transient trees the whole process would be much more efficient (so each update to a tree would be done in place instead of creating new one.) As discussed above, naive usage of transients won't help. Another approach would be implement in Java, but I wish there would some way to achieve this directly from Clojure. Now that I think about it, maybe the solution is to represent the tree as one dimensional vector instead of nested one (any good clojure algorithm for this ? Representing and traversing non binary trees as one dimensional vector?) Jan 20, 12:53 pm, Christophe Grand christo...@cgrand.net wrote: Hi Gabi! Can you tell us more about your problem, what do those deeply nested vectors represent and how are you going to update them? (are all updates batched in one part of your program?) With transients current implementation you can't write an efficient update-in! Christophe On Wed, Jan 20, 2010 at 9:15 AM, Gabi bugspy...@gmail.com wrote: Guys, I really need your expertise here. I have lots of deeply nested vectors, which i need to manipulate frequently (thousands of times) What is the most effective way to do this ? On Jan 17, 4:27 pm, Gabi bugspy...@gmail.com wrote: Right. I thought that transient performing deep 'transientivity'. Here is a fixed version. It takes a regular coll converts whatever it can to transient and update the stuff. The problem is that doing persistent!(assoc!(transient m)) on each level probably misses the whole point of performance. So while it work, it probably slower than the regular update-in. I need a better solution. (defn update-in!! modified version of core/update-in that works on, and return transiants ([m [k ks] f args] (if ks (persistent!(assoc! (transient m) k (apply update-in!! (get m k) ks f args))) (persistent!(assoc! (transient m) k (apply f (get m k) args)) On Jan 17, 3:57 pm, Chouser chou...@gmail.com wrote: On Sun, Jan 17, 2010 at 8:25 AM, Gabi bugspy...@gmail.com wrote: user= (persistent!(update-in!(transient v) [0] reverse)) Forgot to mention that v in the example is defined to [[1 2] [3 4]] So you've got a transient vector of persistent vectors of numbers. The problem is your update-in! then calls assoc! on each level, but of course assoc! on the inner persistent vector fails. You either need to make the inner vectors transient (and then call persist! on them when you're done) or use assoc! only at the outer level. --Chouserhttp://joyofclojure.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: update-in! (?)
Forgot to mention that v in the example is defined to [[1 2] [3 4]] On Jan 17, 3:19 pm, Gabi bugspy...@gmail.com wrote: I really needed an update-in! version that works on transients. I couldn't find one so I just modified the original update-in core (just replaced assoc assoc!): (defn update-in! modified version of core/update-in that works on, and return transients ([m [k ks] f args] (if ks (assoc! m k (apply update-in! (get m k) ks f args)) (assoc! m k (apply f (get m k) args) user= (persistent!(update-in!(transient v) [0] reverse)) [(2 1) [3 4]] BUT when using nested paths, it fails: user=(persistent!(update-in!(transient v) [0 0] inc)) java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to clojure.lang.ITransientAssociative Any idea how to solve 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: update-in! (?)
On Sun, Jan 17, 2010 at 8:25 AM, Gabi bugspy...@gmail.com wrote: user= (persistent!(update-in!(transient v) [0] reverse)) Forgot to mention that v in the example is defined to [[1 2] [3 4]] So you've got a transient vector of persistent vectors of numbers. The problem is your update-in! then calls assoc! on each level, but of course assoc! on the inner persistent vector fails. You either need to make the inner vectors transient (and then call persist! on them when you're done) or use assoc! only at the outer level. --Chouser http://joyofclojure.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: update-in! (?)
Right. I thought that transient performing deep 'transientivity'. Here is a fixed version. It takes a regular coll converts whatever it can to transient and update the stuff. The problem is that doing persistent!(assoc!(transient m)) on each level probably misses the whole point of performance. So while it work, it probably slower than the regular update-in. I need a better solution. (defn update-in!! modified version of core/update-in that works on, and return transiants ([m [k ks] f args] (if ks (persistent!(assoc! (transient m) k (apply update-in!! (get m k) ks f args))) (persistent!(assoc! (transient m) k (apply f (get m k) args)) On Jan 17, 3:57 pm, Chouser chou...@gmail.com wrote: On Sun, Jan 17, 2010 at 8:25 AM, Gabi bugspy...@gmail.com wrote: user= (persistent!(update-in!(transient v) [0] reverse)) Forgot to mention that v in the example is defined to [[1 2] [3 4]] So you've got a transient vector of persistent vectors of numbers. The problem is your update-in! then calls assoc! on each level, but of course assoc! on the inner persistent vector fails. You either need to make the inner vectors transient (and then call persist! on them when you're done) or use assoc! only at the outer level. --Chouserhttp://joyofclojure.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: update-in and get-in why no default?
2010/1/2 Sean Devlin francoisdev...@gmail.com: I don't think your version of the signature supports variadic defaults well. Hi Sean, Thanks for commenting. Just by way of clarification, taking the function as the last argument seems to work fine in my experiments. I'm sure it could be better but here what I've been using: (defn fnil Creates a new function that if passed nil as an argument, operates with supplied arguments instead. The function must be passed as the last argument. [ more] (fn [ m] (apply (last more) (map #(if (nil? %1) %2 %1) m (concat (butlast more) (drop (count (butlast more)) m)) Relating to your examples: user= (def nil+ (fnil 0 1 2 3 4 5 6 +)) user= (nil+ 0 0 0 0 0 0 nil) 6 user= (nil+ 0 0 0 0 0 0 0 nil) java.lang.NullPointerException (NO_SOURCE_FILE:0) user= ((fnil 1 +) nil 2 3 4 5) 15 ; note fnil-2 does not handle the last case, though of course it could easily if you wanted it to: user= ((fnil-2 1 +) nil 2 3 4 5) java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn (NO_SOURCE_FILE:0) ; in principle I don't think one form is any more restrictive than the other, it just comes down to a matter of preference which is the key part I wanted to generate discussion about. matches the signature of partial better, which I personally prefer. Yes that is precisely why it catches me out to write (fnil + 1) because it looks like a partial application. Partial applications are actually very common even when partial is not explicitly used: user= (swap! (atom 1) + 1) 2 So I'm used to seeing arguments to the right of a function get absorbed so to speak, and used to seeing conditionals occur in the middle of the form. Again just clarifying that I too like partial application style but have the opposite reaction in this case of wanting to contrast that for fnil as it is not a partial application. This of course is just my preference and I'm glad to hear reasoning for the other style. Regards, Tim. -- 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: update-in and get-in why no default?
2010/1/2 Timothy Pratley timothyprat...@gmail.com: user= ((fnil-2 1 +) nil 2 3 4 5) java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn (NO_SOURCE_FILE:0) Correction, I just realized of course it doesn't work if I specify the arguments around the wrong way! I should have done: user= ((fnil-2 + 1) nil 2 3 4 5) 1 ; I think this should result in 15, but that's just an implementation detail. -- 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: update-in and get-in why no default?
On Dec 13, 1:24 am, Rich Hickey richhic...@gmail.com wrote: fnil seems to me to have greater utility than patching all functions that apply functions with default-supplying arguments. Hi Rich, To further comment on fnil, after having experimented with it a bit now, I've come to slightly prefer specifying the 'default' value before the function just because I think it reads nicer: (fnil 0 inc) ;; instead of (fnil inc 0) (fnil [] conj) ;; instead of (fnil conj []) I read it as fill nil with 0 for inc I suppose fill nil of inc with 0 makes just as much sense but I find inc 0 leads my eye to believe 0 will always be passed to inc, whereas 0 inc does not. Putting the function last makes it clearer to me that the 0 is conditional. It also looks more like if nil 0. This contrasts with get, which makes perfect sense having the default last, but I think at this point fnil and get are sufficiently far apart that a different argument order would not be surprising. Just a small observation I thought I'd raise for discussion to see what preferences are out there if this function becomes widespread. Regards, Tim. -- 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: update-in and get-in why no default?
Tim, I don't think your version of the signature supports variadic defaults well. Also, I'd (initially) implement fnil differently that Rich. Here's my fnil-2 that I *suspect* has the intended behavior (defn fnil-2 [f defaults] (fn[ args] (let [used-args (map (fn [default-value value] (if value value default-value)) defaults args)] (apply f used-args user=(def nil+ (fnil-2 + 0 1 2 3 4 5 6)) user=(nil+ nil) 0 user=(nil+ 0 nil) 1 user=(nil+ 0 0 nil) 2 user=(nil+ 0 0 0 nil) 3 ... user=(nil+ 0 0 0 0 0 0 nil) 6 ;This example exceeds the provided # of nil values user=(nil+ 0 0 0 0 0 0 0 nil) NPE You get the idea. Also, Rich's style matches the signature of partial better, which I personally prefer. Just my $.02 Sean On Jan 1, 6:45 pm, Timothy Pratley timothyprat...@gmail.com wrote: On Dec 13, 1:24 am, Rich Hickey richhic...@gmail.com wrote: fnil seems to me to have greater utility than patching all functions that apply functions with default-supplying arguments. Hi Rich, To further comment on fnil, after having experimented with it a bit now, I've come to slightly prefer specifying the 'default' value before the function just because I think it reads nicer: (fnil 0 inc) ;; instead of (fnil inc 0) (fnil [] conj) ;; instead of (fnil conj []) I read it as fill nil with 0 for inc I suppose fill nil of inc with 0 makes just as much sense but I find inc 0 leads my eye to believe 0 will always be passed to inc, whereas 0 inc does not. Putting the function last makes it clearer to me that the 0 is conditional. It also looks more like if nil 0. This contrasts with get, which makes perfect sense having the default last, but I think at this point fnil and get are sufficiently far apart that a different argument order would not be surprising. Just a small observation I thought I'd raise for discussion to see what preferences are out there if this function becomes widespread. Regards, Tim. -- 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: update-in and get-in why no default?
On Dec 13, 1:24 am, Rich Hickey richhic...@gmail.com wrote: fnil seems to me to have greater utility than patching all functions that apply functions with default-supplying arguments. Neat :) I like it. The get-in function could be enhanced, and would mirror get. Should I interpret 'could' as 'patch welcome' or 'let me think about it'? Regards, Tim. -- 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: update-in and get-in why no default?
On Thu, Dec 10, 2009 at 7:20 AM, Timothy Pratley timothyprat...@gmail.com wrote: Hi, update-in is an especially useful function but I find the update function inevitably requires a check for nil. If I could supply a not- found value then my code would get better golf scores. When I reach for update-in, I usually want to pass it a numerical operator like inc or +, but these don't play nicely with nil. Another scenario is when I want to pass conj, which is fine if I want to create lists, except if I usually want the data structure to be something else. I've never come across a scenario where I didn't want to supply a not-found value, are there any common ones? If others have similar experience perhaps it is a candidate for change. Ideally I'd like to see a not-found parameter added to update- in and an extra arity overload for get-in as outlined below: (defn update-in2 'Updates' a value in a nested associative structure, where ks is a sequence of keys and f is a function that will take the old value and any supplied args and return the new value, and returns a new nested structure. If any levels do not exist, hash-maps will be created. If there is no value to update, default is supplied to f. ([m [k ks] not-found f args] (if ks (assoc m k (apply update-in2 (get m k) ks f args)) (assoc m k (apply f (get m k not-found) args) user= (reduce #(update-in2 %1 [%2] 0 inc) {} [fun counting words fun]) {words 1, counting 1, fun 2} user= (reduce #(update-in2 %1 [(first %2)] [] conj (second %2)) {} [[:a 1] [:a 2] [:b 3]]) {:b [3], :a [1 2]} (defn get-in2 returns the value in a nested associative structure, where ks is a sequence of keys ([m ks] (reduce get m ks)) ([m ks not-found] (if-let [v (reduce get m ks)] v not-found))) user= (get-in2 {:a {:b 1}} [:a :b] 0) 1 user= (get-in2 {:a {:b 1}} [:a :b :c] 0) 0 Changing update-in would be a breaking change unfortunately. To avoid this you could consider checking the argument type for f to be function or value (making an assumption here that you would rarely want a function as the not-found value which is not 100% watertight). Or you could have a similarly named update-in-or function (which is less aesthetically pleasing), or maybe there is another even better way? The get-in function could be enhanced, and would mirror get. As for update-in, a breaking change and type testing is out of the question. However, the general case is one of applying functions to missing/nil arguments that don't expect them, or whose behavior given nil you'd like to change. If it is just a substitution (and it often is, as you desire in update-in), something like this could cover many applying functions, without having to add extra what-to-do-if-nil arguments: (defn fnil Takes a function f, and returns a function that calls f, replacing a nil first argument to f with the supplied value x. Higher arity versions can replace arguments in the second and third positions (y, z). Note that the function f can take any number of arguments, not just the one(s) being nil-patched. ([f x] (fn ([a] (f (if (nil? a) x a))) ([a b] (f (if (nil? a) x a) b)) ([a b c] (f (if (nil? a) x a) b c)) ([a b c ds] (apply f (if (nil? a) x a) b c ds ([f x y] (fn ([a b] (f (if (nil? a) x a) (if (nil? b) y b))) ([a b c] (f (if (nil? a) x a) (if (nil? b) y b) c)) ([a b c ds] (apply f (if (nil? a) x a) (if (nil? b) y b) c ds ([f x y z] (fn ([a b] (f (if (nil? a) x a) (if (nil? b) y b))) ([a b c] (f (if (nil? a) x a) (if (nil? b) y b) (if (nil? c) z c))) ([a b c ds] (apply f (if (nil? a) x a) (if (nil? b) y b) (if (nil? c) z c) ds) usaage: ((fnil + 0) nil 42) - 42 ((fnil conj []) nil 42) - [42] (reduce #(update-in %1 [%2] (fnil inc 0)) {} [fun counting words fun]) -{words 1, counting 1, fun 2} (reduce #(update-in %1 [(first %2)] (fnil conj []) (second %2)) {} [[:a 1] [:a 2] [:b 3]]) - {:b [3], :a [1 2]} fnil seems to me to have greater utility than patching all functions that apply functions with default-supplying arguments. Rich -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: update-in and get-in why no default?
Tim, I like both of these ideas. I agree, get-in2 seems to make sense as a drop in replacement. With update-in2 I prefer a new name, because I do occasionally write code that constructs lists of functions. I'd hate to get a weird bug while doing this. Sean On Dec 10, 7:20 am, Timothy Pratley timothyprat...@gmail.com wrote: Hi, update-in is an especially useful function but I find the update function inevitably requires a check for nil. If I could supply a not- found value then my code would get better golf scores. When I reach for update-in, I usually want to pass it a numerical operator like inc or +, but these don't play nicely with nil. Another scenario is when I want to pass conj, which is fine if I want to create lists, except if I usually want the data structure to be something else. I've never come across a scenario where I didn't want to supply a not-found value, are there any common ones? If others have similar experience perhaps it is a candidate for change. Ideally I'd like to see a not-found parameter added to update- in and an extra arity overload for get-in as outlined below: (defn update-in2 'Updates' a value in a nested associative structure, where ks is a sequence of keys and f is a function that will take the old value and any supplied args and return the new value, and returns a new nested structure. If any levels do not exist, hash-maps will be created. If there is no value to update, default is supplied to f. ([m [k ks] not-found f args] (if ks (assoc m k (apply update-in2 (get m k) ks f args)) (assoc m k (apply f (get m k not-found) args) user= (reduce #(update-in2 %1 [%2] 0 inc) {} [fun counting words fun]) {words 1, counting 1, fun 2} user= (reduce #(update-in2 %1 [(first %2)] [] conj (second %2)) {} [[:a 1] [:a 2] [:b 3]]) {:b [3], :a [1 2]} (defn get-in2 returns the value in a nested associative structure, where ks is a sequence of keys ([m ks] (reduce get m ks)) ([m ks not-found] (if-let [v (reduce get m ks)] v not-found))) user= (get-in2 {:a {:b 1}} [:a :b] 0) 1 user= (get-in2 {:a {:b 1}} [:a :b :c] 0) 0 Changing update-in would be a breaking change unfortunately. To avoid this you could consider checking the argument type for f to be function or value (making an assumption here that you would rarely want a function as the not-found value which is not 100% watertight). Or you could have a similarly named update-in-or function (which is less aesthetically pleasing), or maybe there is another even better way? Thanks for your consideration. Regards, Tim. -- 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: update-in and get-in why no default?
Seconded; I like the intention of both changes, and do something similar in a lot of my code (e.g., parsing functions that take an extra arg if the parse is unsuccessful). Also, testing the type of update-in2's second arg is a bad idea, imo. As for the breaking change of adding another arg to update-in, I can't think of a time when nil was actually the default value I wanted there, though sometimes the function I was using behaved well with nils (e.g., conj). In every other case, I had to explicitly handle nils (e.g., inc). I don't have a lot of production code that would need retrofitting, so I'm inclined to prefer breaking things for the better (at least while things are young). I imagine others might feel differently. On Dec 10, 7:27 am, Sean Devlin francoisdev...@gmail.com wrote: Tim, I like both of these ideas. I agree, get-in2 seems to make sense as a drop in replacement. With update-in2 I prefer a new name, because I do occasionally write code that constructs lists of functions. I'd hate to get a weird bug while doing this. Sean On Dec 10, 7:20 am, Timothy Pratley timothyprat...@gmail.com wrote: Hi, update-in is an especially useful function but I find the update function inevitably requires a check for nil. If I could supply a not- found value then my code would get better golf scores. When I reach for update-in, I usually want to pass it a numerical operator like inc or +, but these don't play nicely with nil. Another scenario is when I want to pass conj, which is fine if I want to create lists, except if I usually want the data structure to be something else. I've never come across a scenario where I didn't want to supply a not-found value, are there any common ones? If others have similar experience perhaps it is a candidate for change. Ideally I'd like to see a not-found parameter added to update- in and an extra arity overload for get-in as outlined below: (defn update-in2 'Updates' a value in a nested associative structure, where ks is a sequence of keys and f is a function that will take the old value and any supplied args and return the new value, and returns a new nested structure. If any levels do not exist, hash-maps will be created. If there is no value to update, default is supplied to f. ([m [k ks] not-found f args] (if ks (assoc m k (apply update-in2 (get m k) ks f args)) (assoc m k (apply f (get m k not-found) args) user= (reduce #(update-in2 %1 [%2] 0 inc) {} [fun counting words fun]) {words 1, counting 1, fun 2} user= (reduce #(update-in2 %1 [(first %2)] [] conj (second %2)) {} [[:a 1] [:a 2] [:b 3]]) {:b [3], :a [1 2]} (defn get-in2 returns the value in a nested associative structure, where ks is a sequence of keys ([m ks] (reduce get m ks)) ([m ks not-found] (if-let [v (reduce get m ks)] v not-found))) user= (get-in2 {:a {:b 1}} [:a :b] 0) 1 user= (get-in2 {:a {:b 1}} [:a :b :c] 0) 0 Changing update-in would be a breaking change unfortunately. To avoid this you could consider checking the argument type for f to be function or value (making an assumption here that you would rarely want a function as the not-found value which is not 100% watertight). Or you could have a similarly named update-in-or function (which is less aesthetically pleasing), or maybe there is another even better way? Thanks for your consideration. Regards, Tim. -- 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: update-proxy doc - what is this ?
msappler wrote: user= (doc update-proxy) It says:the first arg corresponding to this What is meant with this? this means the proxy object itself (like the this keyword in Java). --~--~-~--~~~---~--~~ 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: update/update-in
Because update-in can use any function to do the update. On Wed, Apr 29, 2009 at 6:54 PM, mifrai fraim...@gmail.com wrote: Hi, I was wondering why there was no update to update-in? But there is an assoc to assoc-in and a get to a get-in. - Mike --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: update/update-in
Thanks for the quick reply and I understand that's the functionality of it. But just like get-in is the recursive form of get - I'm just wondering why there's no singular form of update-in. I know it's not much more work to go (update-in map [:single-key] conj 3) - but from experience there tends be really good reasons behind these kinds of decisions and I'm just curious. On Apr 29, 4:05 pm, David Nolen dnolen.li...@gmail.com wrote: Because update-in can use any function to do the update. On Wed, Apr 29, 2009 at 6:54 PM, mifrai fraim...@gmail.com wrote: Hi, I was wondering why there was no update to update-in? But there is an assoc to assoc-in and a get to a get-in. - Mike --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: update/update-in
I see what you mean, does seem like a useful addition: (defn update [m k f args] (assoc m k (apply f (k m) args))) (update {:foo 0} :foo inc) vs. (assoc {:foo 0} :foo (inc (:foo {:foo 0}))) On Wed, Apr 29, 2009 at 7:13 PM, mifrai fraim...@gmail.com wrote: Thanks for the quick reply and I understand that's the functionality of it. But just like get-in is the recursive form of get - I'm just wondering why there's no singular form of update-in. I know it's not much more work to go (update-in map [:single-key] conj 3) - but from experience there tends be really good reasons behind these kinds of decisions and I'm just curious. On Apr 29, 4:05 pm, David Nolen dnolen.li...@gmail.com wrote: Because update-in can use any function to do the update. On Wed, Apr 29, 2009 at 6:54 PM, mifrai fraim...@gmail.com wrote: Hi, I was wondering why there was no update to update-in? But there is an assoc to assoc-in and a get to a get-in. - Mike --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: update-in wildcards?
Well, I expected someone to tell my that was a horrible idea, not to implement it for me. Thanks! One thing that concerns me is that :* could conceivable be used as a key in a hash-map. Perhaps a separate distinct value should be used as a wildcard? Does clojure have a facility for creating a value that will never be considered equal to any other value? --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: update-in wildcards?
Does clojure have a facility for creating a value that will never be considered equal to any other value? Duh, brainfart. Gensym will work nicely, of course. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: update-in wildcards?
(use '[clojure.contrib.generic.functor :only (fmap)]) (defn update-in-wildcard Like update-in, but with :* as a wildcard matcher ([m [k ks] f args] (condp = [(= k :*) (boolean ks)] [true true] (fmap #(apply update-in-wildcard % ks f args) m) [true false] (fmap f m) [false true] (assoc m k (apply update-in-wildcard (get m k) ks f args)) [false false] (assoc m k (apply f (get m k) args) This seems to do what you want. I had a similar situation but hadn't thought of abstracting it out in this way until I read your post. The condp is somewhat ugly, but I didn't want nested if's checking for the same condition. If anyone can think of a nicer way of doing the conditional, let me know. On Apr 10, 11:32 am, Ozzi Lee ozzi...@gmail.com wrote: I have a structure of nested Maps and Vectors as follows: (def document {:sections [{:items [{:quantity 1} {:quantity 2}]} {:items [{:quantity 3} {:quantity 4}]}]}) The document has a vector of sections (one, in this case), each section has a vector of items (two, here). I want to increment the quantity of every item in every section. The cleanest solution I've found this far is as follows: (defn update-item [item] (update-in item [:quantity] inc)) (defn update-section [section] (update-in section [:items] (partial map update-item))) (update-in document [:sections] (partial map update-section)) I'm not concerned about map turning vectors into seqs. If update-in supported some kind of wildcard, I could write this: (update-in document [:sections * :items * :quantity] inc) Where * is a wildcard, meaning any key. Does the wildcard idea have any merit? Is there a better way to go about this? --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: update-values for clojure.contrib.sql
On Jan 11, 2009, at 10:42 AM, Stephen C. Gilardi wrote: I'd like to include something like this in clojure.contrib.sql. That will go smoothest if I can base it directly on what you've written and that's only possible if you send in a contributor agreement. Would you please send one in? Hi budu, While I still encourage you (and everyone who thinks they may want to contribute) to send in a contributor agreement, I came up with an original implementation for this function. Please see my recent update to clojure.contrib.sql. Thanks for bringing the need for it to the fore. --Steve smime.p7s Description: S/MIME cryptographic signature
Re: update-values for clojure.contrib.sql
On Jan 2, 2009, at 2:21 AM, budu wrote: Hi, I was experimenting with clojure-contrib's sql features and found that there wasn't any update-values function. I've written my own and I'm sharing it here: (defn update-values [table where column-names values] Update columns of a table with values. columns-names is a vector of column names (strings or keywords) and the rest of arguments are the values for those columns. (let [columns (map #(str (the-str %) = ?) column-names) template (if (seq column-names) (apply str (interpose , columns)) )] (apply do-prepared (format update %s set %s where %s (the-str table) template where) [values]))) It only send one set of values to do-prepared because of the where clause that would have to change according to each sets. I'm ready for your commentaries and/or suggestions. Hi budu, I'd like to include something like this in clojure.contrib.sql. That will go smoothest if I can base it directly on what you've written and that's only possible if you send in a contributor agreement. Would you please send one in? Please see http://clojure.org/contributing for more info. Thanks, --Steve smime.p7s Description: S/MIME cryptographic signature
Re: update in place for unique references
Most structures of this type would start life as a uniquely-referenced structure (either empty or a copy of an immutable), and have lots of mutations effectively applied to them in a safe environment, until they are ready to be frozen and released to the world as an immutable version of the structure. It is possible to achieve this behavior explicitly if you really wanted to: (defn create-add-2 [] (with-local-vars [x 1] (do (var-set x 1) (var-set x (inc @x)) (let [z @x] (fn [y] (+ y z)) (Some structures would stay uniquely-referenced their whole life - used for performance in some single-threaded encapsulated mutation-based algorithm.) Such an aggressive optimizer might be unhappy with a runtime check and opt for an unsafe mutable: user= (def p (java.awt.Point. 0 0)) #'user/p user= p #Point java.awt.Point[x=0,y=0] user= (.setLocation p 1 2) nil user= p #Point java.awt.Point[x=1,y=2] But might still be unhappy with having to use object calls, at which point I don't think Clojure is the right language. However lucky for them they could still go away and implement an incredibly efficient java api and call it from within Clojure very easily. They would still want to wring the last few drops of performance and write it in C. Actually they could still invoke that code at a high level via JNI but of course would want to keep the calls to a minimum to avoid calling overhead. I should also clarify one point. I am not asking for this language feature so much as asking whether people have thought about it. There may (or may not) be good reasons for not offering such a language feature. I'm just wondering if it has been considered. (And trying to get a feel for the strengths and weaknesses of Clojure - I am very new to it.) I'm just an observer, but if I can't see such a feature appealing to the performance user because it wont ever be as fast as they want it to be. To appeal to the general user transparent implementation, which it can't be if you want to preserve all the features. A subset between these exist, but is quite small and not a far step from moving up or down. * uniquely-referenced (arbitrary mutation changes effectively allowed, but only ever referred to uniquely (runtime enforced)). I think that pretty accurately describes C++, its not fun debugging a runtime enforced coredump full of crap. :) I know that's not what your proposing sorry but I couldn't resist the analogy! I'm not saying its a bad idea, I just don't find it compelling to me personally. Regards, Tim. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: update in place for unique references
On Jan 8, 10:45 pm, Mark P pierh...@gmail.com wrote: I should also clarify one point. I am not asking for this language feature so much as asking whether people have thought about it. There may (or may not) be good reasons for not offering such a language feature. I'm just wondering if it has been considered. (And trying to get a feel for the strengths and weaknesses of Clojure - I am very new to it.) I think the big strength of Clojure is how easy it is to integrate Java code. If you have some performance-critical code you can always drop down to Java. Certainly, performance is important to Clojure, but I think the assumption is that it will never compete with pure Java on speed. -Stuart Sierra --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: update in place for unique references
Hi Tim, I appreciate your comments. It is possible to achieve this behavior explicitly if you really wanted to: (defn create-add-2 [] (with-local-vars [x 1] (do (var-set x 1) (var-set x (inc @x)) (let [z @x] (fn [y] (+ y z)) That's true. Only the (inc @x) isn't update-in-place. Presumably some java something could be used here instead to get true update in place. Such an aggressive optimizer might be unhappy with a runtime check and opt for an unsafe mutable: user= (def p (java.awt.Point. 0 0)) #'user/p user= p #Point java.awt.Point[x=0,y=0] user= (.setLocation p 1 2) nil user= p #Point java.awt.Point[x=1,y=2] But might still be unhappy with having to use object calls, at which point I don't think Clojure is the right language. However lucky for them they could still go away and implement an incredibly efficient java api and call it from within Clojure very easily. They would still want to wring the last few drops of performance and write it in C. Actually they could still invoke that code at a high level via JNI but of course would want to keep the calls to a minimum to avoid calling overhead. What you're saying could well be true. Ie a runtime check of unique reference might not be acceptable where performance is a major concern. But there are two ways around this. 1. Have the ability to turn runtime uniqueness checking on or off. This way code can be tested with the check on, but then run with it off once we are convinced the code is correct (at coder's own risk of course). 2. Take up Mark Fredrickson's suggestion of a code walking analysis macro to prove uniqueness before running the code. That way no runtime check is needed. The fact that java method calls are always expensive is still a problem though. As you say, ultimately a call to a C or C++ routine via JNI might be the only real performance answer. I wish there were a better way. I'm just an observer, but if I can't see such a feature appealing to the performance user because it wont ever be as fast as they want it to be. To appeal to the general user transparent implementation, which it can't be if you want to preserve all the features. A subset between these exist, but is quite small and not a far step from moving up or down. You might be right here, though I still feel uniqueness is a good tool for writing safe and somewhat transparent equivalent to mutation based code. C++ is (unfortunately) my current main language and I use a runtime uniqueness framework to ensure much more reliable mutation based code there. But I think Java's insistence on virtual function calls may make a highly efficient uniqueness approach difficult to achieve in Clojure. * uniquely-referenced (arbitrary mutation changes effectively allowed, but only ever referred to uniquely (runtime enforced)). I think that pretty accurately describes C++, its not fun debugging a runtime enforced coredump full of crap. :) I know that's not what your proposing sorry but I couldn't resist the analogy! I'm not saying its a bad idea, I just don't find it compelling to me personally. But adhering to a uniqueness discipline within C++, together with a functional approach like FC++, does lead to more reliable and more transparent (and somewhat efficient) C++ code. And uniqueness in a lisp language should be much more elegant than my C++ implementation. But I think you and Mark Fredrickson are right to point out that limitations within the JVM itself may make efficiency via uniqueness that is competative with C/C++, impossible to achieve. I'm still hopeful there may be a way, but I can't see it just now. Cheers, Mark P. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: update in place for unique references
Clean doesn't allow mutation, so it has to do tricks like this or else you'd never be able to write a useful program. Clojure gives you a set of data structures that do very fast non-destructive update. Clojure also gives you tools like atoms, refs, and full access to Java's mutable behavior to specify update in place if that's what you want. Since Clojure gives you a full range of immutable/mutable update choices, I fail to see how Clean's uniqueness typing is at all relevant to Clojure. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: update in place for unique references
Clojure gives you a set of data structures that do very fast non-destructive update. Clojure also gives you tools like atoms, refs, and full access to Java's mutable behavior to specify update in place if that's what you want. Yes, I can see that one could implement this oneself via Java. But it wouldn't be an official part of the language. What I am wondering is whether update-in-place for unique references could lead to greater efficiencies (in some cases) than Clojure's current non-destructive updates. And without harming referential transparency or concurrency benefits. Fundamentally I would have thought update-in-place beats update-by-replace in both execution speed and in memory usage. The only problem with it is that it usually breaks referential transparency as well as causing problems with concurrency. But in the case of a unique reference that is about to disappear, update-in-place does no harm! The memory is about to become obsolete soon anyway so why not commandeer it? And if commandeered, why not update it in place - as nothing else is looking at it. I realize there are issues, but maybe these could be solved and it could lead to even more efficient (both time and memory) code from Clojure, while not sacrificing its strengths. I'm just wondering whether anyone has thought about it. And if so, whether it has potential, or whether there are good reasons why it is not practical. Cheers, Mark P. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: update in place for unique references
Hi Mark F, Thanks for your responses. 1. Data: Is this really a problem that is slowing down Clojure programs in practice? Can you provide some data to that effect? I would suggest writing a couple of Java benchmarks - one that updates a simple structure in place and one that only creates new data. Time them. Write more benchmarks, but this time do it in Clojure (though perhaps with some straight Java calls to make the updates). Are there differences in the Java versions from the Clojure versions? Are there differences in the update vs new data versions? Writing some test code is not a bad idea, but from what I heard Rich Hickey say in his online talks, probably unnecessary to establish that using Clojure built-in data structures involves a performance hit (in the single-thread case anyway). I got the impression that Clojure structures are somewhere in the range of 1.5 to 4 times worse than mutation based structures. Of course, this performance is quite an achievement, given the advantages of Clojure's approach. But for applications which are performance critical, I am wondering whether a uniqueness-based update-in-place would offer a complementary well performing alternative. 2. Take a page from the Scheme playbook. Don't ask the language to implement this feature, ask for the minimal set of tools that you need to implement it. I would think a code walking escape analysis macro could be very useful. Instead of run-time reference counting, the macro could find data that is guaranteed not to escape its scope via a closure (e.g. let bound locals that are not used in any (fn [] ...)s ). What would you need access to? Additional JVM byte-code instructions? Post-compile processing by user code? Update in place methods for the normally immutable types? I don't know exactly what you'd need, but ask for that before asking for a much bigger feature. The escape analysis macro sounds interesting. But an initial approach might be, for each of these new data structures (mutation based under the hood) to have two versions of each structure: * immutable (ie no more changes will ever occur - if you want a modification you will have to make a full copy); and * uniquely-referenced (arbitrary mutation changes effectively allowed, but only ever referred to uniquely (runtime enforced)). Most structures of this type would start life as a uniquely-referenced structure (either empty or a copy of an immutable), and have lots of mutations effectively applied to them in a safe environment, until they are ready to be frozen and released to the world as an immutable version of the structure. (Some structures would stay uniquely-referenced their whole life - used for performance in some single-threaded encapsulated mutation-based algorithm.) I should also clarify one point. I am not asking for this language feature so much as asking whether people have thought about it. There may (or may not) be good reasons for not offering such a language feature. I'm just wondering if it has been considered. (And trying to get a feel for the strengths and weaknesses of Clojure - I am very new to it.) 3. Remember that Clojure relies on the JVM for its allocation and GC. Clojure is not issuing malloc and free calls. The JVM will not make it easy to repurpose the storage of one object with a new object, without going through a method. Maybe the way to handle this (at least initially) would be to only provide uniqueness interfaces to some of Java's main structures. Perhaps not as general as would be ideal, but would easily allow repurposing via a method. Thanks again for your input. Cheers, Mark P. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: update-values for clojure.contrib.sql
Well, one thing that sticks out (particularly to me) is the fact that you forgot to put your doc-string *before* your [params*] list :) (ahem) On Fri, Jan 2, 2009 at 8:21 AM, budu nbudu...@gmail.com wrote: Hi, I was experimenting with clojure-contrib's sql features and found that there wasn't any update-values function. I've written my own and I'm sharing it here: (defn update-values [table where column-names values] Update columns of a table with values. columns-names is a vector of column names (strings or keywords) and the rest of arguments are the values for those columns. (let [columns (map #(str (the-str %) = ?) column-names) template (if (seq column-names) (apply str (interpose , columns)) )] (apply do-prepared (format update %s set %s where %s (the-str table) template where) [values]))) It only send one set of values to do-prepared because of the where clause that would have to change according to each sets. I'm ready for your commentaries and/or suggestions. -- Venlig hilsen / Kind regards, Christian Vest Hansen. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: update-values for clojure.contrib.sql
D'oh! I have a hard time kicking out that old habit. And changing code after testing it too! On Jan 2, 4:21 am, Christian Vest Hansen karmazi...@gmail.com wrote: Well, one thing that sticks out (particularly to me) is the fact that you forgot to put your doc-string *before* your [params*] list :) (ahem) On Fri, Jan 2, 2009 at 8:21 AM, budu nbudu...@gmail.com wrote: Hi, I was experimenting with clojure-contrib's sql features and found that there wasn't any update-values function. I've written my own and I'm sharing it here: (defn update-values [table where column-names values] Update columns of a table with values. columns-names is a vector of column names (strings or keywords) and the rest of arguments are the values for those columns. (let [columns (map #(str (the-str %) = ?) column-names) template (if (seq column-names) (apply str (interpose , columns)) )] (apply do-prepared (format update %s set %s where %s (the-str table) template where) [values]))) It only send one set of values to do-prepared because of the where clause that would have to change according to each sets. I'm ready for your commentaries and/or suggestions. -- Venlig hilsen / Kind regards, Christian Vest Hansen. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: update a ref struct
I know you are asking about refs, but you might want to think about using reduce to walk the line-seq. the nature of reduce lets you have access to the line-seq, two lines at a time no need for a ref. On Mon, Nov 24, 2008 at 2:17 PM, Brian Doyle [EMAIL PROTECTED] wrote: I am parsing a file and to compare the current line with the previous line of the file. I am using line-seq to go thru the file and I thought I would create a ref to store the previous line. When I want to update the previous line value I can't seem to do it. I've never used refs before so I'm sure I'm doing something very stupid. (defstruct line :lat :lon :name) (defn convert [file] (let [prev-line (ref (struct line))] (with-open [r (reader file)] (doseq [l (line-seq r)] (let [ps (split #, l) c-line (struct line (ps 0) (ps 1) (ps 2))] (if (not= c-line @pre-line) (do ; do stuff here then update pre-line (dosync ref-set pre-line (apply struct line (vals c-line))) (println @pre-line ; this prints out all nils doesn't seem to work Sorry if this email is not formatted correctly. Something is wrong with my browser currently typing in a textarea. Thanks. -- The Mafia way is that we pursue larger goals under the guise of personal relationships. Fisheye --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: update a ref struct
Thanks Kevin, I will try using reduce instead. I would like to know what I'm doing wrong with updating the ref for future reference. Thanks. On Mon, Nov 24, 2008 at 3:23 PM, Kevin Downey [EMAIL PROTECTED] wrote: I know you are asking about refs, but you might want to think about using reduce to walk the line-seq. the nature of reduce lets you have access to the line-seq, two lines at a time no need for a ref. On Mon, Nov 24, 2008 at 2:17 PM, Brian Doyle [EMAIL PROTECTED] wrote: I am parsing a file and to compare the current line with the previous line of the file. I am using line-seq to go thru the file and I thought I would create a ref to store the previous line. When I want to update the previous line value I can't seem to do it. I've never used refs before so I'm sure I'm doing something very stupid. (defstruct line :lat :lon :name) (defn convert [file] (let [prev-line (ref (struct line))] (with-open [r (reader file)] (doseq [l (line-seq r)] (let [ps (split #, l) c-line (struct line (ps 0) (ps 1) (ps 2))] (if (not= c-line @pre-line) (do ; do stuff here then update pre-line (dosync ref-set pre-line (apply struct line (vals c-line))) (println @pre-line ; this prints out all nils doesn't seem to work Sorry if this email is not formatted correctly. Something is wrong with my browser currently typing in a textarea. Thanks. -- The Mafia way is that we pursue larger goals under the guise of personal relationships. Fisheye --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: update a ref struct
ref-set needs its one set of parens, and the last thing in the ref-set call needs to be a function either (fn [x] ...) or a symbol for a var that holds a function On Mon, Nov 24, 2008 at 2:30 PM, Brian Doyle [EMAIL PROTECTED] wrote: Thanks Kevin, I will try using reduce instead. I would like to know what I'm doing wrong with updating the ref for future reference. Thanks. On Mon, Nov 24, 2008 at 3:23 PM, Kevin Downey [EMAIL PROTECTED] wrote: I know you are asking about refs, but you might want to think about using reduce to walk the line-seq. the nature of reduce lets you have access to the line-seq, two lines at a time no need for a ref. On Mon, Nov 24, 2008 at 2:17 PM, Brian Doyle [EMAIL PROTECTED] wrote: I am parsing a file and to compare the current line with the previous line of the file. I am using line-seq to go thru the file and I thought I would create a ref to store the previous line. When I want to update the previous line value I can't seem to do it. I've never used refs before so I'm sure I'm doing something very stupid. (defstruct line :lat :lon :name) (defn convert [file] (let [prev-line (ref (struct line))] (with-open [r (reader file)] (doseq [l (line-seq r)] (let [ps (split #, l) c-line (struct line (ps 0) (ps 1) (ps 2))] (if (not= c-line @pre-line) (do ; do stuff here then update pre-line (dosync ref-set pre-line (apply struct line (vals c-line))) (println @pre-line ; this prints out all nils doesn't seem to work Sorry if this email is not formatted correctly. Something is wrong with my browser currently typing in a textarea. Thanks. -- The Mafia way is that we pursue larger goals under the guise of personal relationships. Fisheye -- The Mafia way is that we pursue larger goals under the guise of personal relationships. Fisheye --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: update a ref struct
On Mon, Nov 24, 2008 at 2:34 PM, Kevin Downey [EMAIL PROTECTED] wrote: ref-set needs its one set of parens, and the last thing in the ref-set call needs to be a function either (fn [x] ...) or a symbol for a var that holds a function I made a mistake here. I was thinking of alter, not ref-set. On Mon, Nov 24, 2008 at 2:30 PM, Brian Doyle [EMAIL PROTECTED] wrote: Thanks Kevin, I will try using reduce instead. I would like to know what I'm doing wrong with updating the ref for future reference. Thanks. On Mon, Nov 24, 2008 at 3:23 PM, Kevin Downey [EMAIL PROTECTED] wrote: I know you are asking about refs, but you might want to think about using reduce to walk the line-seq. the nature of reduce lets you have access to the line-seq, two lines at a time no need for a ref. On Mon, Nov 24, 2008 at 2:17 PM, Brian Doyle [EMAIL PROTECTED] wrote: I am parsing a file and to compare the current line with the previous line of the file. I am using line-seq to go thru the file and I thought I would create a ref to store the previous line. When I want to update the previous line value I can't seem to do it. I've never used refs before so I'm sure I'm doing something very stupid. (defstruct line :lat :lon :name) (defn convert [file] (let [prev-line (ref (struct line))] (with-open [r (reader file)] (doseq [l (line-seq r)] (let [ps (split #, l) c-line (struct line (ps 0) (ps 1) (ps 2))] (if (not= c-line @pre-line) (do ; do stuff here then update pre-line (dosync ref-set pre-line (apply struct line (vals c-line))) (println @pre-line ; this prints out all nils doesn't seem to work Sorry if this email is not formatted correctly. Something is wrong with my browser currently typing in a textarea. Thanks. -- The Mafia way is that we pursue larger goals under the guise of personal relationships. Fisheye -- The Mafia way is that we pursue larger goals under the guise of personal relationships. Fisheye -- The Mafia way is that we pursue larger goals under the guise of personal relationships. Fisheye --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---