[racket] free-id-table. Is it a bug?

From: Jens Axel Søgaard (jensaxel at soegaard.net)
Date: Thu Apr 3 11:28:03 EDT 2014

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


Posted on the users mailing list.