разница между внутри и снаружи лямбда-выражения - PullRequest
3 голосов
/ 26 мая 2019

Рассмотрим модуль со следующими процедурами:

(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 символ module внутри лямбда-выражения привязан к модулю, в котором определена процедура.

Может кто-нибудь объяснить это? Означает ли это, что я всегда должен использовать первую форму, если я хочу создать замыкание?

Ответы [ 2 ]

3 голосов
/ 26 мая 2019

proc1 оценивает (current-module) только один раз, когда процедура определена, поэтому module внутри лямбды привязывается к этому значению во время определения.

proc2 не оценивает (current-module) до тех пор, пока не будет вызвана процедура.
Он также оценивает его каждый раз.
Это эквивалентно proc3.

2 голосов
/ 26 мая 2019

Только proc1 печатает тестовый модуль.

proc2 и proc3 эквивалентны, они печатают модуль REPL.

Как и выполнение proc1,2,3 try (current-module) вРЕПЛ.Это прояснит ситуацию.

Для proc1 (current-module) выполняется во время определения процедуры, для proc2 и proc2 (current-module) выполняется во время вызова процедуры.

...