<div dir="ltr"><div>I tried playing with the ffi to get a variable location, as suggested on Rosetta Code:<br> <a href="http://rosettacode.org/wiki/Address_of_a_variable#Racket">http://rosettacode.org/wiki/Address_of_a_variable#Racket</a> <br>
<br>It also doesn't work for what you want...<br><br>Intuitively, there must be some way to suspend GC and get a hold of a stable pointer.  (It wouldn't be possible to call nontrivial C API's otherwise.  But I don't know Racket's FFI.)<br>
<br>Replacing cpointer->int with its correct definition (the integer cast of a pinned pointer) should make the following code work as intended.  <br><br>#lang racket<br>(require (only-in racket [set! #%set!]))<br>(require ffi/unsafe)<br>
 <br>(define-syntax-rule (ref v) (cast v _racket _gcpointer))<br>(define (cpointer->int v) (cast v _gcpointer _fixnum))<br>(define global (make-custom-hash ptr-equal? cpointer->int)) <br>(define (dump global)  (for/list (((k v) (in-dict global))) (cons (~a (cpointer->int k)) (~a v))))<br>
<br>(define-syntax-rule (set! id expr)<br>  (let ([val expr])<br>    (dict-set! global (ref (#%variable-reference id)) val)<br>    (#%set! id val)))<br><br>(define (test)<br>        (define x 0)<br>        (set! x 1)<br>        (set! x 2)<br>
        (dump global))<br><br><div><div><div class="gmail_extra">> (test)<br>'(("198044656" . "1") ("198055120" . "2"))<br><br><br></div><div class="gmail_extra">-Will<br><br>
<br></div><div class="gmail_extra"><div class="gmail_quote">On Wed, Nov 20, 2013 at 10:40 AM,  <span dir="ltr"><<a href="mailto:users-request@racket-lang.org" target="_blank">users-request@racket-lang.org</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Send users mailing list submissions to<br>
        <a href="mailto:users@racket-lang.org">users@racket-lang.org</a><br>
<br>
To subscribe or unsubscribe via the World Wide Web, visit<br>
        <a href="http://lists.racket-lang.org/users/listinfo" target="_blank">http://lists.racket-lang.org/users/listinfo</a><br>
or, via email, send a message with subject or body 'help' to<br>
        <a href="mailto:users-request@racket-lang.org">users-request@racket-lang.org</a><br>
<br>
You can reach the person managing the list at<br>
        <a href="mailto:users-owner@racket-lang.org">users-owner@racket-lang.org</a><br>
<br>
When replying, please edit your Subject line so it is more specific<br>
than "Re: Contents of users digest..."<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>Today's Topics:<br>
<br>
   1. Re: obtaining the location of an identifier (Robby Findler)<br>
   2. Re: obtaining the location of an identifier (Sam Tobin-Hochstadt)<br>
   3. Re: obtaining the location of an identifier (Emina Torlak)<br>
<br><br>---------- Forwarded message ----------<br>From: Robby Findler <<a href="mailto:robby@eecs.northwestern.edu">robby@eecs.northwestern.edu</a>><br>To: Emina Torlak <<a href="mailto:emina@eecs.berkeley.edu">emina@eecs.berkeley.edu</a>><br>
Cc: users <<a href="mailto:users@racket-lang.org">users@racket-lang.org</a>><br>Date: Wed, 20 Nov 2013 12:09:49 -0600<br>Subject: Re: [racket] obtaining the location of an identifier<br><div dir="ltr">You may be able to avoid some of those steps by rewriting the binding forms into macros that rewrite the uses. And it may be possible to use stop-lists in a good way to avoid having to actually write too much boilerplate for traversing expression forms that are irrelevant to you.<div>

<br></div><div>And depending on what your'e doing, you may even find it easier/better to write your own language that has its own bindings form directly (and expand into macros that rewrite the uses).</div><div><br></div>

<div>Sorry for the terse help. Good luck!<br><div><br></div><div>Robby</div></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Nov 20, 2013 at 11:35 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:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">I believe Robby's solution will work.  It's basically similar to what I had in mind, but I was hoping I'd be able to avoid it :)<div>

<br></div><div>The crux of the issue is the need for unique identifiers for variable locations.  I also track updates to vectors and structs, for example, and this is easy precisely because I can use their identities to compute the "location" of the update.  So, boxing values in "raw" variables will have the same effect.  </div>


<div><br></div><div>In terms of implementation, though, it'll be trickier.  As far as I can tell, this approach involves whole-module analysis and transformation:</div><div><br></div><div>* Expand the module completely.</div>


<div>* Find all uses of set! and collect their targets.</div><div>* Rewrite the def and all uses of target variables to perform auto boxing and unboxing.</div><div><br></div><div>If there are tricks/constructs that I should use for the above steps, I'd love to hear them.   Or, of course, if there is some way to obtain variable location identifiers from the runtime, that would be great to know as well.</div>

<span><font color="#888888">
<div><br></div><div>Emina</div><div><br></div><div><br></div><div><br></div></font></span></div><div><div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Nov 20, 2013 at 5:19 AM, Robby Findler <span dir="ltr"><<a href="mailto:robby@eecs.northwestern.edu" target="_blank">robby@eecs.northwestern.edu</a>></span> wrote:<br>


<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><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).<span><font color="#888888"><div>


<br></div>
<div>Robby</div></font></span></div><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:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);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><font color="#888888">
<div><br></div><div>Emina</div><div><br></div></font></span></div><div><div><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:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);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>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>
<br><br>---------- Forwarded message ----------<br>From: Sam Tobin-Hochstadt <<a href="mailto:samth@cs.indiana.edu">samth@cs.indiana.edu</a>><br>To: Emina Torlak <<a href="mailto:emina@eecs.berkeley.edu">emina@eecs.berkeley.edu</a>><br>
Cc: users <<a href="mailto:users@racket-lang.org">users@racket-lang.org</a>>, Robby Findler <<a href="mailto:robby@eecs.northwestern.edu">robby@eecs.northwestern.edu</a>><br>Date: Wed, 20 Nov 2013 13:28:59 -0500<br>
Subject: Re: [racket] obtaining the location of an identifier<br>Two things:<br>
<br>
- There's code here [1] to find all the mutated variables in a module.<br>
- Robby's later suggestion is great if you want to track _all_<br>
variables, not just ones that are targets of `set!`, since you'd<br>
basically change everything to a box.  Otherwise I think expand/parse<br>
is your only option.<br>
<br>
[1] <a href="https://github.com/plt/racket/blob/master/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/utils/mutated-vars.rkt" target="_blank">https://github.com/plt/racket/blob/master/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/utils/mutated-vars.rkt</a><br>

<br>
On Wed, Nov 20, 2013 at 12:35 PM, Emina Torlak <<a href="mailto:emina@eecs.berkeley.edu">emina@eecs.berkeley.edu</a>> wrote:<br>
> I believe Robby's solution will work.  It's basically similar to what I had<br>
> in mind, but I was hoping I'd be able to avoid it :)<br>
><br>
> The crux of the issue is the need for unique identifiers for variable<br>
> locations.  I also track updates to vectors and structs, for example, and<br>
> this is easy precisely because I can use their identities to compute the<br>
> "location" of the update.  So, boxing values in "raw" variables will have<br>
> the same effect.<br>
><br>
> In terms of implementation, though, it'll be trickier.  As far as I can<br>
> tell, this approach involves whole-module analysis and transformation:<br>
><br>
> * Expand the module completely.<br>
> * Find all uses of set! and collect their targets.<br>
> * Rewrite the def and all uses of target variables to perform auto boxing<br>
> and unboxing.<br>
><br>
> If there are tricks/constructs that I should use for the above steps, I'd<br>
> love to hear them.   Or, of course, if there is some way to obtain variable<br>
> location identifiers from the runtime, that would be great to know as well.<br>
><br>
> Emina<br>
><br>
><br>
><br>
><br>
><br>
> On Wed, Nov 20, 2013 at 5:19 AM, Robby Findler <<a href="mailto:robby@eecs.northwestern.edu">robby@eecs.northwestern.edu</a>><br>
> wrote:<br>
>><br>
>> I didn't try it, but you it might work to use local-expand and then find<br>
>> all the binding forms and then rewrite them to use boxes (or some other<br>
>> source of uniqueness you might have around).<br>
>><br>
>> Robby<br>
>><br>
>><br>
>> On Wed, Nov 20, 2013 at 12:53 AM, Emina Torlak <<a href="mailto:emina@eecs.berkeley.edu">emina@eecs.berkeley.edu</a>><br>
>> wrote:<br>
>>><br>
>>> This is how my solution currently works, but unfortunately, it's not<br>
>>> quite right.  Here is a small example that demonstrates why, assuming the<br>
>>> implementation based on free-id-table:<br>
>>><br>
>>> (define (cell init)<br>
>>>   (let ([x init])<br>
>>>     (case-lambda<br>
>>>       [() x]<br>
>>>       [(v) (set! x v)])))<br>
>>><br>
>>> (define foo (cell 0))<br>
>>> (define bar (cell 1))<br>
>>><br>
>>> > (foo 2)<br>
>>> > (bar 3)<br>
>>> > (foo)<br>
>>> 2<br>
>>> > (bar)<br>
>>> 3<br>
>>> > (dict->list global)<br>
>>> '((.#<syntax:18:17 x> . 3))<br>
>>><br>
>>> In the above scenario, I need the global map to contain two bindings:<br>
>>> one for the location of 'foo.x' and the other for the location of 'bar.x.'<br>
>>><br>
>>> Emina<br>
>>><br>
>>><br>
>>><br>
>>> On Tue, Nov 19, 2013 at 10:31 PM, Sam Tobin-Hochstadt<br>
>>> <<a href="mailto:samth@cs.indiana.edu">samth@cs.indiana.edu</a>> wrote:<br>
>>>><br>
>>>> 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>
>>>><br>
>>>> On Mon, Nov 18, 2013 at 2:43 PM, Emina Torlak <<a href="mailto:emina@eecs.berkeley.edu">emina@eecs.berkeley.edu</a>><br>
>>>> wrote:<br>
>>>> > I'm using Racket to implement a language for which I need to track<br>
>>>> > 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<br>
>>>> > 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<br>
>>>> > 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<br>
>>>> > 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<br>
>>>> > it's<br>
>>>> > fragile and there are corner cases for which it is just wrong.  So,<br>
>>>> > before<br>
>>>> > trying to fix that, I was wondering if there is a nicer way to solve<br>
>>>> > it by<br>
>>>> > somehow getting handles for variable locations that are comparable<br>
>>>> > using eq?<br>
>>>> > or equal?<br>
>>>> ><br>
>>>> > Thanks!<br>
>>>> ><br>
>>>> > Emina<br>
>>>> ><br>
>>>> ><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>
>>><br>
>>><br>
>>><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>
>><br>
><br>
<br>
<br><br>---------- Forwarded message ----------<br>From: Emina Torlak <<a href="mailto:emina@eecs.berkeley.edu">emina@eecs.berkeley.edu</a>><br>To: Sam Tobin-Hochstadt <<a href="mailto:samth@cs.indiana.edu">samth@cs.indiana.edu</a>><br>
Cc: users <<a href="mailto:users@racket-lang.org">users@racket-lang.org</a>>, Robby Findler <<a href="mailto:robby@eecs.northwestern.edu">robby@eecs.northwestern.edu</a>><br>Date: Wed, 20 Nov 2013 10:40:47 -0800<br>
Subject: Re: [racket] obtaining the location of an identifier<br><div dir="ltr">This is perfect.  I'm assuming that mutation is rare, so I'd like to restrict boxing only to mutated variables (the expand/parse option).  If I come up with something that can be nicely generalized or reused for other languages, I'll be sure to post it.<div>

<br></div><div>Thanks for all the help!  <br></div><div><br></div><div>Emina</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Nov 20, 2013 at 10:28 AM, 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:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Two things:<br>
<br>
- There's code here [1] to find all the mutated variables in a module.<br>
- Robby's later suggestion is great if you want to track _all_<br>
variables, not just ones that are targets of `set!`, since you'd<br>
basically change everything to a box.  Otherwise I think expand/parse<br>
is your only option.<br>
<br>
[1] <a href="https://github.com/plt/racket/blob/master/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/utils/mutated-vars.rkt" target="_blank">https://github.com/plt/racket/blob/master/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/utils/mutated-vars.rkt</a><br>


<div><div><br>
On Wed, Nov 20, 2013 at 12:35 PM, Emina Torlak <<a href="mailto:emina@eecs.berkeley.edu" target="_blank">emina@eecs.berkeley.edu</a>> wrote:<br>
> I believe Robby's solution will work.  It's basically similar to what I had<br>
> in mind, but I was hoping I'd be able to avoid it :)<br>
><br>
> The crux of the issue is the need for unique identifiers for variable<br>
> locations.  I also track updates to vectors and structs, for example, and<br>
> this is easy precisely because I can use their identities to compute the<br>
> "location" of the update.  So, boxing values in "raw" variables will have<br>
> the same effect.<br>
><br>
> In terms of implementation, though, it'll be trickier.  As far as I can<br>
> tell, this approach involves whole-module analysis and transformation:<br>
><br>
> * Expand the module completely.<br>
> * Find all uses of set! and collect their targets.<br>
> * Rewrite the def and all uses of target variables to perform auto boxing<br>
> and unboxing.<br>
><br>
> If there are tricks/constructs that I should use for the above steps, I'd<br>
> love to hear them.   Or, of course, if there is some way to obtain variable<br>
> location identifiers from the runtime, that would be great to know as well.<br>
><br>
> Emina<br>
><br>
><br>
><br>
><br>
><br>
> On Wed, Nov 20, 2013 at 5:19 AM, Robby Findler <<a href="mailto:robby@eecs.northwestern.edu" target="_blank">robby@eecs.northwestern.edu</a>><br>
> wrote:<br>
>><br>
>> I didn't try it, but you it might work to use local-expand and then find<br>
>> all the binding forms and then rewrite them to use boxes (or some other<br>
>> source of uniqueness you might have around).<br>
>><br>
>> Robby<br>
>><br>
>><br>
>> On Wed, Nov 20, 2013 at 12:53 AM, Emina Torlak <<a href="mailto:emina@eecs.berkeley.edu" target="_blank">emina@eecs.berkeley.edu</a>><br>
>> wrote:<br>
>>><br>
>>> This is how my solution currently works, but unfortunately, it's not<br>
>>> quite right.  Here is a small example that demonstrates why, assuming the<br>
>>> implementation based on free-id-table:<br>
>>><br>
>>> (define (cell init)<br>
>>>   (let ([x init])<br>
>>>     (case-lambda<br>
>>>       [() x]<br>
>>>       [(v) (set! x v)])))<br>
>>><br>
>>> (define foo (cell 0))<br>
>>> (define bar (cell 1))<br>
>>><br>
>>> > (foo 2)<br>
>>> > (bar 3)<br>
>>> > (foo)<br>
>>> 2<br>
>>> > (bar)<br>
>>> 3<br>
>>> > (dict->list global)<br>
>>> '((.#<syntax:18:17 x> . 3))<br>
>>><br>
>>> In the above scenario, I need the global map to contain two bindings:<br>
>>> one for the location of 'foo.x' and the other for the location of 'bar.x.'<br>
>>><br>
>>> Emina<br>
>>><br>
>>><br>
>>><br>
>>> On Tue, Nov 19, 2013 at 10:31 PM, Sam Tobin-Hochstadt<br>
>>> <<a href="mailto:samth@cs.indiana.edu" target="_blank">samth@cs.indiana.edu</a>> wrote:<br>
>>>><br>
>>>> 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>
>>>><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>><br>
>>>> wrote:<br>
>>>> > I'm using Racket to implement a language for which I need to track<br>
>>>> > 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<br>
>>>> > 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<br>
>>>> > 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<br>
>>>> > 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<br>
>>>> > it's<br>
>>>> > fragile and there are corner cases for which it is just wrong.  So,<br>
>>>> > before<br>
>>>> > trying to fix that, I was wondering if there is a nicer way to solve<br>
>>>> > it by<br>
>>>> > somehow getting handles for variable locations that are comparable<br>
>>>> > using eq?<br>
>>>> > or equal?<br>
>>>> ><br>
>>>> > Thanks!<br>
>>>> ><br>
>>>> > Emina<br>
>>>> ><br>
>>>> ><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>
>>><br>
>>><br>
>>><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>
>><br>
><br>
</div></div></blockquote></div><br></div>
<br></blockquote></div><br></div></div></div></div></div>