免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4845 | 回复: 0
打印 上一主题 下一主题

纯粹的和不纯粹的函数式编程 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-02-18 13:40 |只看该作者 |倒序浏览
纯粹的和不纯粹的函数式编程





一个纯粹的函数是指没有任何副作用的函数。副作用其实是指函数在其内部保存某种隐藏的状态。C中,strlen是一个纯函数的很好的例子。如果你对同样的字符串多次调用strlen,它总是返回同样的长度值。strlen的输出(长度)仅由其输入(字符串)决定,不依赖于任何其他东西。但不幸的是,C中很多函数都是不纯的。例如,malloc——如果你用同样的数字对其进行调用,它肯定都不会返回同样的指针给你。malloc当然还依赖于很多隐藏的内部状态(堆上分配的对象、使用的分配方法、从操作系统抓取页,等等)。

ML派生的语言,如OCaml,是“近乎纯粹的”。它们允许通过像引用和数组这类的东西产生一些副作用,但是大部分你写出来的代码都会是纯函数式的因为它们鼓励这种思考方式。Haskell——另一种函数式语言——则是完全纯函数式的。因为写不纯的函数有时候更加有用和有效,所以OCaml更加实用的。

使用纯函数还有一些理论上的好处。其中一个好处是,如果某个函数是纯粹的,那么如果使用同样的参数对其调用多次的话,编译器就只需要调用该函数一次。在C中有一个很好的例子:
  1. for (i = 0; i < strlen (s); ++i)   
  2.   {   
  3.     // 做一些不影响s的事情   
  4.   }  
复制代码
如果就这样编译了,那么这个循环是O(n2)因为每次都要调用strlen (s)然后strlen又需要迭代整个s。如果编译器足够聪明可以推断出strlen是一个纯函数同时s又没有在循环中更新过,那么它就可以删除冗余的strlen的调用,就能使函数变为O(n)复杂度。那么编译器真的能这么做吗?在strlen的情况下,可以,而在其他情况下,可能就不行了。

集中于写短小的纯函数可以让你使用一种自地向上的方式来构建可复用的代码,同时边继续边测试每个小函数。而当前时尚的方式是使用一种自顶向下的方式来仔细设计你的程序,不过在作者的经历中,这往往会导致项目失败。


原文:http://shiningray.cn/docs/ocaml/functional-programming
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP