[英]Can the function argument to `call/cc` equivalently either invoke the continuation or return without invoking the continuation?
方案编程语言说
Scheme允许使用过程
call/cc
捕获任何表达式的延续。 必须为call/cc
传递一个参数为p
的过程。call/cc
构造当前延续的具体表示并将其传递给p
。 连续本身由过程k
。 每次将k
应用于值时,它将值返回到call/cc
应用程序的继续。 从本质上讲,该值成为call/cc
应用程序的值。 如果p
不调用k
而返回,则该过程返回的值将成为call/cc
应用程序的值。
就用call/cc
而言,以下两种定义p
等价的方式是:
p
返回而不调用k
, p
用其否则返回值调用k
? 我不确定如何定义call/cc
。 请问call/cc
曾经直接调用延续k
,除了通过间接p
调用k
?
call/cc
和p
都不调用延续k
很好吗?
是, (call/cc (lambda (k) 1)) <=> (call/cc (lambda (k) (k 1)))
。 您可以通过使用延续传递样式转换来证明这一点。
关键部分是call/cc
的CPS形式为(lambda (k) (lambda (f) ((fk) k)))
。 这两个函数的CPS形式为(lambda (c) (lambda (k) (c 1)))
和(lambda (c) (lambda (k) (k 1)))
。 代入和简化,两者都导致(lambda (k) (k 1))
。
我非常喜欢定界延续,因为它们具有:
(reset (1 + (shift (lambda (f) f)))) <=> (lambda (v) (+ 1 v))
这也可以通过代数证明。
要解决后续问题的详细信息,我们可以使用来自http://matt.might.net/articles/cps-conversion/的代码scheme-cps-convert.rkt
> (T-c '(call/cc (λ (k) 1)) 'halt)
'((λ (f cc) (f (λ (x _) (cc x)) cc)) (λ (k $k2873) ($k2873 1)) halt)
> (T-c '(call/cc (λ (k) (k 1))) 'halt)
'((λ (f cc) (f (λ (x _) (cc x)) cc)) (λ (k $k2940) (k 1 $k2940)) halt)
简化第一个表达式:
((λ (f cc) (f (λ (x _) (cc x)) cc)) (λ (k $k2873) ($k2873 1)) halt)
= ((λ (k $k2873) ($k2873 1)) (λ (x _) (halt x)) halt)
= (halt 1)
第二个
((λ (f cc) (f (λ (x _) (cc x)) cc)) (λ (k $k2940) (k 1 $k2940)) halt)
= ((λ (k $k2940) (k 1 $k2940)) (λ (x _) (halt x)) halt)
= ((λ (x _) (halt x)) 1 halt)
= (halt 1)
证明它们相等,因此在该位置使用k或不使用k都没有区别。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.