<div dir="ltr"><div><div><div><div><div>Hello all,<br><br></div>I was curious why Scheme and now Racket does not inherently support a generic set!.  I found an SRFI <a href="http://srfi.schemers.org/srfi-17/srfi-17.html">http://srfi.schemers.org/srfi-17/srfi-17.html</a> that suggests a generic method solution requiring a lookup for the &quot;real&quot; setter (and so needing a special setter for every data type.  What is the disadvantage of simply changing eval to take a &quot;fetch?&quot; parameter that decides whether to ultimately resolve addresses to values?  Then set! is evaluated with this as #f and can operate on whatever that address is.  I have implemented this in a toy interpreter with the bare minimum of forms plus vectors to test.  The vector-ref type of function gets applied as usual to the vector and index arguments, except that if it&#39;s within a set! as the left argument where the fetch? is #f and the final fetching of the address given by vector-ref never happens.<br>
<br></div>Here&#39;s the critical pieces:<br><br><div>1. setting<br></div><div>&quot;update&quot; is what changes the store<br></div>set! is of course a clause within eval<br></div><div>the last parameter to eval in the first line says don&#39;t fetch<br>
</div><div><br>[(set! addr-x x) (match-let* ([(v*s addr s) (eval addr-x e s #f)]<br>                                  [(v*s v s) (eval x e s)])<br>                        (update addr v s))]<br><br><div>2. evaluating symbols (another clause)<br>
</div><div>the symbol only returns its address with fetching off<br></div><div><br>[(sym y) (let* ([addr (lookup y e)]<br>                    [val (if fetch? (fetch addr s) addr)])<br>               (v*s val s))]<br></div>
<br></div>3. the &quot;built-in&quot; (part of environment) vector-ref called vec@<br></div>&quot;fetch?&quot; will be false if (vec@ ...) is the first argument to set!<br></div>&quot;a&quot; is the base address of the vector<br>
<div><div><br><div><div>(define (vec@-f e s fetch? v i)<br></div><div>...unimportant stuff...<br></div><div>        (let ([val (if fetch? (fetch (+ a i) s) (+ a i))])<br>          (v*s val s)))))<br><br></div><div>So long as all built-in types have this conditional fetcher, then every user type built on top of them won&#39;t need a special setter.  And since this would work just as well for inc! types funtions, from now on<br>
<br>(vector-set! v i (add1 (vector-ref v i))<br></div><div>is<br></div><div>(inc! (vec@ v i))<br></div><div><br></div><div>I assume this has already been thought of and therefore discarded, but why?<br> </div></div></div>
</div></div>