<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 "real" setter (and so needing a special setter for every data type. What is the disadvantage of simply changing eval to take a "fetch?" 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'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's the critical pieces:<br><br><div>1. setting<br></div><div>"update" 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'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 "built-in" (part of environment) vector-ref called vec@<br></div>"fetch?" will be false if (vec@ ...) is the first argument to set!<br></div>"a" 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'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>