Saturday, September 25, 2010

老文: A gentle interpretation of continuation

Ivan: 写完后想完善, 但是后来一直没有继续. 在邮箱躺了一年后... 决定还是抛弃了...

------

Continuation 顾名思义,可以理解为继续计算。
我觉得这个概念可能是FP里最难理解的了。
很多文章介绍scheme的call/cc 我都沒看懂。
這兩天看到newsmth有人推薦看看python的yield時,
結合這篇文章,好像懂了點:
http://ttsiodras.googlepages.com/yield.html

总的来说,它给人的感觉有点像memoization,又有点像call back。
用我自己的话概括,就是能把当前计算的状态保存下来,下次要用到的时候可以接着计算。
如果单单只是保存一个状态,那似乎没多大作用,但是如果能保存很多个,那就似乎很方便了。

可枚举的对象可以看做应用场景之一。
正如文章里面提到的,考虑做一个Permutation Generator,
更抽象一點,考慮一個遞歸樹,我們在這個遞歸樹里搜索某些符合條件的節點(solution).
放到permutation generator里面来说,就是搜索叶节点。
但是我们希望搜索到一个solution时能"暂停"搜索,先返回到调用的程序里(callee)里
对当前得到的solution做一些操作,迟点可以回去继续搜索。
因为在递归树里面搜索是递归的,所以用正常的编程思路实现似乎有点困难。
而如果引入了continuation的概念,如果我们可以把当前的计算状态作为一个对象保存下来,
迟点回去继续,那就非常自然方便了。
给出一个伪代码如下:

searcher.initialize()
while(searcher.next()){
   // do some other...
}

這是一段很典型的constraint-programming style的代碼。
next()  的实现,就可以使用continuation的机制完成。

現在的程序设计语言基本上是一系列的函数调用过程,
因此整个程序的执行可以看做是在一个栈里面进行的操作,
当前的例程位于栈顶top,而调用它的例程位于top-1的位置。
而在支持continuation的PL里,程序的执行过程更像一棵树。
当执行到某个节点时,如果调用了一个例程,则从这个节点生成一个子节点并进入,
这个节点作为子节点的父节点存在;
返回时返回到父节点,但子节点仍然存在,以后有需要时可以重新进入到这个子节点继续计算。
此时程序的执行就不是结构化的了,所以说continuation有点类似goto。

No comments: