What should (foo) return?
MIT/GNU-Scheme, SCM, GSI, Mzscheme, and Scheme48 return 10.
Is this behavior guaranteed by R5RS?
This should be guaranteed by the static lexical scoping rules for
"let". When bindings are created by "let", a new environment is
created, the bindings are evaluated one by one, and after all
evaluation is complete, all the bindings are added to the new
environment. This means that the "foo" created by the "let" is bound
to a lambda expression of zero args, returning the constant integer 9.
It is only AFTER this that the lambda expression is bound to the
identifier "foo" in the top level environment by the second "define".
When (foo) is applied, the lambda is executed "in the environment
within which it was defined", which has "foo" bound to a lambda of
zero args returning the constant 9. This definition of "foo"
effectively "shadows" the definition of foo created by the second
define.
Hope this helps.
Brian C. Barnes
I think it's guaranteed by R5RS section 5.2.1 [1].
Was this a trick question?
Will
> Aubrey Jaffer wrote:
> > (define foo (lambda () 9))
> > (define foo (let ((foo foo)) (lambda () (+ 1 (foo)))))
> >
> > What should (foo) return?
> >
> > MIT/GNU-Scheme, SCM, GSI, Mzscheme, and Scheme48 return 10.
> >
> > Is this behavior guaranteed by R5RS?
>
> I think it's guaranteed by R5RS section 5.2.1 [1].
> Was this a trick question?
No. Kawa chokes on this code. I wanted to make sure I wasn't
misreading R5RS.
> Will
>
> [1] http://www-swiss.ai.mit.edu/~jaffer/r5rs_7.html#SEC45
This example exposes a big difference between top-level definitions and
internal ones. As an internal definition, this wrapping of FOO is
illegal because it would be equivalent to:
(define foo (lambda () 9))
(define (bar)
(letrec ((foo (let ((foo foo)) (lambda () (+ 1 (foo))))))
(foo)))
At the time that LET is entered, it is not allowed to reference the
value of FOO.
Where did you get the idea that there was any similarity between the
semantics of top-level defines and the semantics of internal defines?
In R5RS top-level:
* You can have defines and define-syntaxes
* Evaluation is sequential
* You can have multiple definitions of the same variable.
* Continuations have no clear semantics.
* You can mix definitions and expressions.
In R5RS internal bodies:
* You can only have defines.
* Evaluation is in any order (letrec semantics).
* You cannot have multiple bindings of the same variable.
* Continuation have clear semantics.
* All definitions must come before all expressions.
* You must have at least one expression.
Aziz,,,
> On Mar 28, 4:29 pm, Aubrey Jaffer <a...@alum.mit.edu> wrote:
> > This example exposes a big difference between top-level definitions and
> > internal ones.
>
> Where did you get the idea that there was any similarity between the
> semantics of top-level defines and the semantics of internal defines?
In the r6rs discussions, the letrec* semantics have been touted as
making internal defines more like top-level defines. But I think the
letrec* version is also in error:
(define (bar)
(letrec* ((foo (let ((foo foo)) (lambda () (+ 1 (foo))))))
(foo)))
R6RS top-level is an R6RS library in disguise. It has letrec*
semantics which means that you cannot do:
(define (foo) 5)
(define foo (let ((foo foo)) (lambda () (+ (foo) 1))))
at the R6RS top-level just like how you cannot do it internally.
R6RS has no "repl" semantics, sorry.
Aziz,,,
If and when the R6RS is ratified, we'll need a raft
of SRFIs to deal with things omitted from the R6RS
(or, in a few cases, botched). One of those will
be a SRFI describing the semantics of a top level
for interactive development; authors of textbooks
will be in dire need of this.
It seems to me that the obvious thing for this SRFI
to do is to keep the R5RS semantics, including load,
while allowing or requiring a few changes that would
improve compatibility with R6RS programs: case
sensitivity, lexical changes, internal definitions
have letrec* semantics, let-syntax and letrec-syntax
do not introduce a new scope, and maybe a few others
I've forgotten. Agreement on a standard way to load
R6RS libraries into an interactive top level would
also be desirable.
Will
Excellent idea.
Aziz,,,