On Tue, Dec 23, 2008 at 10:15 AM, Adam Harrison (Clojure)
<[email protected]> wrote:
>
>
> Hi folks,
>
> I have been trying to work out how best to validate the structure of
> arguments passed into macros. It would appear that there are several
> ways of tackling this and I was wondering which is considered best
> practice. As an example, lets say I want a macro, 'print-even' which
> prints its arguments if they are even in number and throws an exception
> otherwise (sorry for the poor example but it's illustrative). I can see
> at least three implementations:
>
> 1) Defer all the work until the expanded macro code is executed:
>
> (defmacro print-even [& args]
>  `(if (even? (count '~args))
>    (print ~...@args)
>    (throw (Exception. "Uneven"))))
>
> 2) Perform the even? check at macro time, but leave throwing the
> exception until runtime:
>
> (defmacro print-even [& args]
>  (if (even? (count args))
>    `(print ~...@args)
>    `(throw (Exception. "Uneven"))))
>
> 3) Throw the exception at macro time:
>
> (defmacro print-even [& args]
>  (if (even? (count args))
>    `(print ~...@args)
>    (throw (Exception. (format "Uneven (%d arguments)" (count args)))))
>
>
> Intuitively (3) feels like the right choice for two reasons:
>
> - It does as much of the work as possible up front
> - Given that defmacro is effectively extending the syntax of the
> language, you could view calling print-even with an odd number of
> arguments as a syntax error which seems best raised as early as possible
>
> This has an obvious flaw though - the caller may expect to be able to
> supply an expression which they want evaluated:
>
> (print-even (range 1 3))
>

It is that expectation which is flawed. You can't substitute:

(print-even (range 1 3))

for

(print-even 1 2)

In a macro or a function.

Functions/macros don't auto-apply themselves when taking & args.

(defn foo [& args] args)

(foo 1 2)
-> (1 2)

(foo (range 1 3))
-> ((1 2))

Rich

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to