[racket] obtaining the location of an identifier

From: Emina Torlak (emina at eecs.berkeley.edu)
Date: Wed Nov 20 01:53:00 EST 2013

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
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20131119/bf1a80ae/attachment-0001.html>

Posted on the users mailing list.