[plt-scheme] Reproviding "else"

From: Robby Findler (robby at eecs.northwestern.edu)
Date: Mon Mar 16 21:30:38 EDT 2009

Ryan, this is a very nice message and, if you have the energy, I bet
it would fit nicely into the guide somewhere.


On Mon, Mar 16, 2009 at 3:42 PM, Ryan Culpepper <ryanc at ccs.neu.edu> wrote:
> On Mar 16, 2009, at 3:19 PM, Neil Toronto wrote:
>> The attached example language module "cond-lang.ss" implements a very
>> small language, reproviding a few bits of Scheme and providing a new cond
>> macro. When "cond-test.ss" uses that macro, the compiler gives an error:
>>   compile: unbound identifier (and no #%top syntax transformer
>>   is bound) in: else
>> It's not just else, though: you can't use as a literal any name that's in
>> scope in the macro definition. (For example, the compiler gives the same
>> error if else is changed to foobar and foobar is defined at the top level.)
>> Well, you can, but you have to provide that name as well as the macro. If
>> you can't safely do that, there are uglier ways.
>> Why are literals with syntax properties used for matching?
> Rather, the literals are matched by *binding*, not by their symbolic name.
> The macro is looking for the 'else' in scope in "cond-lang.ss", which is the
> 'else' from the 'scheme' language. But the 'else' used in "cond-test.ss" is
> something else, so the macro interprets it as a 'text-expr^', and it
> eventually gets flagged as an unbound variable. The solution, as you remark,
> is to provide 'else'.
> So, why are literals matched by binding, rather than by symbolic name?
> It's a matter of syntax design. Your macro analyzes its clauses and tries to
> distinguish between an else-clause and an ordinary test-clause. In order for
> the macro to distinguish the two kinds of clauses, they should not overlap.
> That is, there shouldn't be any valid test-clause that is also an
> else-clause. They have the same shape, so the thing that really
> distinguishes them is the first part: There shouldn't be any valid test
> expression that is also the else keyword.
> If keywords were recognized by just their spelling, then there would be an
> overlap between the else keyword and a local variable called 'else' in the
> "cond-test.ss" module. Instead, the 'else' keyword is defined as a macro
> that always raises an error when used as an expression. That makes 'else'
> effectively not a valid expression, so there's no overlap.
> The alternative would be to say that a test-expression is almost like an
> ordinary expression, except that it can't be a variable named 'else'. This
> might seem innocuous---who uses 'else' as a variable name? But it's a hidden
> danger and, at the same time, unnecessary clutter in the meaning of
> 'new:cond'. Better to *reserve* the word right off the bat and learn of
> conflicts as early as possible.
> There are other advantages that come from treating keywords as bindings,
> including the ability to rename them when you import them into a module, the
> ability to keep some keywords internal (just don't export them), and the
> ability to get nice documentation links for keywords via Scribble :)
> Ryan
>> #lang scheme
>> (define-syntax new:cond
>>  (syntax-rules (else)
>>   [(_)  (void)]
>>   [(_ [else else-expr])  else-expr]
>>   [(_ [test-expr^ then-expr^] [test-expr then-expr] ...)
>>    (if test-expr^
>>        then-expr^
>>        (new:cond [test-expr then-expr] ...))]))
>> (provide
>> #%module-begin #%datum #%app if define
>> (rename-out [new:cond cond])
>> < quote)
>> #lang s-exp "cond-lang.ss"
>> (define (classify-age n)
>>  (cond [(< n 0) 'twinkle-in-daddys-eye]
>>       [(< n 10) 'precocious]
>>       [(< n 20) 'cheeky]
>>       [(< n 30) 'spunky]
>>       [(< n 50) 'not-dead-yet]
>>       [(< n 120) 'cobol-programming]
>>       [else  'holy-fate-worse-than-death-batman!]))
>> (classify-age 121)
>> _________________________________________________
>>  For list-related administrative tasks:
>>  http://list.cs.brown.edu/mailman/listinfo/plt-scheme
> _________________________________________________
>  For list-related administrative tasks:
>  http://list.cs.brown.edu/mailman/listinfo/plt-scheme

Posted on the users mailing list.