Re: mapmap?
On Thu, Dec 9, 2010 at 8:43 PM, Steven E. Harris s...@panix.com wrote: Ken Wesson kwess...@gmail.com writes: and to encapsulate as a function: (defn fmap [f m] (into {} (for [[k v] m] [k (f v)]))) Here, fmap is a poor choice of name, if it's meant to be a reference to Haskell's function of the same name. It's not obvious to me that mapping a function over a map should just apply the function to the values. Yes, applying the function to the keys instead could yield duplicates, but just because one choice of behavior isn't promising doesn't make the other choice obviously valid. If you called your function, say, fmap-values I would not have complained. Please direct all complaints regarding calling it fmap to Sunil. He was the first to suggest that name in this thread, not I. (aanlkti=-m4c2wwnhjta=jqfsfpzhnofed-hfzs-yb...@mail.gmail.com) I merely copied him. :) -- You 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: mapmap?
While on the topic, I'd like to raise a naming issue. The 'mapmap' function seems to be a recurring theme (see, e.g., http://tech.puredanger.com/2010/09/24/meet-my-little-friend-mapmap/) and many Clojure projects include one -- Incanter comes to mind. My project used to, too. But we found out that the name mapmap has its deficiencies. First, it conflates the two senses of the word map (1. noun -- an object implementing IPersistentMap; 2. verb -- to apply a function to each element of a collection, producing a new one) by putting them right next to each other. This impairs code readability: I once found myself typing (mapmap #(map ... ) ...) -- it's unobvious at first sight which map is used in which sense. Second, all these implementations of mapmap floating around are mutually incompatible, which partly stems from the fact that it is unclear from the name what the argument of mapmap should be. Should it be a value-value function? Or should it take two arguments, a key and a value? Or should it take a [key value] pair? Actually, each one of these flavors is useful on different occasions. So to differentiate between them, we've now dropped mapmap and use transform-v and transform-kv instead. Here they are, with docstrings: (defn transform-kv Transforms each entry in a map with f and returns the resulting map. f should take and return a key/value pair. Similar to clojure.contrib.generic.functor/fmap, but can take keys into account. Works on any seq of pairs (not necessarily maps), always returning maps. [f x] (into {} (map (fn [[k v]] (f k v)) x))) (defn transform-v Like transform-kv, but takes a value-value function, leaving keys intact. [f x] (into {} (map (fn [[k v]] [k (f v)]) x))) -- You 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: mapmap?
Just checking performance versus the version i have been using i noticed quite a difference For 10 runs over a small 10 key/value map (defn fmap [keyf valf m] (into {} (for [[k v] m] [(keyf k) (valf v)]))) 550ms (defn fmap2 [keyf valf m] (- (fn [inputmap [k v]] (assoc inputmap (name k) (inc v))) (reduce {} inputmap))) 250ms On Dec 7, 7:50 am, Alex Baranosky alexander.barano...@gmail.com wrote: Ahh apply does it again! I saw how the code be simplified, but just tonight learned how apply can be used in situations like 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: mapmap?
On Tue, Dec 7, 2010 at 3:31 AM, Tobias Raeder tobias.rae...@googlemail.com wrote: Just checking performance versus the version i have been using i noticed quite a difference For 10 runs over a small 10 key/value map (defn fmap [keyf valf m] (into {} (for [[k v] m] [(keyf k) (valf v)]))) 550ms (defn fmap2 [keyf valf m] (- (fn [inputmap [k v]] (assoc inputmap (name k) (inc v))) (reduce {} inputmap))) 250ms Does the speed difference persist if you fix the bugs in the second version? :) -- You 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: mapmap?
This is a solved problem. The trick is to use a higher-higher order function... http://fulldisclojure.blogspot.com/2010/01/12-fn-proposal-same-multisame.html On Dec 7, 7:38 am, Daniel Janus nath...@gmail.com wrote: While on the topic, I'd like to raise a naming issue. The 'mapmap' function seems to be a recurring theme (see, e.g.,http://tech.puredanger.com/2010/09/24/meet-my-little-friend-mapmap/) and many Clojure projects include one -- Incanter comes to mind. My project used to, too. But we found out that the name mapmap has its deficiencies. First, it conflates the two senses of the word map (1. noun -- an object implementing IPersistentMap; 2. verb -- to apply a function to each element of a collection, producing a new one) by putting them right next to each other. This impairs code readability: I once found myself typing (mapmap #(map ... ) ...) -- it's unobvious at first sight which map is used in which sense. Second, all these implementations of mapmap floating around are mutually incompatible, which partly stems from the fact that it is unclear from the name what the argument of mapmap should be. Should it be a value-value function? Or should it take two arguments, a key and a value? Or should it take a [key value] pair? Actually, each one of these flavors is useful on different occasions. So to differentiate between them, we've now dropped mapmap and use transform-v and transform-kv instead. Here they are, with docstrings: (defn transform-kv Transforms each entry in a map with f and returns the resulting map. f should take and return a key/value pair. Similar to clojure.contrib.generic.functor/fmap, but can take keys into account. Works on any seq of pairs (not necessarily maps), always returning maps. [f x] (into {} (map (fn [[k v]] (f k v)) x))) (defn transform-v Like transform-kv, but takes a value-value function, leaving keys intact. [f x] (into {} (map (fn [[k v]] [k (f v)]) x))) -- You 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: mapmap?
If you use (empty m) rather than {} it will also work for other types. On Dec 7, 5:45 am, Ken Wesson kwess...@gmail.com wrote: This is also very easy to implement: (into {} (for [[k v] the-map] [k (f v)])) e.g. user= (into {} (for [[k v] {:a 3 :b 7}] [k (inc v)])) {:a 4, :b 8} user= and to encapsulate as a function: (defn fmap [f m] (into {} (for [[k v] m] [k (f v)]))) -- You 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: mapmap?
On Dec 7, 5:50 am, Sean Devlin francoisdev...@gmail.com wrote: This is a solved problem. The trick is to use a higher-higher order function... http://fulldisclojure.blogspot.com/2010/01/12-fn-proposal-same-multis... Why not call it unseq? -- You 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
mapmap?
Do the standard libraries contain a function to map a function over a map? (mapmap inc {:a 1 :b 2}) = (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: mapmap?
Oops. I meant: (mapmap inc {:a 1 :b 2}) = { :a 2 :b 3) Sorry about that. Alex -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: mapmap?
Hi Alex, (clojure.contrib.generic.functor/fmap inc {:a 1 :b 2}) = {:a 2 :b 3} The above is probably what you want. HTH Sunil. On Tue, Dec 7, 2010 at 9:26 AM, Alex Baranosky alexander.barano...@gmail.com wrote: Oops. I meant: (mapmap inc {:a 1 :b 2}) = { :a 2 :b 3) Sorry about that. Alex -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.comclojure%2bunsubscr...@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: mapmap?
Thanks Sunil. On Mon, Dec 6, 2010 at 11:00 PM, Sunil S Nandihalli sunil.nandiha...@gmail.com wrote: Hi Alex, (clojure.contrib.generic.functor/fmap inc {:a 1 :b 2}) = {:a 2 :b 3} The above is probably what you want. HTH Sunil. On Tue, Dec 7, 2010 at 9:26 AM, Alex Baranosky alexander.barano...@gmail.com wrote: Oops. I meant: (mapmap inc {:a 1 :b 2}) = { :a 2 :b 3) Sorry about that. Alex -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.comclojure%2bunsubscr...@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.comclojure%2bunsubscr...@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: mapmap?
This is also very easy to implement: (into {} (for [[k v] the-map] [k (f v)])) e.g. user= (into {} (for [[k v] {:a 3 :b 7}] [k (inc v)])) {:a 4, :b 8} user= and to encapsulate as a function: (defn fmap [f m] (into {} (for [[k v] m] [k (f v)]))) -- You 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: mapmap?
I think it will be fun to come up with a solution that will work with n maps: (defn multi-fmap [f maps] ...) i.e. (multi-fmap #(+ %1 %1 %2 ) {:a 1 :b 2} {:a 3 :b 4}) = {:a 5 :b 8} (multi-fmap #(+ %1 %2 %3 ) {:a 1 :b 2} {:a 3 :b 4} {:a 5 :b 6}) = {:a 9 :b 12} -- You 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: mapmap?
On Tue, Dec 7, 2010 at 12:04 AM, Alex Baranosky alexander.barano...@gmail.com wrote: I think it will be fun to come up with a solution that will work with n maps: (defn multi-fmap [f maps] ...) i.e. (multi-fmap #(+ %1 %1 %2 ) {:a 1 :b 2} {:a 3 :b 4}) = {:a 5 :b 8} (multi-fmap #(+ %1 %2 %3 ) {:a 1 :b 2} {:a 3 :b 4} {:a 5 :b 6}) = {:a 9 :b 12} (defn multi-fmap [f maps] (into {} (for [k (keys (first maps))] [k (apply f (map #(get % k) maps))]))) works for your two test-cases. It assumes that the keys you're interested in are exactly the keys of the first map; if any map is missing a key the function will get a nil argument in the position corresponding to that map when computing the result's value for that key. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: mapmap
I've been using a number of similar functions in my own coding. This was my approach. (defn seq2map Constructs a map from a sequence by applying keyvalfn to each element of the sequence. keyvalfn should return a pair [key val] to be added to the map for each input sequence element. [aseq keyvalfn] (loop [aseq aseq amap {}] (if (empty? aseq) amap (let [[key val] (keyvalfn (first aseq))] (recur (rest aseq) (assoc amap key val)) (defn seq2redundant-map Constructs a map from a sequence by applying keyvalfn to each element of the sequence. keyvalfn should return a pair [key val] to be added to the map for each input sequence element. If key is already in the map, its current value will be combined with the new val using (mergefn curval val). [aseq keyvalfn mergefn] (loop [aseq aseq amap {}] (if (empty? aseq) amap (let [[key val] (keyvalfn (first aseq))] (recur (rest aseq) (update-in amap [key] mergefn val)) (defn maphash Creates a new map by applying keyfn to every key of in-map and valfn to every corresponding val. [keyfn valfn in-map] (seq2map (seq in-map) (fn [[key val]] [(keyfn key) (valfn val)]))) ~Gary -- You 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: mapmap
On 18 Dec 2009, at 15:03, Sean Devlin wrote: The last entry is the most relevant to a map-utils library. Check out the visitor stuff: http://groups.google.com/group/clojure-dev/msg/6c1bbce17cafdf52 The idea is to take your generic functor application idea and put it on steroids. I'm going to be writing about this a lot more once 1.1 is out the door. A whole lot. The functor abstraction is certainly not my idea, I just wrote the Clojure implementation, which is almost trivial. Functors have their origin in mathematics (category theory, see http://en.wikipedia.org/wiki/Functor) , although the link to functors in functional programming is not as evident or straightforward as some make it seem to be. Functors are a well-established and much-used abstraction in Haskell and part of its standard library. Haskell purists would probably complain that my Clojure version has nothing to do with the real thing because Clojure doesn't have static typing, but the practical utility of functors is the same in Clojure as it is in Haskell. Your visitor approach looks a bit like the data structure walkers in clojure.walk. Could both be unified into a single concept and library? Konrad. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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: mapmap
On 17 Dec 2009, at 20:26, Sean Devlin wrote: Konrad, I am working on a different proposal on the dev list: http://groups.google.com/group/clojure-dev/browse_thread/thread/9a518c853bfbba8b# This is a more in depth version of these functions for maps. I'd love to have you contribute to the discussion here. I vaguely remember that discussion, but at the time I was too busy with other things to look at it. Now I did, but I don't think I have much to contribute. The way maps are used in the code examples of that thread just doesn't occur in the applications I have for Clojure. Just one general remark: I don't think it is a good idea to structure libraries around Clojure datatypes, as it is implied by a library name such as map-utils. Clojure's built-in data types can implement many different data abstractions, and I'd prefer to structure libraries around those abstractions rather than around the concrete representations. BTW, this is also the reason why I like multimethods and protocols, as very often an abstraction can have multiple practically useful implementations. Let's take maps as an example. A map can represent a table, or a small database. A map can also represent a function defined on a finite set of arguments. The operations used on maps are likely to be different for those two use-cases, and it is even quite possible that the same operation should have a different name for each application. So I'd rather see a library table-utils and another library discrete-function- utils. The latter should also provide implementations of its functions for vectors, which can represent functions defined on a finite range of integers. The discussion in the thread you cite turns mostly around using maps to represent tables. As I said, I don't have much use for this, so my only recommendation is to call it table-utils rather than map-utils and to envisage altenative representations, such as on-disk databases. Konrad. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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: mapmap
Konrad, Yeah, there are discussions of two libs there. The idea is that most of the fn in this thread will be used for table-utils. The last entry is the most relevant to a map-utils library. Check out the visitor stuff: http://groups.google.com/group/clojure-dev/msg/6c1bbce17cafdf52 The idea is to take your generic functor application idea and put it on steroids. I'm going to be writing about this a lot more once 1.1 is out the door. A whole lot. Sean On Dec 18, 3:50 am, Konrad Hinsen konrad.hin...@fastmail.net wrote: On 17 Dec 2009, at 20:26, Sean Devlin wrote: Konrad, I am working on a different proposal on the dev list: http://groups.google.com/group/clojure-dev/browse_thread/thread/9a518... This is a more in depth version of these functions for maps. I'd love to have you contribute to the discussion here. I vaguely remember that discussion, but at the time I was too busy with other things to look at it. Now I did, but I don't think I have much to contribute. The way maps are used in the code examples of that thread just doesn't occur in the applications I have for Clojure. Just one general remark: I don't think it is a good idea to structure libraries around Clojure datatypes, as it is implied by a library name such as map-utils. Clojure's built-in data types can implement many different data abstractions, and I'd prefer to structure libraries around those abstractions rather than around the concrete representations. BTW, this is also the reason why I like multimethods and protocols, as very often an abstraction can have multiple practically useful implementations. Let's take maps as an example. A map can represent a table, or a small database. A map can also represent a function defined on a finite set of arguments. The operations used on maps are likely to be different for those two use-cases, and it is even quite possible that the same operation should have a different name for each application. So I'd rather see a library table-utils and another library discrete-function- utils. The latter should also provide implementations of its functions for vectors, which can represent functions defined on a finite range of integers. The discussion in the thread you cite turns mostly around using maps to represent tables. As I said, I don't have much use for this, so my only recommendation is to call it table-utils rather than map-utils and to envisage altenative representations, such as on-disk databases. Konrad. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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
mapmap
I was just wondering how a #'map for maps could be done most succinctly. Came up with this: (defn mapmap Map values of map m using function f. [f m] (reduce (fn [m [k v]] (assoc m k (f v))) {} m)) But there is probably a more straightforward way. What do you use? Florian -- Florian Ebeling florian.ebel...@gmail.com -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: mapmap
1. I'd call it map-vals (as opposed to map-keys) 2. Slight change in the body (defn map-vals [f coll] (into {} (map (juxt key (comp f val)) coll)) There is talk of getting something like this into contrib. Stay tuned :) Sean On Dec 17, 9:37 am, C. Florian Ebeling florian.ebel...@gmail.com wrote: I was just wondering how a #'map for maps could be done most succinctly. Came up with this: (defn mapmap Map values of map m using function f. [f m] (reduce (fn [m [k v]] (assoc m k (f v))) {} m)) But there is probably a more straightforward way. What do you use? Florian -- Florian Ebeling florian.ebel...@gmail.com -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: mapmap
AFAIK, such a function is still not in clojure core because it's not clear to Rich whether f should have one argument (the value), or 2 arguments (key + value). Your version seems good, you can maybe improve it a little bit by using transients (not tested): (persistent! (reduce (fn [m [k v]] (assoc! m k (f v))) (transient {}) m)) HTH, -- Laurent 2009/12/17 C. Florian Ebeling florian.ebel...@gmail.com I was just wondering how a #'map for maps could be done most succinctly. Came up with this: (defn mapmap Map values of map m using function f. [f m] (reduce (fn [m [k v]] (assoc m k (f v))) {} m)) But there is probably a more straightforward way. What do you use? Florian -- Florian Ebeling florian.ebel...@gmail.com -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.comclojure%2bunsubscr...@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: mapmap
AFAIK, such a function is still not in clojure core because it's not clear to Rich whether f should have one argument (the value), or 2 arguments (key + value). That is a good question. But I thought if the key makes a difference, then one could use standard map and rely on map's collection nature, using into {} afterwards. My reasoning was that map does not care about the index of an element of collection either. So the key should not count in. But there are valid reasons for the opposite decision as well, I guess. Florian -- Florian Ebeling florian.ebel...@gmail.com -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: mapmap
On Dec 17, 9:37 am, C. Florian Ebeling florian.ebel...@gmail.com wrote: (defn mapmap Map values of map m using function f. [f m] (reduce (fn [m [k v]] (assoc m k (f v))) {} m)) But there is probably a more straightforward way. What do you use? I do that exactly, but I never felt the need to define a new function for it. The advantage of reduce is that you can change the keys too, and pick which keys end up in the final map. -SS -- You 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: mapmap
Hi Laurent, If you want to use transients, since the keyset is unchanged, it should perform slightly better when using (transient m) instead of (transient {}) as the seed to reduce. Christophe On Dec 17, 3:46 pm, Laurent PETIT laurent.pe...@gmail.com wrote: AFAIK, such a function is still not in clojure core because it's not clear to Rich whether f should have one argument (the value), or 2 arguments (key + value). Your version seems good, you can maybe improve it a little bit by using transients (not tested): (persistent! (reduce (fn [m [k v]] (assoc! m k (f v))) (transient {}) m)) HTH, -- Laurent 2009/12/17 C. Florian Ebeling florian.ebel...@gmail.com I was just wondering how a #'map for maps could be done most succinctly. Came up with this: (defn mapmap Map values of map m using function f. [f m] (reduce (fn [m [k v]] (assoc m k (f v))) {} m)) But there is probably a more straightforward way. What do you use? Florian -- Florian Ebeling florian.ebel...@gmail.com -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.comclojure%2bunsubscr...@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: mapmap
On 17 Dec 2009, at 15:44, Sean Devlin wrote: 1. I'd call it map-vals (as opposed to map-keys) 2. Slight change in the body (defn map-vals [f coll] (into {} (map (juxt key (comp f val)) coll)) There is talk of getting something like this into contrib. Stay tuned :) There's already clojure.contrib.generic.functor/fmap, which is a multimethod whose implementation for maps does just that. Here's the code: (defmethod fmap clojure.lang.IPersistentMap [f m] (into (empty m) (for [[k v] m] [k (f v)]))) Konrad. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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: mapmap
On Thu, Dec 17, 2009 at 12:16 PM, Konrad Hinsen konrad.hin...@fastmail.net wrote: On 17 Dec 2009, at 15:44, Sean Devlin wrote: (defn map-vals [f coll] (into {} (map (juxt key (comp f val)) coll)) vs: (defmethod fmap clojure.lang.IPersistentMap [f m] (into (empty m) (for [[k v] m] [k (f v)]))) Are there any guidelines as to when it's appropriate to use the map function vs a list comprehension? e -- You 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: mapmap
Konrad, I am working on a different proposal on the dev list: http://groups.google.com/group/clojure-dev/browse_thread/thread/9a518c853bfbba8b# This is a more in depth version of these functions for maps. I'd love to have you contribute to the discussion here. Sean On Dec 17, 12:16 pm, Konrad Hinsen konrad.hin...@fastmail.net wrote: On 17 Dec 2009, at 15:44, Sean Devlin wrote: 1. I'd call it map-vals (as opposed to map-keys) 2. Slight change in the body (defn map-vals [f coll] (into {} (map (juxt key (comp f val)) coll)) There is talk of getting something like this into contrib. Stay tuned :) There's already clojure.contrib.generic.functor/fmap, which is a multimethod whose implementation for maps does just that. Here's the code: (defmethod fmap clojure.lang.IPersistentMap [f m] (into (empty m) (for [[k v] m] [k (f v)]))) Konrad. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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: mapmap
Depends if you need a closure. There are times I do 2D mappings, and I have to write something like (map (partail map #(do-work %)) coll). Or I have to compose my mapping operations. for is awesome when you need some of the other built-ins, like :while Sean On Dec 17, 12:39 pm, Erik Price erikpr...@gmail.com wrote: On Thu, Dec 17, 2009 at 12:16 PM, Konrad Hinsen konrad.hin...@fastmail.net wrote: On 17 Dec 2009, at 15:44, Sean Devlin wrote: (defn map-vals [f coll] (into {} (map (juxt key (comp f val)) coll)) vs: (defmethod fmap clojure.lang.IPersistentMap [f m] (into (empty m) (for [[k v] m] [k (f v)]))) Are there any guidelines as to when it's appropriate to use the map function vs a list comprehension? e -- You 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: mapmap
Good to know, thank you ! 2009/12/17 Christophe Grand christo...@cgrand.net Hi Laurent, If you want to use transients, since the keyset is unchanged, it should perform slightly better when using (transient m) instead of (transient {}) as the seed to reduce. Christophe On Dec 17, 3:46 pm, Laurent PETIT laurent.pe...@gmail.com wrote: AFAIK, such a function is still not in clojure core because it's not clear to Rich whether f should have one argument (the value), or 2 arguments (key + value). Your version seems good, you can maybe improve it a little bit by using transients (not tested): (persistent! (reduce (fn [m [k v]] (assoc! m k (f v))) (transient {}) m)) HTH, -- Laurent 2009/12/17 C. Florian Ebeling florian.ebel...@gmail.com I was just wondering how a #'map for maps could be done most succinctly. Came up with this: (defn mapmap Map values of map m using function f. [f m] (reduce (fn [m [k v]] (assoc m k (f v))) {} m)) But there is probably a more straightforward way. What do you use? Florian -- Florian Ebeling florian.ebel...@gmail.com -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.comclojure%2bunsubscr...@googlegroups.com clojure%2bunsubscr...@googlegroups.comclojure%252bunsubscr...@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.comclojure%2bunsubscr...@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: mapmap
Erik, My experience is that you should only use filter/map if you either have a pre-existing function or you want to use a _very_ short closure (using #()). For any other case the code becomes unmanageable and then I feel that using for is the wiser choice. I hope that they are just as efficient, but I haven't really tested it. I feel like even if it isn't right now they can be brought up to the same speed. -- http://wave.theWE.net http://twitter.com/theWE_ On Thu, Dec 17, 2009 at 7:39 PM, Erik Price erikpr...@gmail.com wrote: On Thu, Dec 17, 2009 at 12:16 PM, Konrad Hinsen konrad.hin...@fastmail.net wrote: On 17 Dec 2009, at 15:44, Sean Devlin wrote: (defn map-vals [f coll] (into {} (map (juxt key (comp f val)) coll)) vs: (defmethod fmap clojure.lang.IPersistentMap [f m] (into (empty m) (for [[k v] m] [k (f v)]))) Are there any guidelines as to when it's appropriate to use the map function vs a list comprehension? e -- You 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.comclojure%2bunsubscr...@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: mapmap
Avital Oliver avi...@thewe.net writes: My experience is that you should only use filter/map if you either have a pre-existing function or you want to use a _very_ short closure (using #()). For any other case the code becomes unmanageable and then I feel that using for is the wiser choice. I agree, but then again I've been criticized for writing too bulky functions so perhaps it's better to extract the conditions and the body as separate functions where possible. I guess the other advantage of map is that is more easily replaced with 'pmap'. I hope that they are just as efficient, but I haven't really tested it. I feel like even if it isn't right now they can be brought up to the same speed. In theory 'for' is slightly more efficient than a filter/map combo as it avoids one lazy sequence, but for almost all purposes the difference is negligible and not worth bothering over. -- You 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