浏览 8509 次
锁定老帖子 主题:(鳞爪琐思)为什么fp不需要yield?
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2005-05-30
它让iterator的实现者用最直观简单的internal iterator的方式书写,而同时仍然允许iterator的使用者用external iterator的方式去用它。 然而,函数式语言对此却不感冒。是函数式语言抱残守缺吗? 其实。函数式语言拥有比yield更一般更强大的continuation机制。 让我们再回忆一下internal iterator的几点缺陷: 1。回调的定义语法繁琐。(java恶心的anonymous class语法) 2。无法在循环中间return, break。 对1,大多函数式语言都支持lamda语法,比anonymous class简单多了,比如: foreach arr \i-> print i 这句等价于: for(i:arr);{System.out.println(i);;} \i ->print i代表一个匿名函数,它对任何参数都直接打印。 等同于ruby的block语法: |i|{print i} 而且,很多函数式语言还支持currying。这样,我可以直接写: foreach arr print 对2,continuation提供了立即跳出循环的方法。 callcc \exit->body 在body中,任何地方如果调用了exit,程序流程都会立即跳出body,回到callcc这个地方来。 比如,对下面的循环: boolean find(arr, k, max, def);{ foreach(i:arr);{ if(i<0); return false; else if(i==k); return true; else if(i>max); break; } return def; } 我们有两个跳出点: return 跳出find函数;break跳出foreach循环。 对等的用fp的continuation,代码可以写成这样: find(arr, k, max, def); = callcc \return -> callcc \loopreturn -> let break = loopreturn false; continue = true; foreach arr \i-> if i<0 then return false else if i==k then return true else if i>max then break else continue; in return def 我们只要在可能跳出的程序点加上一句 callcc \label->后面的代码就可以通过调用label函数来跳到这点。 如此,利用callcc函数+internal iterator,我们就可以轻松达到yield要达到的目的,自然也就没有必要单独引入一个yield关键字和一套额外的语义了。 你可能会说:这不就是goto嘛! 其实,上面演示的,是只向循环外跳转的continuation,也是最简单的一类continuation。(jaskell就只支持这种continuation)。 这种continuation还是更象break和return。 当然,一些语言的continuation确实可以做很多非常复杂难解变态的事情(比如scheme),此时,滥用continuation只怕真的不会比滥用goto好多少。 不过,无可否认, 这种continuation的强大程度也是goto望尘莫及的。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2006-09-25
为什么只有 Ruby?
http://www.nirvanastudio.org/java/why-java-and-almost-every-other-programming-language-sucks.html |
|
返回顶楼 | |
发表时间:2006-09-26
然。
JavaScript就可以写出这类强大的效果……有兴趣者请参阅Selenium-Core,HtmlTestRunner类。 |
|
返回顶楼 | |
发表时间:2006-09-26
JS 可以实现callcc ? cool.
我下载了selenium core, 但是没有找到 HtmlTestRunner这个类。文件名是什么? 好吧,广告的目的达到了,现在可以告诉咱了吧? 找到了,是selenium-testrunner.js这个文件。 里面倒是有很多事件机制的代码。文件太长了,没看到contiunaiton的部分。 和Timer相关?一步一步驱动? Rhino Javascript (Java server side JS)支持contiunation。著名的cocoon就是用的这个。 browser JS continuation 也找到几个。 http://chumsley.org/jwacs/ The function_continuation statement The new function_continuation statement takes no arguments and returns the return continuation for the current function. For example, in the following code: function sleep(msec) { var k = function_continuation; setTimeout(function() { resume k; }, msec); suspend; } http://neilmix.com/narrativejs/doc/index.html |
|
返回顶楼 | |
发表时间:2006-09-26
也说不上callcc,只不过是JavaScript不能阻塞调用,要用timer来模拟,我们把它重构成比较漂亮的、一堆lambda传来传去的样子了。
|
|
返回顶楼 | |
发表时间:2006-09-27
有人用JS实现了符合R5RS标准的Scheme,call/cc不在话下吧
http://www.bluishcoder.co.nz/jsscheme/ buaawhl 写道 JS 可以实现callcc ? cool.
我下载了selenium core, 但是没有找到 HtmlTestRunner这个类。文件名是什么? 好吧,广告的目的达到了,现在可以告诉咱了吧? 找到了,是selenium-testrunner.js这个文件。 里面倒是有很多事件机制的代码。文件太长了,没看到contiunaiton的部分。 和Timer相关?一步一步驱动? Rhino Javascript (Java server side JS)支持contiunation。著名的cocoon就是用的这个。 browser JS continuation 也找到几个。 http://chumsley.org/jwacs/ The function_continuation statement The new function_continuation statement takes no arguments and returns the return continuation for the current function. For example, in the following code: function sleep(msec) { var k = function_continuation; setTimeout(function() { resume k; }, msec); suspend; } http://neilmix.com/narrativejs/doc/index.html |
|
返回顶楼 | |
发表时间:2006-09-27
ShiningRay 写道 有人用JS实现了符合R5RS标准的Scheme,call/cc不在话下吧 http://www.bluishcoder.co.nz/jsscheme/ First-class continuations with even dynamic-wind 这个很牛啊。说明是GPL的,但是找不到source。 有一个download link,是混淆过的JQuery.js。 |
|
返回顶楼 | |
发表时间:2006-09-27
call/cc实际上是个lambda,只要支持lambda的语言都能搞call/cc
|
|
返回顶楼 | |
发表时间:2006-09-29
buaawhl 写道 ShiningRay 写道 有人用JS实现了符合R5RS标准的Scheme,call/cc不在话下吧 http://www.bluishcoder.co.nz/jsscheme/ First-class continuations with even dynamic-wind 这个很牛啊。说明是GPL的,但是找不到source。 有一个download link,是混淆过的JQuery.js。 evidently you haven't read every line on that page. note the last line: Original Original by Alex Yakovlev from http://alex.ability.ru/scheme.html. it's implemented in 2000+ lines of js. |
|
返回顶楼 | |
发表时间:2006-09-29
right. http://www.bluishcoder.co.nz/jsscheme/ http://alex.ability.ru/scheme.html 这两个link, view source,就可以看到了。thanks. theCallCC = TopEnv['call-with-current-continuation'] = function(list,state) { state.ready = false; return callF( list.car, new Pair( state.cc.clone(), theNil ), state ); } |
|
返回顶楼 | |