关于计划的小问题

时间:2010-09-14 09:56:04

标签: scheme

我对lisp很新,最近我发现了一些我不理解的薄片。

此代码有效:

(define (f x) (define a x) (define (b) a) (b))

这不是:

(define (f x) (define a x) (define b a) b)

为什么?

3 个答案:

答案 0 :(得分:2)

在kawa interpeter中它起作用 在Guile它没有,因为 这段代码

(define (f x) (define a x) (define b a) b)

扩展为

(define (f x) (letrec ((a x) (b a)) b))

在我分配之前,您无法访问aletrec不适用于非功能定义,例如:

(letrec ((x 5)
         (y x))
     y)

您可以使用let* insted

(define (f x) (let* ((a x) (b a)) b))

在此代码中

(define (f x) (define a x) (define (b) a) (b))

在程序b中,您可以在已经定义的情况下访问变量。

答案 1 :(得分:2)

您应该查看有关letrec*的讨论 - 有些实现会将其用作更严格letrec的更宽松版本,这会导致您看到的差异。

答案 2 :(得分:0)

您可能会看到R5RS和R6RS标准之间的行为变化。其中一个changes in R6RS是“内部定义现在按letrec*定义。”

在R5RS中,内部define s are completely equivalentletrec。特别是,关于内部定义的部分说“就像等效的letrec表达式一样,必须能够评估<expression>中每个内部定义的<body>而不分配或引用到被定义的任何<variable>的值。“

但是,在R6RS中,内部define s are equivalentletrec*。并且,正如您所期望的那样,letrec* allows您可以在初始化器中引用先前变量的值以用于以后的变量。