3

Consider a module with the following procedures:

(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)))

I was under the impression that all these were equivalent, but they are not.

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

Only in proc1 the module symbol inside the lambda expression is bound to the module were the procedure is defined.

Can somebody explain this? Does it mean I always have to use the first form, if I want to create a closure?

Will Ness
  • 70,110
  • 9
  • 98
  • 181
Ernest A
  • 7,526
  • 8
  • 34
  • 40

2 Answers2

3

proc1 evaluates (current-module) only once, when the procedure is defined, so module inside the lambda is bound to that value at definition-time.

proc2 does not evaluate (current-module) until the procedure is called.
It also evaluates it every time.
It is equivalent to proc3.

molbdnilo
  • 64,751
  • 3
  • 43
  • 82
2

Only proc1 prints the test module.

proc2 and proc3 are equivalent, they print the REPL module.

As well as executing proc1,2,3 try (current-module) in the REPL. It will make things clearer.

For proc1 (current-module) is executed at the time the procedure is defined, for proc2 and proc2 (current-module) is executed at the time the procedure is called.

river
  • 1,028
  • 6
  • 16