Re: Mapping a function to a map

2010-09-08 Thread Daniel Werner
On Sep 7, 9:00 am, Thomas  wrote:
> I've also been using my own version of a map-to-values function
> extensively and it would be really nice to have something like that,
> either in contrib or in core. It comes in handy surprisingly often.

+1

I find myself writing functions like map-values and filter-values over
and over again in different languages because they are so useful. If
possible, I would prefer to (:use) a single, canonical version from
clojure.contrib (or clojure.core).

Daniel

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that 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: Mapping a function to a map

2010-09-07 Thread Thomas
I've also been using my own version of a map-to-values function
extensively and it would be really nice to have something like that,
either in contrib or in core. It comes in handy surprisingly often.

Best,

Thomas

On Sep 6, 5:40 pm, Nicolas Oury  wrote:
> Dear all,
>
> is there a function to map a function to all values in a map, keeping
> the same keys?
> Reducing from the seqed map seems a bit slower that what could be done
> directly...
>
> Best,
>
> Nicolas.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that 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: Mapping a function to a map

2010-09-06 Thread Nicolas Oury
Different reactions:

1. The reduce solution is O(n .log n) + time of mapping elements, as
inserting in a map is O(log n). A tree with n leafs and arity at least
binary is of size at most 2n. So a map on a map could be done
 in O(n) + time of mapping elements, but it would need a bit of
support from runtime.

My question was : is there such support in runtime? Is it planned?
Would such a patch be welcomed or not?


2. lazy maps would not be performant. A seq of pairs would have a O(n)
look up. Clojure hash-map and sorted-map have a O(log n) look up.
Having a seq of pairs can be done manually but is less useful than
real maps.

3. reduce is strict because it is a consumer. The co-operator of
reduce is a producer and should be lazy.
reduce type is (a -> b -> b) -> (seq a) -> b
a co-reduce would be : (a-> (a , b)) -> a -> (seq b), meaning, with a
state, you produce an element and another state(a is the type of state
and b of element).
It is often called unfold and would be a nice addition to clojure.contrib.
I think that most lazy sequence can provably be written as (), cons
and unfold, but I am not sure and have no reference in mind.

Best,

Nicolas.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that 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: Mapping a function to a map

2010-09-06 Thread gary ng
On Mon, Sep 6, 2010 at 10:47 AM, Robert McIntyre  wrote:
> Why is it that clojure maps aren't lazy though?
> Wouldn't that be just as useful an abstraction as lazy sequences?
> Aren't map really just lists of pairs in the end anyway?
>
how can laziness benefit map usage pattern ? efficient search requires
the keys to be in some form of balanced tree(?) so everything needs to
be realized while building the tree ?

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that 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: Mapping a function to a map

2010-09-06 Thread Robert McIntyre
Why is it that clojure maps aren't lazy though?
Wouldn't that be just as useful an abstraction as lazy sequences?
Aren't map really just lists of pairs in the end anyway?

--Robert McIntyre

On Mon, Sep 6, 2010 at 1:19 PM, Michał Marczyk  wrote:
> On 6 September 2010 18:49, Robert McIntyre  wrote:
>> I thought that since into uses reduce, it would be lazy, but I was wrong.
>> reduce just plows through everything with a non-lazy recursion.
>
> Well, there's another reason in that the concept of a lazy map is
> problematic. In Clojure, at any rate, either you have a map or you
> don't -- it's always strict.
>
>> Why is reduce not lazy?
>
> The tail call in reduce is a call to itself, so it's pretty hard to
> imagine a meaningful way for it to be lazy -- it only has anything to
> return other than a result to a further call to reduce upon reaching
> the end of the sequence being reduced. Thus, it's purpose is
> fundamentally to go through the entire seq producing a single "end
> product".
>
> In contrast, a right fold's tail is a call to the reduction function
> with one of the arguments being a further call to foldr, so that can
> be made lazy in a sufficiently lazy language; but in Clojure, only
> seqs can be lazy, so that wouldn't really work either.
>
> Sincerely,
> Michał
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that 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: Mapping a function to a map

