Re: how to understand macro in clojure?

2009-09-29 Thread John Harrop
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?

2009-09-28 Thread Michael Wood

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?

2009-09-28 Thread Jarkko Oranen



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?

2009-09-25 Thread 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?

(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
-~--~~~~--~~--~--~---