[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