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?
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With