Use before definition

John Cowan tells the tale of Professor Simpleton and Dr Hardcase to try to convince us that allowing uses of macros before their definitions in Scheme is wrong.

For me, this seems like a case of ‘this feature would let people write bad code’, to which Scheme’s answer is always clear: they shouldn’t write bad code, then; we’re not in the business of stopping bad programmers by restricting all programmers’ access to the most powerful abstractions. Nonetheless, it does need to argued that a feature is powerful or useful to justify its existence: we don’t accept things which can only be used to make a mess.

It’s perfectly cromulent in mathematics (and in some programming languages) to write a definition by stating a complete form using some abstractions and follow it with the word ‘where’ and an explanation of those abstractions also in standard notation. Scheme, unlike languages such as Haskell, lacks an explicit ‘where’ clause, but it’s just as good to do this without it:

(define (my-high-level-proc x)
  (%my-internal-syntax x () some-more-info ...))
(define-syntax %my-internal-syntax
  (lambda (stx)
    (syntax-case ...)))

Totally forbidding use before definition disallows even this reasonable ordering.

More generally, John’s analogy falls down because the macro definition as we explain it to a Scheme compiler is not necessarily the macro definition as we explain it to humans reading the program. If my library uses my own special frob macro throughout, and I explain what it does in a comment at the top of the code, Professor Simpleton has no reason to complain. As long as it is clear to a human what the macro does, I can put the (perhaps quite subtle or otherwise involved) implementation of the expansion right at the end of the file. The compiler need not care either way.

In fact, Professor Simpleton’s problem becomes more relevant in another case we actually explicitly want to support in Scheme: when someone has written their own alternative prelude whose core constructs don’t resemble those of Scheme at all. (At least one notable Lisper has their own prelude for CL such that their code, by their own admission, ‘no longer looks like CL’. I can’t remember who it was, but they said it on their personal blog, I think.)

See also: Naming things.