[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: macros vs. blocks
At 11:26 PM -0800 11/21/02, Trevor Blackwell wrote:
>John Clements <firstname.lastname@example.org> writes:
>> Hmm. If you consider the three largest categories of macros [*] to be
>> 1) those that affect evaluation order (if),
>> 2) those that introduce literal data (quote), and
>> 3) those that introduce bindings (let),
>> I don't see how block notation solves any other than category (1).
>I would refine my macros-are-useless claim a bit: languages that already
>have syntax for things such as assignment, variable declaration, and
>quoted data (Python, Perl, Smalltalk, ...) don't benefit much from
Funny, Lisp and Dylan have support for all of these things, and
I see quite a bit of benefit. But, hey, what do I know.
>Using macros for #2 is probably a bad idea. I think it's generally
>clearer to include the ' symbol (or whatever your favorite language
>uses) than to have some arguments be magically quoted.
>Using macros for #3 is also usually a bad idea. Having macros like CL
>(do) or (while), which magically introduce a variable with non-obvious
>scoping, is hazardous. I'd rather just have one way of declaring
>control-structure variables, like Smalltalk:
> list do: [:x |
> x print.
>where it's totally obvious what the scope of the variable is. Scheme
>succeeds here too, because it uses lambda semantics everywhere.
What makes you think that, say, Lisp macros introduce variables
that have "magic" or "non-obvious" scoping? I can see that the
scope for x is within  in your example, which isn't very much
different from this:
(dolist (x list)
And yes, I could have used (mapc #'print list), but we're talking
about macros here.
>Alan Bawden <Alan@LCS.MIT.EDU> writes:
>> (define-syntax assert
>> (syntax-rules ()
>> ((assert test)
>> (if (not test) (assert-error (quote test))))))
>The assert family is certainly a classic macro application, although
>having it print something like
> ASSERTION FAILURE: (> x 0).
>is pretty darn useless, since there might be lots of occurrences of
>(assert (> x 0)) in the code, and also that assertion failures often
>indicate an error in the caller rather than where the assert statement
>is. I'd much rather rely on the stack traceback with line numbers and
>function arguments that any good interpreted language gives you. So I
>claim this sort of pun is pretty useless.
So give the assert macro an argument that includes a message
string. You're just complaining about the (overly) simple
example that Alan gave, not about macros.
>Scott McKay <email@example.com> writes:
>> ;; Defines the (empty) element <hd:image-server/>
>> (define-element image-server ()
>> (show-string *image-server-url*))
>These sort of function-plus-linkage definitions are a reasonable use of
>macros. But, having to write something like:
>(defun image-server ...)
>(register-tag 'image-server image-server)
>really isn't that bad. Especially since you often want several different
>tags to share code, or you often want to add a bunch of similar tags:
>(dolist color '(red green blue)
> (register-tag color (lambda () (format t "<font color=~A>" color))))
If you reduce every problem to its simplest case, of course
you don't need anything powerful to solve the problem. I can
use exactly your methods to reconstruct Guy Steele's recent
parodies. And honestly, why do we need anything more abstract
than C structs and functions anyway?
I think if you took the time to fully elaborate the contents
of the 'define-element' and 'define-body-element', you would
quickly see that a single call to 'register-tag' is not nearly
all that needs to be done. As I said, the macro also arranges
to handle body and attribute parsing, and a couple of other
I also mentioned that adding persistence adjectives to class-defining
syntax is an even more fertile place to look for examples of where
you can really win big, where "win big" is measured by "how little
do you have to perturb the existing language to add this useful
and powerful new feature".