提问人:Trenton J 提问时间:3/21/2023 最后编辑:Will NessTrenton J 更新时间:4/1/2023 访问量:112
请解释“thunks”的编码。
Please explain coding for "thunks."
问:
我有我从书中尝试过的以下代码。
;pg 51 "The Scheme Programming Language" by R. Kent Dybvig"
(define lazy
(lambda (t)
;so lazy accepts argument t
(let ([val #f] [flag #f])
;isn't val <- #f (& flag <- #f) ea. time,
;and if so, how is other val returned?
(lambda () ;operates on no arguments
(if (not flag)
(begin (set! val (t))
; if flag == #f (as it initially is)
; then val <- t, the argument to lazy
(set! flag #t)))
val)))) ; returns val regardless,
; and executes it?
(define p
(lazy (lambda ()
;so this lambda w/o arguments gets
; passed to t above
(display "sig1 ")
;these 2 lines are printed only
; first time, but why?
(display "sig2 ")
"sig 3" )))
;this seems to get printed every time
;as if it were the only argument in p
;to pass to t
; invoke with (p)
; "When passed a thunk t (a zero-argument procedure),
; lazy returns a new thunk that, when invoked,
; returns the value of invoking t."
; That is way too convoluted to easily understand!
; What is the new thunk - a copy of the one
; sent to it, in this case (p)?
; Is this sort of a call-back function?
它根据书有效,但我无法理解它。请参阅上面的评论和问题。我可能在评论中假设了不正确的事情。此外,我来自 C 背景,并试图了解这种新的编程方案方式。我在这里是一个非常初学者。谢谢!
答:
0赞
Nathan Hughes
3/21/2023
#1
这个 thunk 背后的想法是,除非您需要它,否则它不会调用它,并且它存储调用包装的 lambda 的值,以便 lambda 只被调用一次。您可以将 thunk 传递到函数中,而不必担心如果该函数调用过多会浪费资源。
是的,lazy 是一个回调函数,它接受函数 t 作为参数并返回调用 t 的函数。
局部变量标志用于跟踪是否已调用传入的 lambda。即使在声明局部变量的函数完成后,lambda 仍会保留对局部变量的引用,因为它是一个闭包。闭包在程序中传递时会携带它们被声明的环境,因此 flag 和 val 实际上成为闭包的私有变量。
lazy 返回的 lambda 不是任何东西的副本,而是一个正在创建的新对象,它可以多次调用,但要确保传入的 lambda t 只调用一次。p 将保存通过调用 lazy 传入 lambda 返回的函数,将调用包装成 display 并返回“sig 3”,该函数在 lazy 的定义中作为 t 传入。
评论