Re: Help with anonymous functions

2009-10-25 Thread jsrodrigues

Thanks for the help Lauri!

John

On Oct 25, 10:29 am, Lauri Pesonen  wrote:
> Hi John,
>
> 2009/10/25 jsrodrigues :
>
>
>
> > When I try the following:
> > user=> (into {} (map #([% (* % %)]) [1 2 3 4]))
>
> The #(...) form assumes that the is a function call and thus it is
> implicitly wrapped in parens. That is, #(+ % %) becomes (fn [x] (+ x
> x)). So in your code the anonymous function body becomes ([x (* x x)])
> which is broken and results in the error you are seeing. To fix this
> you need to use a function that creates a vector out of your arguments
> rather than the literal vector notation, i.e. #(vector % (* % %))
>
> user> (map #(vector % (* % %)) [1 2 3 4])
> ([1 1] [2 4] [3 9] [4 16])
>
> > John
>
> --
>   ! Lauri

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

2009-10-25 Thread MarkSwanson

Thanks Lauri. I was stuck on this too.

FYI this issue prompted me to submit a patch to improve the arity
error message:

http://groups.google.com/group/clojure/browse_thread/thread/de969a419a535a82


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

2009-10-25 Thread Lauri Pesonen

Hi John,

2009/10/25 jsrodrigues :
>
> When I try the following:
> user=> (into {} (map #([% (* % %)]) [1 2 3 4]))

The #(...) form assumes that the is a function call and thus it is
implicitly wrapped in parens. That is, #(+ % %) becomes (fn [x] (+ x
x)). So in your code the anonymous function body becomes ([x (* x x)])
which is broken and results in the error you are seeing. To fix this
you need to use a function that creates a vector out of your arguments
rather than the literal vector notation, i.e. #(vector % (* % %))

user> (map #(vector % (* % %)) [1 2 3 4])
([1 1] [2 4] [3 9] [4 16])

> John

-- 
  ! Lauri

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



Help with anonymous functions

2009-10-25 Thread jsrodrigues

Hi,

I'm trying to find the #(...) equivalent of (fn [] ...) for the
following case:

user=> (into {} (map (fn [x] [x (* x x)]) [1 2 3 4]))
{4 16, 3 9, 2 4, 1 1}

When I try the following:
user=> (into {} (map #([% (* % %)]) [1 2 3 4]))

I get the error:
java.lang.RuntimeException: java.lang.IllegalArgumentException: Wrong
number of args passed to: LazilyPersistentVector (NO_SOURCE_FILE:0)

I even tried the following:
user=> (macroexpand-1 '#([% (* % %)]))

And got the result from the macroexpand-1:
(fn* [p1__181] ([p1__181 (* p1__181 p1__181)]))

What am I doing wrong here?

Thanks,
John


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: -> with anonymous functions

2009-09-22 Thread Roman Roelofsen

Thanks for the explanation!

So the solution is much simpler:

user=> (-> person :childs first (select-keys [:name]))
{:name "Son"}

Cool :-)



On Sep 22, 3:26 pm, Jarkko Oranen  wrote:
> On Sep 22, 3:58 pm, Roman Roelofsen 
> wrote:
>
>
>
> > Hi there!
>
> > Lets assume I have this map:
>
> > user=> (def person {:name "Father" :childs [{:name "Son" :age 10}]})
>
> > Testing:
>
> > user=> (-> person :childs first)
> > {:name "Son", :age 10}
>
> > Now lets filter the child map:
>
> > user=> (def only-name (fn [m] (select-keys m [:name])))
> > user=> (-> person :childs first only-name)
> > {:name "Son"}
>
> > So why does this not work?:
>
> > user=> (-> person :childs first (fn [m] (select-keys m [:name])))
> > java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't
> > know how to create ISeq from: Symbol (NO_SOURCE_FILE:59)
>
> > Or this?:
>
> > user=> (-> person :childs first #(select-keys % [:name]))
> > java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to
> > clojure.lang.IPersistentVector (NO_SOURCE_FILE:60)
>
> You assume more of -> than you should :)
> -> does not take functions as parameters. It only sees a bunch of
> symbols, as it is a macro, which means it does a code transformation.
> It puts the first form (the symbol person) in the second position of
> the following form (the keyword :childs), which must be a sequence, or
> if it is not, is wrapped in a list first. This repeats recursively
> until there are no more forms left.
> Now, the anonymous function example fails because (-> person :childs
> first (fn [] whatever)) transforms into (fn (first (:childs person)) x
> [] y). which is not what you intended, but nonetheless a correct
> result.
>
> If you look at the examples that work and macroexpand them, you would
> see that (-> person :childs first) transforms first into (-> (:childs
> person) first) and from there to (first (:childs person)) which
> happens to be a valid Clojure expression

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

2009-09-22 Thread Jarkko Oranen



On Sep 22, 3:58 pm, Roman Roelofsen 
wrote:
> Hi there!
>
> Lets assume I have this map:
>
> user=> (def person {:name "Father" :childs [{:name "Son" :age 10}]})
>
> Testing:
>
> user=> (-> person :childs first)
> {:name "Son", :age 10}
>
> Now lets filter the child map:
>
> user=> (def only-name (fn [m] (select-keys m [:name])))
> user=> (-> person :childs first only-name)
> {:name "Son"}
>
> So why does this not work?:
>
> user=> (-> person :childs first (fn [m] (select-keys m [:name])))
> java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't
> know how to create ISeq from: Symbol (NO_SOURCE_FILE:59)
>
> Or this?:
>
> user=> (-> person :childs first #(select-keys % [:name]))
> java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to
> clojure.lang.IPersistentVector (NO_SOURCE_FILE:60)

You assume more of -> than you should :)
-> does not take functions as parameters. It only sees a bunch of
symbols, as it is a macro, which means it does a code transformation.
It puts the first form (the symbol person) in the second position of
the following form (the keyword :childs), which must be a sequence, or
if it is not, is wrapped in a list first. This repeats recursively
until there are no more forms left.
Now, the anonymous function example fails because (-> person :childs
first (fn [] whatever)) transforms into (fn (first (:childs person)) x
[] y). which is not what you intended, but nonetheless a correct
result.

If you look at the examples that work and macroexpand them, you would
see that (-> person :childs first) transforms first into (-> (:childs
person) first) and from there to (first (:childs person)) which
happens to be a valid Clojure expression

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

2009-09-22 Thread Christophe Grand
Hi Roman!

On Tue, Sep 22, 2009 at 2:58 PM, Roman Roelofsen <
roman.roelof...@googlemail.com> wrote:

>
> Hi there!
>
> Lets assume I have this map:
>
> user=> (def person {:name "Father" :childs [{:name "Son" :age 10}]})
>
> Testing:
>
> user=> (-> person :childs first)
> {:name "Son", :age 10}
>
> Now lets filter the child map:
>
> user=> (def only-name (fn [m] (select-keys m [:name])))
> user=> (-> person :childs first only-name)
> {:name "Son"}
>
> So why does this not work?:
>
> user=> (-> person :childs first (fn [m] (select-keys m [:name])))
> java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't
> know how to create ISeq from: Symbol (NO_SOURCE_FILE:59)
>

because -> put its firs t argument in second position into its second
argument:
(-> foo (fn [x] x)) becomes (fn foo [x] x)

user=> (macroexpand-1 '(-> foo (fn [x] x)))
(fn foo [x] x)

Or this?:
>
> user=> (-> person :childs first #(select-keys % [:name]))
> java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to
> clojure.lang.IPersistentVector (NO_SOURCE_FILE:60)
>

Ditto. At read time, #(...) expand to seomething like (fn [x] (...)).

One usual albeit somewhat ugly workaround is to put another pair of parens
around the fn

user=> (macroexpand-1 '(-> foo ((fn [x] x
((fn [x] x) foo)

HTH,

 Christophe

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



-> with anonymous functions

2009-09-22 Thread Roman Roelofsen

Hi there!

Lets assume I have this map:

user=> (def person {:name "Father" :childs [{:name "Son" :age 10}]})

Testing:

user=> (-> person :childs first)
{:name "Son", :age 10}

Now lets filter the child map:

user=> (def only-name (fn [m] (select-keys m [:name])))
user=> (-> person :childs first only-name)
{:name "Son"}

So why does this not work?:

user=> (-> person :childs first (fn [m] (select-keys m [:name])))
java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't
know how to create ISeq from: Symbol (NO_SOURCE_FILE:59)

Or this?:

user=> (-> person :childs first #(select-keys % [:name]))
java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to
clojure.lang.IPersistentVector (NO_SOURCE_FILE:60)


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