Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

difference between let inside and outside a lambda expression

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?

like image 356
Ernest A Avatar asked May 09 '26 22:05

Ernest A


2 Answers

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.

like image 163
molbdnilo Avatar answered May 11 '26 16:05

molbdnilo


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.

like image 44
river Avatar answered May 11 '26 14:05

river