[plt-scheme] Semantics of let

From: Greg Woodhouse (gregory.woodhouse at sbcglobal.net)
Date: Thu Feb 23 17:22:47 EST 2006

I guess I pretty much knew this was going to happen before I tried it,
but in the meta-circular interpreter I've been writing, let pretty much
behaves like letrec. For example,

> (run)
>> (let ((f (lambda (x) (if (= x 0) 1 (* x (f (- x 1))))))) (f 3))

(Run just starts the read/eval/print loop.)

What I do is maintain a list of "frames" (actually hash tables), and
with each let, I add a new frame to the front of the list and add the
binging there. When looking up a value, I start at the head of the
list, and go on to the next frame if I don't find a binding. Similarly,
to apply a lambda expression, I create a new frame and enter bindings
for the formals and evaluate the body.

Okay, so that's not Scheme. In Scheme, f would be unbound when I
attempt the recursive call, and so I've been thinking about how best to
emulate Scheme semantics. My hunch is that the recursive ressolution
process is the issue: that the lambda expression would be bound to a
name in a single hash table that has no link to a "parent". But it
would seem that x would have to be bound within a stack frame,
suggesting that functions and variables live in different namespaces. I
put everything in one namespace (environment, but tag builtins and
lambda abstractions so that they can be handled appropriately.)

So, what am I asking? Well, I've kind of been making this up as I go
along, and now see that what I have is a different language. Does R5RS
(say) specify what should be happening here? Where do I look?

Gregory Woodhouse  <gregory.woodhouse at sbcglobal.net>
"All truth passes through three stages: First, it is ridiculed.
Second, it is violently opposed. Third, it is accepted as
being self-evident."
--Arthur Schopenhauer

Posted on the users mailing list.