[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