[racket] obtaining the location of an identifier

From: Robby Findler (robby at eecs.northwestern.edu)
Date: Wed Nov 20 08:19:35 EST 2013

I didn't try it, but you it might work to use local-expand and then find
all the binding forms and then rewrite them to use boxes (or some other
source of uniqueness you might have around).

Robby


On Wed, Nov 20, 2013 at 12:53 AM, Emina Torlak <emina at eecs.berkeley.edu>wrote:

> This is how my solution currently works, but unfortunately, it's not quite
> right.  Here is a small example that demonstrates why, assuming the
> implementation based on free-id-table:
>
> (define (cell init)
>   (let ([x init])
>     (case-lambda
>       [() x]
>       [(v) (set! x v)])))
>
> (define foo (cell 0))
> (define bar (cell 1))
>
> > (foo 2)
> > (bar 3)
> > (foo)
> 2
> > (bar)
> 3
> > (dict->list global)
> '((.#<syntax:18:17 x> . 3))
>
> In the above scenario, I need the global map to contain two bindings:
>  one for the location of 'foo.x' and the other for the location of 'bar.x.'
>
>
> Emina
>
>
>
> On Tue, Nov 19, 2013 at 10:31 PM, Sam Tobin-Hochstadt <
> samth at cs.indiana.edu> wrote:
>
>> I think that just identifiers and `free-id-table`s should work here.
>> Here's your example:
>>
>> #lang racket
>>
>> (require syntax/id-table (only-in racket [set! #%set!]))
>>
>> (define global (make-free-id-table))
>>
>> (define-syntax-rule (location-of id) #'id)
>>
>> (define-syntax-rule (set! id expr)
>>   (let ([v expr])
>>     (dict-set! global (location-of id) v)
>>     (#%set! id v)))
>>
>> > (define x 1)
>> > (set! x 2)
>> > (set! x 3)
>> > (for/list ([(k v) (in-dict global)]) (list k v))
>> '((.#<syntax:4:8 x> 3))
>>
>> Also at https://gist.github.com/samth/7558673
>>
>> Sam
>>
>> On Mon, Nov 18, 2013 at 2:43 PM, Emina Torlak <emina at eecs.berkeley.edu>
>> wrote:
>> > I'm using Racket to implement a language for which I need to track state
>> > updates---in particular, variable mutation using set!.  For example,
>> > consider this module definition:
>> >
>> > #lang racket
>> >
>> > (require (only-in racket [set! #%set!]))
>> >
>> > (define global (make-hash))
>> >
>> > (define-syntax-rule (location-of id)
>> >   (#%variable-reference id)) ; doesn't quite do the right thing
>> >
>> > (define-syntax-rule (set! id expr)
>> >   (let ([val expr])
>> >     (hash-set! global (location-of id) val)
>> >     (#%set! id val)))
>> >
>> > When I evaluate the following sequence of forms against the above
>> > definition, I would like the global hash map to contain just one binding
>> > that maps the location for 'x' to the value 2.  With the above
>> > implementation I get two map entries, since variable-reference doesn't
>> quite
>> > do what I hoped it did:
>> >
>> >> (define x 0)
>> >> (set! x 1)
>> >> (set! x 2)
>> >> x
>> > 2
>> >> global
>> > '#hash((#<variable-reference> . 1) (#<variable-reference> . 2))
>> >
>> > Is there another construct in Racket that I could use for this purpose?
>>  If
>> > not, can something like this be implemented and how much work would it
>> > entail?
>> >
>> > I have a purely macro-based solution that works for the most part, but
>> it's
>> > fragile and there are corner cases for which it is just wrong.  So,
>> before
>> > trying to fix that, I was wondering if there is a nicer way to solve it
>> by
>> > somehow getting handles for variable locations that are comparable
>> using eq?
>> > or equal?
>> >
>> > Thanks!
>> >
>> > Emina
>> >
>> >
>> > ____________________
>> >   Racket Users list:
>> >   http://lists.racket-lang.org/users
>> >
>>
>
>
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20131120/54260533/attachment-0001.html>

Posted on the users mailing list.