[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
macros vs. blocks
Paul Graham writes:
>
> If anyone has good examples of macros that *can't* be expressed with
> a convenient notation for closures, it would be interesting to see
> them. My Smalltalk-hacking friend Trevor Blackwell has often
> claimed that macros were unnecessary if you had blocks, so as long
> as we're on the subject, please send him (and ll1-discuss) your
> counterexamples. (The point is not mainly to quiet Trevor, of
> course, but to understand macros better.)
List comprehensions make a good example. Consider the following
bit of Haskell code:
[ (a, b) | a <- as, b <- bs, a < b ]
This takes two lists 'as' and 'bs', and returns all of the elements of
their cartesian eproduct such that each a < b. In regular Scheme, this
would look like:
(foldl (lambda (a acc)
(foldl (lambda (b acc)
(if (< a b)
(cons (pair a b) acc)
acc))
acc
bs))
'()
as)
For concreteness, I'll use a Smalltalk-like syntax for blocks -- '[a b
c: <expr>]' for '(lambda (a b c) <expr>)'. So in Scheme + blocks, this
would look like:
(foldl [a acc:
(foldl [b acc: (if (< a b) (cons (pair a b) acc) acc)] acc bs)]
'()
as)
Block notation *is* much more compact than using lambda, but list
comprehensions are more readable still -- and I'd want to define them
with macros, rather than as a baked-in language feature.
--
Neel Krishnaswami
neelk@alum.mit.edu