2010-09-06 Thread Stuart Sierra
On Sep 6, 11:40 am, Nicolas Oury  wrote:
> is there a function to map a function to all values in a map, keeping
> the same keys?

I like "reduce" because you can modify both the key and the value, and
even choose to omit or add certain keys:

(reduce (fn [[k v] m] (assoc m k (...do stuff with v...)) {} the-
input-map)

The more common "into/map" style may be slightly easier to understand:

(into {} (map (fn [[k v]] ...return a pair...) the-input-map)

Neither form is lazy, because Clojure maps aren't lazy.

-S

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that 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: Mapping a function to a map

2010-09-06 Thread Michał Marczyk
On 6 September 2010 18:49, Robert McIntyre  wrote:
> I thought that since into uses reduce, it would be lazy, but I was wrong.
> reduce just plows through everything with a non-lazy recursion.

Well, there's another reason in that the concept of a lazy map is
problematic. In Clojure, at any rate, either you have a map or you
don't -- it's always strict.

> Why is reduce not lazy?

The tail call in reduce is a call to itself, so it's pretty hard to
imagine a meaningful way for it to be lazy -- it only has anything to
return other than a result to a further call to reduce upon reaching
the end of the sequence being reduced. Thus, it's purpose is
fundamentally to go through the entire seq producing a single "end
product".

In contrast, a right fold's tail is a call to the reduction function
with one of the arguments being a further call to foldr, so that can
be made lazy in a sufficiently lazy language; but in Clojure, only
seqs can be lazy, so that wouldn't really work either.

Sincerely,
Michał

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that 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: Mapping a function to a map

2010-09-06 Thread gary ng
On Mon, Sep 6, 2010 at 10:09 AM, Justin Kramer  wrote:
> reduce returns a single value; there's no collection to make lazy.
> There is reductions, which returns the intermediate results of reduce
> as a lazy sequence.
>
if f = cons in 'reduce f a seq', there is a collection. Though in this
case, one should use foldr rather than foldl.

That lead to a question I have asked before, is there a lazy foldr in
clojure ? A related question, what about unfold ?

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that 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: Mapping a function to a map

2010-09-06 Thread Justin Kramer
reduce returns a single value; there's no collection to make lazy.
There is reductions, which returns the intermediate results of reduce
as a lazy sequence.

Justin

On Sep 6, 12:49 pm, Robert McIntyre  wrote:
> I thought that since into uses reduce, it would be lazy, but I was wrong.
> reduce just plows through everything with a non-lazy recursion.
>
> Why is reduce not lazy?
>
> --Robert McIntyre
>
> On Mon, Sep 6, 2010 at 12:37 PM, Michał Marczyk
>
>
>
>  wrote:
> > On 6 September 2010 18:29, Robert McIntyre  wrote:
> >> walk is good but it's not lazy. If you want to preserve laziness you can 
> >> do:
>
> > This won't be lazy, because (into {} ...) is a strict operation.
>
> > I'd suggest something like
>
> > (defn mmap [f m]
> >  (zipmap (keys m) (map f (vals m
>
> > f is expected to care about the value only.
>
> > Sincerely,
> > Michał
>
> > --
> > You received this message because you are subscribed to the Google
> > Groups "Clojure" group.
> > To post to this group, send email to clojure@googlegroups.com
> > Note that 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: Mapping a function to a map

2010-09-06 Thread gary ng
On Mon, Sep 6, 2010 at 9:49 AM, Robert McIntyre  wrote:
> I thought that since into uses reduce, it would be lazy, but I was wrong.
> reduce just plows through everything with a non-lazy recursion.
>
> Why is reduce not lazy?
>
reduce in clojure == foldl in Haskell

and as far as I know, there are very rare use cases for lazy foldl.
The general rule of thumb in Haskell is use foldl'(strict version) or
foldr(lazy). That may explain why reduce is not lazy.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that 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: Mapping a function to a map

2010-09-06 Thread Robert McIntyre
I thought that since into uses reduce, it would be lazy, but I was wrong.
reduce just plows through everything with a non-lazy recursion.

Why is reduce not lazy?

--Robert McIntyre

On Mon, Sep 6, 2010 at 12:37 PM, Michał Marczyk
 wrote:
> On 6 September 2010 18:29, Robert McIntyre  wrote:
>> walk is good but it's not lazy. If you want to preserve laziness you can do:
>
> This won't be lazy, because (into {} ...) is a strict operation.
>
> I'd suggest something like
>
> (defn mmap [f m]
>  (zipmap (keys m) (map f (vals m
>
> f is expected to care about the value only.
>
> Sincerely,
> Michał
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that 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: Mapping a function to a map

2010-09-06 Thread Michał Marczyk
On 6 September 2010 18:29, Robert McIntyre  wrote:
> walk is good but it's not lazy. If you want to preserve laziness you can do:

This won't be lazy, because (into {} ...) is a strict operation.

I'd suggest something like

(defn mmap [f m]
  (zipmap (keys m) (map f (vals m

f is expected to care about the value only.

Sincerely,
Michał

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that 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: Mapping a function to a map

2010-09-06 Thread Robert McIntyre
walk is good but it's not lazy. If you want to preserve laziness you can do:

(defn map-vals
  "transform a map by mapping it's keys to different values."
  [f m]
  (into {} (map (fn [[key val]] [key (f val)]) m)))

This is also nice because you can then write functions whose arguments
are [val] instead of [key val] and ignoring the key.

--Robert McIntyre

On Mon, Sep 6, 2010 at 12:06 PM, Sunil S Nandihalli
 wrote:
>  (clojure.walk/walk (fn [[key val]] [key (* 2 val)]) identity {:a 1 :b 2})
>
> On Mon, Sep 6, 2010 at 9:26 PM, Sunil S Nandihalli
>  wrote:
>>
>> Nicolas
>> I am not sure of the performance characteristics.. but you may want to
>> look at
>> (clojure.walk/walk #(do (println "inner : " %) %) #(do (println "outer : "
>> %) %) {:a 1 :b 2})
>>
>> Best regards,
>> Sunil.
>> On Mon, Sep 6, 2010 at 9:10 PM, Nicolas Oury 
>> wrote:
>>>
>>> Dear all,
>>>
>>> is there a function to map a function to all values in a map, keeping
>>> the same keys?
>>> Reducing from the seqed map seems a bit slower that what could be done
>>> directly...
>>>
>>> Best,
>>>
>>> Nicolas.
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To post to this group, send email to clojure@googlegroups.com
>>> Note that 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: Mapping a function to a map

2010-09-06 Thread Sunil S Nandihalli
 (clojure.walk/walk (fn [[key val]] [key (* 2 val)]) identity {:a 1 :b 2})

On Mon, Sep 6, 2010 at 9:26 PM, Sunil S Nandihalli <
sunil.nandiha...@gmail.com> wrote:

> Nicolas
> I am not sure of the performance characteristics.. but you may want to look
> at
>
> *(clojure.walk/walk #(do (println "inner : " %) %) #(do (println "outer :
> " %) %) {:a 1 :b 2})
> *
> Best regards,
> Sunil.
>
> On Mon, Sep 6, 2010 at 9:10 PM, Nicolas Oury wrote:
>
>> Dear all,
>>
>> is there a function to map a function to all values in a map, keeping
>> the same keys?
>> Reducing from the seqed map seems a bit slower that what could be done
>> directly...
>>
>> Best,
>>
>> Nicolas.
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that 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: Mapping a function to a map

2010-09-06 Thread Sunil S Nandihalli
Nicolas
I am not sure of the performance characteristics.. but you may want to look
at

*(clojure.walk/walk #(do (println "inner : " %) %) #(do (println "outer : "
%) %) {:a 1 :b 2})
*
Best regards,
Sunil.
On Mon, Sep 6, 2010 at 9:10 PM, Nicolas Oury  wrote:

> Dear all,
>
> is there a function to map a function to all values in a map, keeping
> the same keys?
> Reducing from the seqed map seems a bit slower that what could be done
> directly...
>
> Best,
>
> Nicolas.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that 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