让 Ran 在 lambda 表达式内部和外部之间的区别



考虑一个具有以下过程的模块:

(define-module (test test)
  #:export     (proc1 proc2 proc3))
(define proc1
  (let ((module (current-module)))
    (lambda ()
      (format #t "~sn" module))))
(define proc2
  (lambda ()
    (let ((module (current-module)))
      (format #t "~sn" module))))
(define (proc3)
  (let ((module (current-module)))
    (format #t "~sn" module)))

我的印象是所有这些都是等价的,但事实并非如此。

scheme@(guile-user)> (use-modules (test test))
scheme@(guile-user)> (proc1)
#<directory (test test) 562a062152d0>
$1 = #t
scheme@(guile-user)> (proc2)
#<directory (guile-user) 562a05b8bbd0>
$2 = #t
scheme@(guile-user)> (proc3)
#<directory (guile-user) 562a05b8bbd0>
$3 = #t

只有在proc1 lambda 表达式中的module符号绑定到模块时,才定义了该过程。

有人可以解释一下吗?这是否意味着如果我想创建一个闭包,我总是必须使用第一种形式?

proc1在定义过程时仅计算一次(current-module),因此 lambda 内部module在定义时绑定到该值。

在调用该过程之前,proc2不会评估(current-module)
它还每次都会对其进行评估。
相当于proc3

只有 proc1 打印测试模块。

proc2 和 proc3 是等效的,它们打印 REPL 模块。

以及在 REPL 中执行 proc1,2,3 try(当前模块(。它会让事情更清楚。

对于 proc1(当前模块(在定义过程时执行

,对于 proc2 和 proc2(当前模块(在调用过程时执行。

相关内容

最新更新