[plt-scheme] suggestions on generators.ss

From: Dave Herman (dherman at ccs.neu.edu)
Date: Fri Apr 7 00:14:57 EDT 2006

> I know bad things will probably happen if I lexically bind yield:
> 
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>> (define-generator (evens n)
>     (let yield ((n n))
>       (yield n)
>       (yield (+ n 2))))
>> (define f (evens 0))
>> (f)
> ;; hilarity ensues
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

I don't think that's the problem with unhygienic macros. If I'm not 
mistaken, introducing a new binding for yield just shadows it as always. 
The only reason the above code is broken is because it's stupid; you 
can't use the same name in the same scope to refer to two different 
bindings. No semantics in the world will do-what-you-mean.

The real hilarity will ensue when you try to write other macros that 
expand into uses of define-generator.

> I think a solution would be to somehow restrict 'yield as a real keyword
> in the context of a define-generator (though I'm not quite sure how to do
> this yet).  But perhaps the non-hygienic macro is just a bad idea?

Usually.

Okay, unhygienic macros can be reasonable as a user convenience.  But I 
use the rule of thumb that whenever you define an unhygienic macro, you 
should define an alternative, hygienic version of the macro. This allows 
other people to write macros that expand into a use of your macro.

For example, you could have two versions of your form:

     ;; hygienic version
     (define-generator* (evens n) my-name-for-yield
       etc etc
       (my-name-for-yield n)
       etc etc)

     ;; unhygienic version
     (define-generator (evens n)
       etc etc
       (yield n)
       etc etc)

You can implement the definition of define-generator in terms of 
define-generator* to avoid duplication.

Dave


Posted on the users mailing list.