[plt-scheme] syntax and promises and possibly phases
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])
(begin
(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
john