<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
Thanks for the explanation. I suspected it was for efficiency
reasons, but as I've never implemented a "real" scheme, I don't know
the trade off. I wonder how bad it is. Way back, they invented
lisp. Then they said it was too slow for real stuff. Now they say
other languages are too weak for real stuff, and lisp's relatively
little slowness is made up for by its power. And here we are,
saying a powerful feature would slow it down!<br>
<br>
Is it 2x, 3x, 4x, 10x, infinityx slower to implement some kind of
lvalue system? And wouldn't that system be necessary only in code
that uses the mutation?<br>
<br>
<div class="moz-cite-prefix">On 06/09/2013 08:18 AM, Carl Eastlund
wrote:<br>
</div>
<blockquote
cite="mid:CAEOPtY3WjAFvJketQjW=Baz8A07iyk06ap4q4a5hc0rA5+Kf=A@mail.gmail.com"
type="cite">
<div dir="ltr">
<div>Sean,<br>
<br>
</div>
Not every Scheme uses an interpreter with an eval function as
its primary method of execution, or even at all. Racket uses a
bytecode interpreter and a JIT native-code compiler; the eval
function simply triggers compilation to bytecode. These give a
great deal more efficiency than running via eval, and supporting
multiple modes of execution would be significantly more
expensive. Evaluating to values by default, rather than to
addresses, also gives the compiler a great deal of flexibility.
It doesn't need to keep track of the addresses where it found
things and refer to them there in case they are about to be
mutated; once they have been "found" via evaluation, they can be
copied to register and the original address can be forgotten, if
that's most expedient. I'm not a compiler implementer myself,
so I'm sure others can probably give more specific details. In
the meantime, I hope this explanation is helpful.<br>
<div class="gmail_extra"><br clear="all">
<div>Carl Eastlund</div>
<br>
<div class="gmail_quote">On Thu, Jun 6, 2013 at 4:12 PM, Sean
Kanaley <span dir="ltr"><<a moz-do-not-send="true"
href="mailto:skanaley@gmail.com" target="_blank">skanaley@gmail.com</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">
<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 moz-do-not-send="true"
href="http://srfi.schemers.org/srfi-17/srfi-17.html"
target="_blank">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>
<br>
____________________<br>
Racket Users list:<br>
<a moz-do-not-send="true"
href="http://lists.racket-lang.org/users"
target="_blank">http://lists.racket-lang.org/users</a><br>
<br>
</blockquote>
</div>
<br>
</div>
</div>
</blockquote>
<br>
</body>
</html>