Re: rules for writing macros

2009-02-15 Thread Stuart Halloway

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

2009-02-04 Thread Stuart Halloway

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

2009-02-04 Thread H Durer

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

2009-02-04 Thread CuppoJava

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

2009-02-04 Thread Nathanael Cunningham
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

2009-02-03 Thread Konrad Hinsen

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

2009-02-03 Thread GS



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

2009-02-03 Thread 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.

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

2009-02-03 Thread Chouser

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

2009-02-03 Thread Achim Passen

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

2009-02-03 Thread Daniel Jomphe

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

2009-02-03 Thread Konrad Hinsen

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