[racket] obtaining the location of an identifier
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>