d11*_*wtq 8 scheme functional-programming seasoned-schemer
关于letcc这一点的一些问题在The Seasoned Schemer中使用.
(define (intersect-all sets)
(letcc hop
(letrec
((A (lambda (sets)
(cond
((null? (car sets)) (hop '())
((null? (cdr sets)) (car sets))
(else
(intersect (car sets)
(A (cdr sets)))))))
; definition of intersect removed for brevity
(cond
((null? sets) '())
(else (A sets))))))
Run Code Online (Sandbox Code Playgroud)
我想我明白什么letcc实现,那就是基本类似catch,并throw在红宝石(貌似CL),这基本上意味着代码的整体结构可以通过调用任何指定的剪短letcc的.这感觉就像是最"功能性"的事情我已经在这短短的系列丛书遇到,这让我觉得有点犹豫,使用它,因为我想学习的好功能的风格.我只是误解letcc,还是它不是一个真正的函数式编程概念,只是为了提高性能?整个想法,我可以在一些例程的中间,然后突然到达代码中的另一个点感觉有点错误...就像滥用Java中的try/catch程序流程一样.
letcc 似乎不存在于我在OS X中安装的guile版本(1.8.7).我应该在guile中寻找另一个名称吗?
如果我letcc通过将它与Java中的try/catch进行比较来误解,或者在ruby中捕获/抛出(这不是异常处理,只是为了清楚,对于非rubyists),它在功能级别上究竟是如何工作的?它可以用更长,更复杂的方式表达,这让我觉得它毕竟是功能性的吗?
Eli*_*lay 11
"功能性"有几个含义,但没有任何流行的含义以任何方式与延续相矛盾.但是它们可能被滥用来创建难以阅读的代码.它们不是可以"滥用程序流"的工具- 它们是程序流工具.
在那里帮不了你.我知道Guile有一个半新近的延续,但我不知道事情的立场.它应该肯定有call-with-current-continuation,通常也在更友好的名称下call/cc,并且let/cc是一个可以构建的简单宏call/cc.
我可以告诉你,在Racket中有一个let/cc内置的和一堆其他内置在同一个系列中,另外还有一个完整的各种控制操作符库(带有大量的引用列表).
简单的使用let/cc确实类似于捕获/抛出的东西 - 更具体地说,这种延续通常被称为"逃避延续"(或有时"向上").这是您在该代码中使用的那种用法,通常用于实现a abort或a return.
但是Scheme中的延续是可以在任何地方使用的东西.有关显示此差异的非常简单的示例,请尝试以下操作:
(define (foo f) (f 100))
(let/cc k (+ (foo k) "junk") (more junk))
Run Code Online (Sandbox Code Playgroud)最后,如果你想阅读更多关于continuation的内容,你可以看到PLAI的相关部分,还有Matthew Might写的更简单的示例概述,你可以看到我写的一些基于PLAI的类注释,一些受后一篇文章启发的例子.