[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: macros vs. blocks
Trevor Blackwell writes:
> John Clements <clements@brinckerhoff.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).
>
> 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.
When you're building fancy binding constructs using higher order
functions (such as with continuation-passing or monadic code), then
the syntactic burden of lambdas -- even in a lightweight form like the
block notation -- can rapidly become unbearable. The difference
between:
(bind (g w)
(lambda (x)
(bind (h w x)
(lambda (y)
(bind (i w x y)
(lambda (z)
(return z)))))))
and
do x <- (g w)
y <- (h w x)
z <- (i w x y)
return z
is pretty striking, no? A reason you'd want such a thing is it can
make a nonstandard binding construct (eg for a logic variable) look
natural, without having to expose all of the machinery to the user.
--
Neel Krishnaswami
neelk@alum.mit.edu