Re: Macro Implementation: I Don't Understand This Error Message
I'm not sure where I picked it up, but I remembered the arguments being called form and env, and googling for clojure form env led me to: http://groups.google.com/group/clojure/browse_thread/thread/d710c290b67951a3/b827d46389110f26?lnk=gstq=clojure+macro+%26env#b827d46389110f26 : form contains the form how the *macro* was called. *env* contains local bindings in the *macro* environment. (At least this is what my little test shows...) These magic parameters are given to all parameters, but usually hidden. It's probably safe to ignore them if you don't know what they really do. -- Eivind Magnus Hvidevold Cell: +47 926 78 423 On Sat, Oct 2, 2010 at 8:41 AM, Stefan Rohlfing stefan.rohlf...@gmail.comwrote: @Jürgen and Chris Thank you very much for helping me enlarge my understanding of macros! I realize that learning the subtleties of a macro implementation is not easy but well worth the effort. It is also quite interesting that a macro as it seems takes two implicit extra arguments. I am curious what these arguments might be and hope someone can tell us. Stefan Actually, it's not. That's becuase the compiler inserts a couple of extra implicit arguments to all calls to macros. So in fact, my-infix, at runtime, expects 3 arguments. Check this out: user= (defmacro foo [x] x) #'user/foo user= (foo 23) 23 user= (def foo2 (var-get #'foo)) #'user/foo2 user= (foo2 23) java.lang.IllegalArgumentException: Wrong number of args (1) passed to: user$foo (NO_SOURCE_FILE:0) user= (foo2 23 34 45) 45 I hope that makes it clearer. I certainly feel like I understand macros a little better after figuring this out. As for what exactly the two implicit args to macros are - I don't know. Someone else will have to explain that. - Chris -- 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.comclojure%2bunsubscr...@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: Macro Implementation: I Don't Understand This Error Message
@Jürgen and Chris Thank you very much for helping me enlarge my understanding of macros! I realize that learning the subtleties of a macro implementation is not easy but well worth the effort. It is also quite interesting that a macro as it seems takes two implicit extra arguments. I am curious what these arguments might be and hope someone can tell us. Stefan Actually, it's not. That's becuase the compiler inserts a couple of extra implicit arguments to all calls to macros. So in fact, my-infix, at runtime, expects 3 arguments. Check this out: user= (defmacro foo [x] x) #'user/foo user= (foo 23) 23 user= (def foo2 (var-get #'foo)) #'user/foo2 user= (foo2 23) java.lang.IllegalArgumentException: Wrong number of args (1) passed to: user$foo (NO_SOURCE_FILE:0) user= (foo2 23 34 45) 45 I hope that makes it clearer. I certainly feel like I understand macros a little better after figuring this out. As for what exactly the two implicit args to macros are - I don't know. Someone else will have to explain that. - Chris -- 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
Macro Implementation: I Don't Understand This Error Message
Dear Clojure Group, I wanted to expand the 'infix' macro presented in chapter 7.3.1 of 'Clojure in Action' to handle nested s-expressions: My first version did not work: (defmacro my-infix [expr] (if (coll? expr) (let [ [left op right] expr] (list op (my-infix left) (my-infix right))) expr)) ;; Test: (my-infix ((3 * 5) - (1 + 1))) ;; Wrong number of args (1) passed to: user$my-infix ;; [Thrown class java.lang.IllegalArgumentException] However, the following version does work: (defmacro new-infix [expr] (if (coll? expr) (let [ [left op right] expr] `(~op (new-infix ~left) (new-infix ~right))) expr)) (new-infix ((3 * 5) - (1 + 1))) ;; -- 13 (macroexpand '(new-infix ((3 * 5) - (1 + 1 ;; (- (user/new-infix (3 * 5)) (user/new-infix (1 + 1))) I would love to know why the first version 'my-infix' throws an exception. Can anybody give me a hint? I hope the answer could give me a better understanding of how macros work. -- 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: Macro Implementation: I Don't Understand This Error Message
2010/10/1 Stefan Rohlfing stefan.rohlf...@gmail.com: Dear Clojure Group, I wanted to expand the 'infix' macro presented in chapter 7.3.1 of 'Clojure in Action' to handle nested s-expressions: My first version did not work: (defmacro my-infix [expr] (if (coll? expr) (let [ [left op right] expr] (list op (my-infix left) (my-infix right))) expr)) ;; Test: (my-infix ((3 * 5) - (1 + 1))) ;; Wrong number of args (1) passed to: user$my-infix ;; [Thrown class java.lang.IllegalArgumentException] Macros a special functions meant to be called by the compiler during macro-expansion. But you a are calling a macro function directly in your function body, instead of generating code that will be expanded (calling your macro function) by the compiler: (defmacro my-infix [expr] (if (coll? expr) (let [ [left op right] expr] (list op `(my-infix ~left) `(my-infix ~right))) expr)) Jürgen -- 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: Macro Implementation: I Don't Understand This Error Message
On Oct 1, 3:59 am, Stefan Rohlfing stefan.rohlf...@gmail.com wrote: I wanted to expand the 'infix' macro presented in chapter 7.3.1 of 'Clojure in Action' to handle nested s-expressions: My first version did not work: (defmacro my-infix [expr] (if (coll? expr) (let [ [left op right] expr] (list op (my-infix left) (my-infix right))) expr)) ;; Test: (my-infix ((3 * 5) - (1 + 1))) ;; Wrong number of args (1) passed to: user$my-infix ;; [Thrown class java.lang.IllegalArgumentException] I would love to know why the first version 'my-infix' throws an exception. Can anybody give me a hint? I hope the answer could give me a better understanding of how macros work. I think I can explain - someone correct me if I'm wrong. The problem occurs while my-infix is being compiled. As the compiler works its way into the body of my-infix, it comes across a call to something called my-infix. Intuitively, you would expect that since my- infix is a macro (or is it? more to come), the compiler would call it then-and-there - but how could it? my-infix hasn't even finished compiling, so how could it possibly be called? So my next thought is that it should be an error - and this may very well be true. But it seems that what actually happens is that the my- infix var is in a sort of intermediate state - it exists, which is why the compiler doesn't complain, but it has not yet been flagged as being a macro. Try this: (defmacro ct-prn [expr] ; compile-time prn (prn (eval expr)) expr) (defmacro my-infix [expr] (ct-prn (meta #'my-infix)) (if (coll? expr) (let [ [left op right] expr] (list op (my-infix left) (my-infix right))) expr)) (prn (meta #'my-infix)) Here's what I get printed out: {:ns #Namespace user, :name my-infix} {:macro true, :ns #Namespace user, :name my-infix, :file C:\\Temp\ \temp.clj, :line 5, :arglists ([expr])} So while compiling, my-infix is not yet flagged as a macro, so the call to it gets compliled into a regular, run-time call to a function. Still this seems like it should be OK - what's up with the Wrong number of args (1)... stuff? Isn't 1 the right number of args for my- infix? Actually, it's not. That's becuase the compiler inserts a couple of extra implicit arguments to all calls to macros. So in fact, my-infix, at runtime, expects 3 arguments. Check this out: user= (defmacro foo [x] x) #'user/foo user= (foo 23) 23 user= (def foo2 (var-get #'foo)) #'user/foo2 user= (foo2 23) java.lang.IllegalArgumentException: Wrong number of args (1) passed to: user$foo (NO_SOURCE_FILE:0) user= (foo2 23 34 45) 45 I hope that makes it clearer. I certainly feel like I understand macros a little better after figuring this out. As for what exactly the two implicit args to macros are - I don't know. Someone else will have to explain that. - Chris -- 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