Re: how to understand macro in clojure?
On Mon, Sep 28, 2009 at 5:23 AM, Jarkko Oranen chous...@gmail.com wrote: What happens is, when you call (mfloat + 1 2) the macro evaluates ('+ (float 1) (float 2)), ie. it calls the *symbol* + with parameters 1.0 and 2.0. Symbols, when used as functions, look themselves up in whatever associative thing you give them as the first parameter, OR return the second parameter in case of lookup failure. So, ('+ 1.0 2.0) evaluates to 2.0, which is the macro expansion. and as 2.0 evaluated is 2.0, it is the actual result. Very sneaky. Why is invoking a symbol returning the second argument even when the first is not an associative thing at all? It should probably return the second argument (defaulting to nil) on not-found but not on genuine errors. A ClassCastException java.lang.Float cannot be cast to clojure.core.IAssoc (or whatever) would have been more informative in this case. --~--~-~--~~~---~--~~ 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: how to understand macro in clojure?
Hi 2009/9/26 gerryx...@gmail.com gerryx...@gmail.com: (defn float2 [f a b] (f (float a ) (float b))) (float2 + 1 2) = 3.0 (defmacro mfloat2 [f a b] (f (float a) (float b))) (mfloat2 + 1 2 ) = 2.0 ??? macro expend to last expression in list,right? This is because (mfloat2 + 1 2) expands to: + (float 1) (float 2) Notice that there are no parentheses around the whole thing. i.e. this is not a function call. And if you evaluate that, you get: user= + (float 1) (float 2) #core$_PLUS___4323 clojure.core$_plus___4...@b2ee9a 1.0 2.0 Only the last value is used. Also: user= (mfloat2 + (+ 0 1) (+ 1 1)) java.lang.ClassCastException: clojure.lang.PersistentList (NO_SOURCE_FILE:0) (defmacro m2float2 [f a b] `(~f (float ~a) (float ~b))) (mfloat2 + 1 2) = 3.0 This expands as follows: user= (macroexpand-1 '(m2float2 + 1 2)) (+ (clojure.core/float 1) (clojure.core/float 2)) so it does the right thing. And passing in expressions instead of literal numbers works too: user= (m2float2 + (+ 0 1) (+ 1 1)) 3.0 (defmacro m3float2 [f a b] (list f (float a ) (float b))) (m3float2 + 1 2) = 3.0 This one expands as follows: user= (macroexpand-1 '(m3float2 + 1 2)) (+ 1.0 2.0) and you get the same error as for the first one if you try to pass in something that is not a literal number: user= (m3float2 + (+ 0 1) (+ 1 1)) java.lang.ClassCastException: clojure.lang.PersistentList (NO_SOURCE_FILE:0) functions of macro only not evaluating args ? A macro is basically a function that takes some code and produces other code before the compiler compiles the program. I am not an expert on macros, so maybe someone else here could give you a proper answer. what's the difference between macro and call by name in other language? I don't know what call by name is. A book that is often recommended for helping to understand lisp macros is On Lisp by Paul Graham. This is a book about Common Lisp macros, but they are quite similar to Clojure macros. The book is downloadable from here: http://www.paulgraham.com/onlisptext.html -- Michael Wood esiot...@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: how to understand macro in clojure?
On Sep 28, 12:13 pm, Michael Wood esiot...@gmail.com wrote: Hi 2009/9/26 gerryx...@gmail.com gerryx...@gmail.com: (defn float2 [f a b] (f (float a ) (float b))) (float2 + 1 2) = 3.0 (defmacro mfloat2 [f a b] (f (float a) (float b))) (mfloat2 + 1 2 ) = 2.0 ??? macro expend to last expression in list,right? This is because (mfloat2 + 1 2) expands to: + (float 1) (float 2) This is wrong. There is no way for a macro to expand to multiple expressions. What happens is, when you call (mfloat + 1 2) the macro evaluates ('+ (float 1) (float 2)), ie. it calls the *symbol* + with parameters 1.0 and 2.0. Symbols, when used as functions, look themselves up in whatever associative thing you give them as the first parameter, OR return the second parameter in case of lookup failure. So, ('+ 1.0 2.0) evaluates to 2.0, which is the macro expansion. and as 2.0 evaluated is 2.0, it is the actual result. in the defn case, it works because the f parameter is actually evaluated, and thus it's the + *function* and not the symbol '+. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
how to understand macro in clojure?
(defn float2 [f a b] (f (float a ) (float b))) (float2 + 1 2) = 3.0 (defmacro mfloat2 [f a b] (f (float a) (float b))) (mfloat2 + 1 2 ) = 2.0 ??? macro expend to last expression in list,right? (defmacro m2float2 [f a b] `(~f (float ~a) (float ~b))) (mfloat2 + 1 2) = 3.0 (defmacro m3float2 [f a b] (list f (float a ) (float b))) (m3float2 + 1 2) = 3.0 functions of macro only not evaluating args ? what's the difference between macro and call by name in other language? gerry --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---