Re: rules for writing macros
Does this clarify the point I was making? When writing macros, you cannot dynamically build one of the syntactic sugar forms. For example, you cannot write a macro that expands cls and member into (cls/member): (defmacro call-static [cls member] `(~cls/~member)) - java.lang.Exception: Invalid token: cls Instead, you should build normal, unsugared forms: (defmacro call-static [cls member] `(. ~cls ~member)) - nil On Tue, Feb 3, 2009 at 11:26 AM, Mark Volkmann r.mark.volkm...@gmail.com wrote: Now I remember what I was thinking about. This isn't so much a difference between macros and functions as it is a rule about something you cannot do in a macro. Quoting from Programming Clojure ... You cannot write a macro that expands to any of the syntactic sugar forms ... For example, you cannot write a macro that expands to (Math/PI). Hm... (defmacro pi [] 'Math/PI) == #'user/pi (macroexpand '(pi)) == Math/PI (pi) == 3.141592653589793 (defmacro strlen [s] `(.length ~s)) == #'user/strlen (strlen hello) == 5 (defmacro mydoc [s] `(:doc ^#'~s)) == #'user/mydoc (macroexpand '(mydoc doc)) == (:doc (clojure.core/meta (var doc))) (mydoc doc) == Prints documentation for a var or special form given its name That's a whole lot of sugar that all seems to work ok. Is there some other syntactic sugar form that does not work? Perhaps he's referring to actually producing reader macro usages, like this: (defmacro mydoc2 [s] `(:doc ~(symbol (str ^#' s == #'user/ mydoc2 (macroexpand '(mydoc2 doc)) == (:doc ^#'doc) (mydoc2 doc) == java.lang.Exception: Unable to resolve symbol: ^#'doc --Chouser --~--~-~--~~~---~--~~ 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 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: rules for writing macros
Thanks Mark, Chouser, I will update that section of the book with a corrected example in Beta 7. Cheers, Stuart On Tue, Feb 3, 2009 at 11:26 AM, Mark Volkmann r.mark.volkm...@gmail.com wrote: Now I remember what I was thinking about. This isn't so much a difference between macros and functions as it is a rule about something you cannot do in a macro. Quoting from Programming Clojure ... You cannot write a macro that expands to any of the syntactic sugar forms ... For example, you cannot write a macro that expands to (Math/PI). Hm... (defmacro pi [] 'Math/PI) == #'user/pi (macroexpand '(pi)) == Math/PI (pi) == 3.141592653589793 (defmacro strlen [s] `(.length ~s)) == #'user/strlen (strlen hello) == 5 (defmacro mydoc [s] `(:doc ^#'~s)) == #'user/mydoc (macroexpand '(mydoc doc)) == (:doc (clojure.core/meta (var doc))) (mydoc doc) == Prints documentation for a var or special form given its name That's a whole lot of sugar that all seems to work ok. Is there some other syntactic sugar form that does not work? Perhaps he's referring to actually producing reader macro usages, like this: (defmacro mydoc2 [s] `(:doc ~(symbol (str ^#' s == #'user/ mydoc2 (macroexpand '(mydoc2 doc)) == (:doc ^#'doc) (mydoc2 doc) == java.lang.Exception: Unable to resolve symbol: ^#'doc --Chouser --~--~-~--~~~---~--~~ 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 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: rules for writing macros
Marde, Feb 3, 2009 at 14:24, Konrad Hinsen konrad.hin...@laposte.net skribis: [...] I can't think of anything that would be forbidden in a macro but allowed in a plain function. There are many things that don't make sense in a macro, of course: launching agents, opening windows, ... Well, for normal functions you have macros to avoid the usual eager applicative rule of argument evaluation. This allows you to build e.g. infinte data structures (assuing you don't try to evaluate it all thus findining the limits of your JVM). There is I think no equivalent for macros, i.e. you cannot write a macro that expands into an infinite program (well, you can I guess but the compiler will soon show you the limits of the JVM again). Holger --~--~-~--~~~---~--~~ 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 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: rules for writing macros
Personally I find that the clearest way to think about macros, is to treat them like a *very* advanced search-and-replace feature. Just keep in mind that macros expand into code, and check to make sure that your generated code is indeed valid code. --~--~-~--~~~---~--~~ 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 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: rules for writing macros
I just wanted to point out that ' is syntactic sugar for (quote) not (list). (list) will evaluate your arguments, where as '() will not. So if you try to use them interchangeable you'll run into trouble. user (list 1 2 (+ 1 2)) (1 2 3) user '(1 2 (+ 1 2)) (1 2 (+ 1 2)) Its a pretty common lisp gotcha. -Nate --~--~-~--~~~---~--~~ 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 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: rules for writing macros
On Feb 3, 2009, at 14:49, Mark Volkmann wrote: I see from the feedback so far that my statements are wrong. However, I think it's true that there are *some* things you can do in a function that you cannot do in a macro, and perhaps vice-versa. Are those clearly documented anywhere? If not, what are some? I can't think of anything that would be forbidden in a macro but allowed in a plain function. There are many things that don't make sense in a macro, of course: launching agents, opening windows, ... Konrad. --~--~-~--~~~---~--~~ 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 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: rules for writing macros
On Feb 4, 12:01 am, Mark Volkmann r.mark.volkm...@gmail.com wrote: Are the following statements true? They aren't discussed athttp://clojure.org/macros, but I think they are true. Macros cannot call other macros during their evaluation, but they can expand to code that calls macros. I don't know, but I'll bravely guess that this is false, simply because I don't see any reason for it to be true. After all, many things we take for granted are in fact macros (e.g. for). I bet you can use for during the execution of a macro. Macros cannot use syntactic sugar such as '(items) to create a list and instead must use non-sugared forms like (list items). This is false. Macros use ', `, ~ and ~@ all the time. This leads me to a question I've always had. Is there a variant of ~@ that can be used outside of macros? e.g. (+ @(1 2 3)) ; - 6 (I realise you can use apply here, but that's not always the case.) Gavin --~--~-~--~~~---~--~~ 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 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: rules for writing macros
On Tue, Feb 3, 2009 at 8:24 AM, Konrad Hinsen konrad.hin...@laposte.net wrote: On Feb 3, 2009, at 14:49, Mark Volkmann wrote: I see from the feedback so far that my statements are wrong. However, I think it's true that there are *some* things you can do in a function that you cannot do in a macro, and perhaps vice-versa. Are those clearly documented anywhere? If not, what are some? I can't think of anything that would be forbidden in a macro but allowed in a plain function. There are many things that don't make sense in a macro, of course: launching agents, opening windows, ... Now I remember what I was thinking about. This isn't so much a difference between macros and functions as it is a rule about something you cannot do in a macro. Quoting from Programming Clojure ... You cannot write a macro that expands to any of the syntactic sugar forms ... For example, you cannot write a macro that expands to (Math/PI). when you are writing macros, make sure they expand to ordinary forms, not any of the sugared short forms. -- R. Mark Volkmann Object Computing, Inc. --~--~-~--~~~---~--~~ 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 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: rules for writing macros
On Tue, Feb 3, 2009 at 11:26 AM, Mark Volkmann r.mark.volkm...@gmail.com wrote: Now I remember what I was thinking about. This isn't so much a difference between macros and functions as it is a rule about something you cannot do in a macro. Quoting from Programming Clojure ... You cannot write a macro that expands to any of the syntactic sugar forms ... For example, you cannot write a macro that expands to (Math/PI). Hm... (defmacro pi [] 'Math/PI) == #'user/pi (macroexpand '(pi)) == Math/PI (pi) == 3.141592653589793 (defmacro strlen [s] `(.length ~s)) == #'user/strlen (strlen hello) == 5 (defmacro mydoc [s] `(:doc ^#'~s)) == #'user/mydoc (macroexpand '(mydoc doc)) == (:doc (clojure.core/meta (var doc))) (mydoc doc) == Prints documentation for a var or special form given its name That's a whole lot of sugar that all seems to work ok. Is there some other syntactic sugar form that does not work? Perhaps he's referring to actually producing reader macro usages, like this: (defmacro mydoc2 [s] `(:doc ~(symbol (str ^#' s == #'user/mydoc2 (macroexpand '(mydoc2 doc)) == (:doc ^#'doc) (mydoc2 doc) == java.lang.Exception: Unable to resolve symbol: ^#'doc --Chouser --~--~-~--~~~---~--~~ 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 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: rules for writing macros
Hi! Am 03.02.2009 um 17:26 schrieb Mark Volkmann: On Tue, Feb 3, 2009 at 8:24 AM, Konrad Hinsen konrad.hin...@laposte.net wrote: On Feb 3, 2009, at 14:49, Mark Volkmann wrote: I see from the feedback so far that my statements are wrong. However, I think it's true that there are *some* things you can do in a function that you cannot do in a macro, and perhaps vice-versa. Are those clearly documented anywhere? If not, what are some? I can't think of anything that would be forbidden in a macro but allowed in a plain function. There are many things that don't make sense in a macro, of course: launching agents, opening windows, ... Now I remember what I was thinking about. This isn't so much a difference between macros and functions as it is a rule about something you cannot do in a macro. Quoting from Programming Clojure ... You cannot write a macro that expands to any of the syntactic sugar forms ... For example, you cannot write a macro that expands to (Math/PI). when you are writing macros, make sure they expand to ordinary forms, not any of the sugared short forms. It's certainly ugly and inconvenient to do it this way, but it seems to work fine: user= (defmacro static-field [c f] (symbol (str (name c) \/ (name f #'user/field user= (macroexpand-1 '(static-field Math PI)) Math/PI user= (static-field Math PI) 3.141592653589793 user= (defmacro call-method [o m] `(~(symbol (str \. m)) ~o)) #'user/call user= (macroexpand-1 '(call-method foo toString)) (.toString foo) user= (call-method foo toString) foo Kind regards, achim -- R. Mark Volkmann Object Computing, Inc. --~--~-~--~~~---~--~~ 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 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: rules for writing macros
Mark Volkmann wrote: I see from the feedback so far that my statements are wrong. However, I think it's true that there are *some* things you can do in a function that you cannot do in a macro, and perhaps vice-versa. Are those clearly documented anywhere? If not, what are some? You might be interested in the development of this thread: http://groups.google.com/group/clojure/browse_thread/thread/fa976abf80c91361/0019b33732f34e62 --~--~-~--~~~---~--~~ 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 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: rules for writing macros
On Feb 3, 2009, at 14:01, Mark Volkmann wrote: Are the following statements true? They aren't discussed at http://clojure.org/macros, but I think they are true. Macros cannot call other macros during their evaluation, but they can expand to code that calls macros. Macros can certainly expand to code that uses macros. As for the first part of your statement, it depends on what you mean by calling a macro. A macro is just a function marked (with a tag in the metadata) as a macro. More precisely, the var whose value is the macro is tagged as a macro. This tag causes the compiler to call the macro function at compile time, rather than compile a call at runtime. The arguments are therefore unevaluated forms. The definition of a macro is an ordinary function definition, which can use macros just like any other function. These macros will be expanded when the macro is compiled, not when it is executed. If you want it to call another function tagged as a macro, but call it as if it weren't tagged as a macro, you can retrieve its function definition from the var and call it by another name. For example, (def and-fn @(var and)) will assign the function that implements and to and-fn, which is an ordinary function. Macros cannot use syntactic sugar such as '(items) to create a list and instead must use non-sugared forms like (list items). The standard quote is not very useful in macro definitions, but syntax-quote (`) is: (defmacro l [x y] `(~x ~y)) (macroexpand-1 '(l 1 2)) -- (1 2) Konrad. --~--~-~--~~~---~--~~ 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 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 -~--~~~~--~~--~--~---