Skip to content

Anaphoric Macros

Does the convenience that anaphoric macros provide justify breaking hygiene? In that chapter of On Lisp, the author stated that:

This chapter will show that variable capture can also be used constructively. There are some useful macros which couldn’t be written without it.

My evaluation of that claim is that while the former is true, anaphoric macros are not evidence of such a case as they only save you a variable binding. The latter claim is interesting because it begs the question of whether or not they should be written as macros at all. It made me wonder how anaphoric macros might look in Scheme, how they might look as functions, and whether one is clearly superior to the other.

I wrote two versions of aif, the first is a macro (m-aif) and the second is a function (f-aif). Both provide the same functionality albeit with a different mechanism for implementation and syntax for application:

m-aif

(define-syntax m-aif
  (λ (stx)
    (syntax-case stx ()
      ((_ test-form then-form)
       (syntax (_ test-form then-form void)))
      ((_ test-form then-form else-form)
       (with-syntax ((it (syntax-local-introduce (syntax it))))
         (syntax
          (let ((it test-form))
            (if it
                then-form
                else-form))))))))

f-aif

(define f-aif
  (λ (test-form then-form . else-form)
    (let ((it (test-form)))
      (if it
          (then-form it)
          (unless (null? else-form)
            ((car else-form)))))))

The difference between utilizing the two versions becomes a matter of syntactic preference:

m-aif

(m-aif (identity 10)
       (display (* it 23)))

f-aif

(f-aif (λ () (identity 10))
       (λ (it) (display (* it 23))))

Which do you like better?

It should be an easy decision; with f-aif you get the desired functionality without breaking hygiene, albeit at the “cost” forcing the user to utilize lambda expressions.

In practice, requiring the use of lambda expressions is not an egregious demand of the user; instead, it is a pleasure. lambda is a special thing. The functionality that it provides is often more than enough to implement functionality that may initially appear to require macros (hygienic or not).

Macros are often times clearly the only, and the best, solution. This time isn’t one of them.

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*