<div dir="ltr">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).<div><br></div>
<div>Robby</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Nov 20, 2013 at 12:53 AM, Emina Torlak <span dir="ltr"><<a href="mailto:emina@eecs.berkeley.edu" target="_blank">emina@eecs.berkeley.edu</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">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:<div>
<br></div><div><div>
<font face="courier new, monospace">(define (cell init)</font></div><div><font face="courier new, monospace"> (let ([x init])</font></div><div><font face="courier new, monospace"> (case-lambda</font></div><div><font face="courier new, monospace"> [() x]</font></div>
<div><font face="courier new, monospace"> [(v) (set! x v)])))</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">(define foo (cell 0))</font></div><div><font face="courier new, monospace">(define bar (cell 1))</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">> (foo 2)</font></div><div><font face="courier new, monospace">> (bar 3)</font></div><div><font face="courier new, monospace">> (foo)</font></div>
<div><font face="courier new, monospace">2</font></div><div><font face="courier new, monospace">> (bar)</font></div><div><font face="courier new, monospace">3</font></div><div><font face="courier new, monospace">> (dict->list global)</font></div>
</div><div><font face="courier new, monospace">'((.#<syntax:18:17 x> . 3))</font><br></div><div><br></div><div>In the above scenario, I need the <font face="courier new, monospace">global</font> map to contain two bindings: one for the location of 'foo.x' and the other for the location of 'bar.x.' </div>
<span class="HOEnZb"><font color="#888888">
<div><br></div><div>Emina</div><div><br></div></font></span></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Nov 19, 2013 at 10:31 PM, Sam Tobin-Hochstadt <span dir="ltr"><<a href="mailto:samth@cs.indiana.edu" target="_blank">samth@cs.indiana.edu</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I think that just identifiers and `free-id-table`s should work here.<br>
Here's your example:<br>
<br>
#lang racket<br>
<br>
(require syntax/id-table (only-in racket [set! #%set!]))<br>
<br>
(define global (make-free-id-table))<br>
<br>
(define-syntax-rule (location-of id) #'id)<br>
<br>
(define-syntax-rule (set! id expr)<br>
(let ([v expr])<br>
(dict-set! global (location-of id) v)<br>
(#%set! id v)))<br>
<br>
> (define x 1)<br>
> (set! x 2)<br>
> (set! x 3)<br>
> (for/list ([(k v) (in-dict global)]) (list k v))<br>
'((.#<syntax:4:8 x> 3))<br>
<br>
Also at <a href="https://gist.github.com/samth/7558673" target="_blank">https://gist.github.com/samth/7558673</a><br>
<br>
Sam<br>
<div><div><br>
On Mon, Nov 18, 2013 at 2:43 PM, Emina Torlak <<a href="mailto:emina@eecs.berkeley.edu" target="_blank">emina@eecs.berkeley.edu</a>> wrote:<br>
> I'm using Racket to implement a language for which I need to track state<br>
> updates---in particular, variable mutation using set!. For example,<br>
> consider this module definition:<br>
><br>
> #lang racket<br>
><br>
> (require (only-in racket [set! #%set!]))<br>
><br>
> (define global (make-hash))<br>
><br>
> (define-syntax-rule (location-of id)<br>
> (#%variable-reference id)) ; doesn't quite do the right thing<br>
><br>
> (define-syntax-rule (set! id expr)<br>
> (let ([val expr])<br>
> (hash-set! global (location-of id) val)<br>
> (#%set! id val)))<br>
><br>
> When I evaluate the following sequence of forms against the above<br>
> definition, I would like the global hash map to contain just one binding<br>
> that maps the location for 'x' to the value 2. With the above<br>
> implementation I get two map entries, since variable-reference doesn't quite<br>
> do what I hoped it did:<br>
><br>
>> (define x 0)<br>
>> (set! x 1)<br>
>> (set! x 2)<br>
>> x<br>
> 2<br>
>> global<br>
> '#hash((#<variable-reference> . 1) (#<variable-reference> . 2))<br>
><br>
> Is there another construct in Racket that I could use for this purpose? If<br>
> not, can something like this be implemented and how much work would it<br>
> entail?<br>
><br>
> I have a purely macro-based solution that works for the most part, but it's<br>
> fragile and there are corner cases for which it is just wrong. So, before<br>
> trying to fix that, I was wondering if there is a nicer way to solve it by<br>
> somehow getting handles for variable locations that are comparable using eq?<br>
> or equal?<br>
><br>
> Thanks!<br>
><br>
> Emina<br>
><br>
><br>
</div></div>> ____________________<br>
> Racket Users list:<br>
> <a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
><br>
</blockquote></div><br></div>
</div></div><br>____________________<br>
Racket Users list:<br>
<a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
<br></blockquote></div><br></div>