I'm very new to lisp and recently i discovered the thin that I don't开发者_如何学Python understand.
This code works:
(define (f x) (define a x) (define (b) a) (b))
And this doesn't:
(define (f x) (define a x) (define b a) b)
Why?
In kawa interpeter it works In Guile it doesn't, because this code
(define (f x) (define a x) (define b a) b)
is expand to
(define (f x) (letrec ((a x) (b a)) b))
And you can't access to a
before I's assign. letrec
won't work for non-function definitions, for example:
(letrec ((x 5)
(y x))
y)
You can use let*
insted
(define (f x) (let* ((a x) (b a)) b))
In this code
(define (f x) (define a x) (define (b) a) (b))
In procedure b you access a varible when it's already defined.
You should look up discussions about letrec*
-- some implementations use it as a more permissive version of the stricter letrec
, which results in the difference you see.
You might be seeing the change in behavior between the R5RS and R6RS standards. One of the changes in R6RS is "Internal definitions are now defined in terms of letrec*
."
In R5RS, the internal define
s are completely equivalent to a letrec
. In particular, the section on internal definitions says that "Just as for the equivalent letrec
expression, it must be possible to evaluate each <expression>
of every internal definition in a <body>
without assigning or referring to the value of any <variable>
being defined."
However, in R6RS, internal define
s are equivalent to a letrec*
. And, as you would expect, letrec*
allows you to refer to the value of preceding variables in the intializer for later variables.
精彩评论