为什么此发电机实现在球拍中不起作用?
我正在尝试使用 call/cc
在球拍中实现发电机,如果我在repl中使用它,我已经有了
(define (foo2)
(define (g abort)
(define-syntax-rule
(yield x)
(call/cc (lambda (k)
(set! g k)
(abort x))))
(yield 'foo)
(yield 'bar)
(yield 'tar)
(abort 'end))
(thunk (call/cc g)))
代码
foo.rkt> (define g (foo2))
foo.rkt> (g)
'foo
foo.rkt> (g)
'bar
foo.rkt> (g)
'tar
foo.rkt> (g)
'end
foo.rkt> (g)
'end
foo.rkt>
此 列表,它挂起,我不知道发生了什么事
foo.rkt> (define g (foo2))
foo.rkt> (list (g) (g) (g))
;; prompt is not released
?我的发电机实施是错误的?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
什么是
(列表(g)(g)(g))
?好吧,基本上是在CPS中:您要替换
g&
,但是你们所有人yarts
共享相同的初始中止
continuation> g1
,您将永远无法连续g2
,因为每次中止
被称为您运行持续g1
。如果您逐步完成,您会注意到此延续将得到所有收益率值,但最终将调用中止
。即使您删除了最后一个通话,它也会始终在表达式中拨打第二个(g)
。它有助于知道
呼叫/CC&
是:现在,CPS中的
g
看起来像这样。请注意,中止
是其中的免费变量,即使您替换g&
作为修复程序,它们也将是相同的,我想您需要将设置为
>的设置。 G
。例如。而不是(set!gk)
也许是这样的:然后列表表达式按预期工作。为什么它在repl中工作的原因是继续提示。
What is
(list (g) (g) (g))
? Well it is basically this in CPS:You are replacing
g&
, but all of youyield
share the same initialabort
which is continuationg1
and you will never ever reach continuationg2
since every timeabort
is called you run continuationg1
. If you step through you'll notice that this continuation gets fed all the yield values but eventually it callsabort
. Even if you remove the last call it will always call the second(g)
in your expression.It helps to know
call/cc&
is this:Now
g
in CPS would look something like this. Notice theabort
are free variables in there and they will be the same even if you replaceg&
As a fix I guess you need to control what you set as
g
. Eg. instead of(set! g k)
something like this perhaps:Then the list expression works as expected. Why it worked in the REPL is due to continuation prompts.