[racket] free-id-table. Is it a bug?
Thanks for the counterexample.
/Jens Axel
2014-04-03 15:46 GMT+02:00 Ryan Culpepper <ryanc at ccs.neu.edu>:
> On 04/03/2014 05:51 AM, Jens Axel Søgaard wrote:
>>
>> It seems the table needs to be created with #:phase -1.
>>
>> Since syntax-case uses a fender expression I added
>> a begin in save-and-define, but it works either way
>> (because free-id-table-set! returns a non-false value).
>>
>> #lang racket
>> (require (for-syntax syntax/id-table))
>>
>> (define-for-syntax table (make-free-id-table #:phase -1))
>>
>> (define-syntax (save-and-define stx)
>> (syntax-case stx ()
>> [(_ ID)
>> (begin
>> (free-id-table-set! table #'ID 1)
>> #'(define ID 1))]))
>>
>> (define-syntax (load stx)
>> (syntax-case stx ()
>> [(_ ID2)
>> (if (free-id-table-ref table #'ID2 #f)
>> #''ok
>> #''different)]))
>>
>> (module+ test
>> (save-and-define a)
>> (displayln (load a)))
>
>
> The code above is not correct. Here's a counterexample:
>
> (require (for-template (only-in racket/base [lambda x] [lambda y])))
> ;; x and y mean the same thing at phase -1
> (save-and-define x)
> (load y) ;; => 'ok, but should be 'different
>
> The #:phase -1 means compare the for-template bindings, which is not what
> you want. You want to compare the normal (phase-0) bindings, because the
> identifiers are defined using plain old 'define'. See my other message for a
> fix.
>
> As an aside, you should rarely-to-never use a constant phase number like -1.
> Use (sub1 (syntax-local-phase-level)) instead. That way your code will still
> work if required at a shifted phase (eg, for-syntax).
>
> Ryan
>
>
>
> ____________________
> Racket Users list:
> http://lists.racket-lang.org/users
--
--
Jens Axel Søgaard