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

时间:2019-05-26 18:03:41

标签: module scheme read-eval-print-loop lexical-scope guile

按照以下步骤考虑模块:

(define-module (test test)
  #:export     (proc1 proc2 proc3))

(define proc1
  (let ((module (current-module)))
    (lambda ()
      (format #t "~s\n" module))))

(define proc2
  (lambda ()
    (let ((module (current-module)))
      (format #t "~s\n" module))))

(define (proc3)
  (let ((module (current-module)))
    (format #t "~s\n" 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符号才绑定到定义过程的模块。

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

2 个答案:

答案 0 :(得分:2)

proc1仅在定义过程时对(current-module)进行一次评估,因此lambda内部的module在定义时绑定到该值。

proc2在调用该过程之前不会求值(current-module)
它还会每次对其进行评估。
它等效于proc3

答案 1 :(得分:1)

仅proc1会打印测试模块。

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

在REPL中执行proc1,2,3 try(当前模块)。它将使事情变得更清楚。

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