Re: Help with anonymous functions
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
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
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
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
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
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
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
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 -~--~~~~--~~--~--~---