[plt-scheme] syntax and promises and possibly phases

From: John Clements (clements at brinckerhoff.org)
Date: Mon May 19 15:04:46 EDT 2003

On Monday, May 19, 2003, at 02:09  PM, Matthew Flatt wrote:

>   For list-related administrative tasks:
>   http://list.cs.brown.edu/mailman/listinfo/plt-scheme
> At Sun, 18 May 2003 14:00:41 -0400, "Neil W. Van Dyke" wrote:
>> I now have to admit that I was trying to use a concrete example to 
>> ask a
>> more general question about syntax extensions that cache values.
>> So I'm also curious if there's a way to solve this problem using a
>> hygienic macro, without using a table.  Intuition says there should be
>> an easy way.
>> (I asked on plt-scheme list before comp.lang.scheme, since the answer
>> might be sensitive to the trickiness of evaluation phases, and 
>> MzScheme
>> seems to know phase separation well.)
> You're poking at the edges of the phase problem, where it's not yet
> right in MzScheme, and where I think we need one more piece to make it
> right.
> Here's one way to do what you want, at least for now. It exploits a
> kind of hole in MzScheme:
>   (define-syntax remember
>     (syntax-rules ()
>       [(_ expr)
>        (let ([b #&#f])
>          (begin
>            (unless (unbox b)
>              (set-box! b (list expr)))
>            (car (unbox b))))]))
>   (define (f x) (remember x))
>   (define (g x) (remember x))
> Everytime you call `f', the result is the argument provided to `f' for
> its very first call. Ditto for `g', but `g' is independent of `f'.
> The `remember' macro exploits an as-yet-untamed phase: the time when
> run-time values are generated for syntactic constants. If you evaluate
> the expressions above directly, this generation happens when each
> definition is compiled. If you compile the code to .zo, it happens at
> `read' time for the compiled code.
> If you put the code in a module, then every instance of the module
> (independent of its phase) shares the same pair of mutable boxes for
> `f' and `g'. That's the most obvious way that this is a hole in the
> enforcement of phases.

I'm guessing that I'm confused here, but can't we achieve the same 
result with 3D code?  Even in a module? Is this an instance of the same 
thing?  Or does 3D code just break all the rules?

(module stx-test mzscheme

   (define-syntax (remember stx)
     (syntax-case stx ()
       [(_ expr)
        (let ([b (box #f)])
          #`(let ([b #,b])
                (unless (unbox b)
                  (set-box! b (list expr)))
                (car (unbox b)))))]))

   (define (f x) (remember x))

   (define (g x) (remember x))

   (display (equal? (list (f 3)
                 (g 9)
                 (f 4)
                 (g 10))
           `(3 9 3 9)))

=> #t


Posted on the users mailing list.