Scheme 这些过程如何能够访问在它们内部调用的另一个过程的输入值?

Scheme 这些过程如何能够访问在它们内部调用的另一个过程的输入值?,scheme,racket,Scheme,Racket,因此p-cons过程将x和y作为输入,并返回一个匿名过程,该过程将z作为输入(并记住x和y?) 我很难理解的是,当我在REPL中运行此命令时: (p-car (p-cons 1 2)) 它用p-cdr返回1和2,这是它们的目的。但是我不明白它们如何能够访问p-cons过程的值?有人能解释一下这是如何工作的吗?我可能没有完全理解什么? 以下是程序: (define (p-cons x y) (lambda (z) (z x y))) (define (p-car proc

因此p-cons过程将x和y作为输入,并返回一个匿名过程,该过程将z作为输入(并记住x和y?) 我很难理解的是,当我在REPL中运行此命令时:

(p-car (p-cons 1 2))
它用p-cdr返回1和2,这是它们的目的。但是我不明白它们如何能够访问p-cons过程的值?有人能解释一下这是如何工作的吗?我可能没有完全理解什么? 以下是程序:

 (define (p-cons x y)
      (lambda (z) (z x y)))

    (define (p-car proc)
      (proc (lambda (x y) x)))

    (define (p-cdr proc)
      (proc (lambda (x y) y)))

计划程序是封闭的。它们可以引用定义过程的环境中的变量

当在闭包中引用变量时,当您离开定义它的范围时,它们不会被销毁。相反,他们将继续生活,直到关闭仍然存在

使用闭包的教科书示例是计数器:

<!-- language: scheme -->
(define (make-counter)
  (let ((x 0))
    (lambda ()
      (set! x (+ x 1))
      x)))

(define counter (make-counter))

(counter) => 1
(counter) => 2
(counter) => 3
(counter) => 4

(定义(生成计数器)
(let((x 0))
(lambda()
(集!x(+x1))
x) ))
(定义计数器(生成计数器))
(计数器)=>1
(计数器)=>2
(计数器)=>3
(计数器)=>4
这里,
(lambda()(set!x(+x 1))x
过程引用了定义它的环境中的
x
(即
x
来自
make counter
)。因此,即使
make counter
的执行已经完成,
x
变量仍然有效,因为它在过程
counter
中被引用


有关更多信息,请参阅问题(可能最相关的答案)。

计划程序是关闭的。它们可以引用定义过程的环境中的变量

当在闭包中引用变量时,当您离开定义它的范围时,它们不会被销毁。相反,他们将继续生活,直到关闭仍然存在

使用闭包的教科书示例是计数器:

<!-- language: scheme -->
(define (make-counter)
  (let ((x 0))
    (lambda ()
      (set! x (+ x 1))
      x)))

(define counter (make-counter))

(counter) => 1
(counter) => 2
(counter) => 3
(counter) => 4

(定义(生成计数器)
(let((x 0))
(lambda()
(集!x(+x1))
x) ))
(定义计数器(生成计数器))
(计数器)=>1
(计数器)=>2
(计数器)=>3
(计数器)=>4
这里,
(lambda()(set!x(+x 1))x
过程引用了定义它的环境中的
x
(即
x
来自
make counter
)。因此,即使
make counter
的执行已经完成,
x
变量仍然有效,因为它在过程
counter
中被引用


有关更多信息,请参阅问题(可能最相关的答案)。

要了解为什么
1
2
没有丢失,您可以按以下步骤执行表达式:

(p-car (p-cons 1 2))
=> (p-car (lambda (z) (z 1 2)))
=> ((lambda (z) (z 1 2)) (lambda (x y) x))
=> ((lambda (x y) x) 1 2)
=> 1
(p-cons12)
实质上是生成过程:
(lambda(z)(z12))
。您可以将任何函数
f
传递到此过程,它将返回
(f 1 2)
。例如:

((lambda (z) (z 1 2)) +)                  ; => 3
((lambda (z) (z 1 2)) (lambda (x y) x))   ; => 1 
((lambda (z) (z 1 2)) (lambda (x y) y))   ; => 2

要查看
1
2
没有丢失的原因,可以按如下方式单步执行表达式:

(p-car (p-cons 1 2))
=> (p-car (lambda (z) (z 1 2)))
=> ((lambda (z) (z 1 2)) (lambda (x y) x))
=> ((lambda (x y) x) 1 2)
=> 1
(p-cons12)
实质上是生成过程:
(lambda(z)(z12))
。您可以将任何函数
f
传递到此过程,它将返回
(f 1 2)
。例如:

((lambda (z) (z 1 2)) +)                  ; => 3
((lambda (z) (z 1 2)) (lambda (x y) x))   ; => 1 
((lambda (z) (z 1 2)) (lambda (x y) y))   ; => 2