[racket] set!: eval-ing to lvalues

From: Sean Kanaley (skanaley at gmail.com)
Date: Thu Jun 6 16:12:30 EDT 2013

Hello all,

I was curious why Scheme and now Racket does not inherently support a
generic set!.  I found an SRFI
http://srfi.schemers.org/srfi-17/srfi-17.htmlthat 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.

Here's the critical pieces:

1. setting
"update" is what changes the store
set! is of course a clause within eval
the last parameter to eval in the first line says don't fetch

[(set! addr-x x) (match-let* ([(v*s addr s) (eval addr-x e s #f)]
                                  [(v*s v s) (eval x e s)])
                        (update addr v s))]

2. evaluating symbols (another clause)
the symbol only returns its address with fetching off

[(sym y) (let* ([addr (lookup y e)]
                    [val (if fetch? (fetch addr s) addr)])
               (v*s val s))]

3. the "built-in" (part of environment) vector-ref called vec@
"fetch?" will be false if (vec@ ...) is the first argument to set!
"a" is the base address of the vector

(define (vec at -f e s fetch? v i)
...unimportant stuff...
        (let ([val (if fetch? (fetch (+ a i) s) (+ a i))])
          (v*s val s)))))

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

(vector-set! v i (add1 (vector-ref v i))
(inc! (vec@ v i))

I assume this has already been thought of and therefore discarded, but why?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20130606/32c2e53d/attachment-0001.html>

Posted on the users mailing list.