Re: mapmap?

2010-12-09 Thread Ken Wesson
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?

2010-12-07 Thread Daniel Janus
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?

2010-12-07 Thread Tobias Raeder
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?

2010-12-07 Thread Ken Wesson
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?

2010-12-07 Thread Sean Devlin
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?

2010-12-07 Thread pepijn (aka fliebel)
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?

2010-12-07 Thread javajosh


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?

2010-12-06 Thread Alex Baranosky
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?

2010-12-06 Thread Alex Baranosky
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?

2010-12-06 Thread Sunil S Nandihalli
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?

2010-12-06 Thread Alex Baranosky
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?

2010-12-06 Thread Ken Wesson
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?

2010-12-06 Thread Alex Baranosky
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?

2010-12-06 Thread Ken Wesson
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

2009-12-29 Thread lambdatronic
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

2009-12-20 Thread Konrad Hinsen
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

2009-12-18 Thread Konrad Hinsen
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

2009-12-18 Thread Sean Devlin
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

2009-12-17 Thread C. Florian Ebeling
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

2009-12-17 Thread Sean Devlin
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

2009-12-17 Thread Laurent PETIT
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

2009-12-17 Thread C. Florian Ebeling
 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

2009-12-17 Thread Stuart Sierra
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

2009-12-17 Thread Christophe Grand
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

2009-12-17 Thread Konrad Hinsen
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

2009-12-17 Thread Erik Price
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

2009-12-17 Thread Sean Devlin
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

2009-12-17 Thread Sean Devlin
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

2009-12-17 Thread Laurent PETIT
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

2009-12-17 Thread Avital Oliver
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

2009-12-17 Thread Alex Osborne
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