面向过程编程和函数式编程有什么区别?
不理解函数式编程。求解。
更新:
个人理解:“面向过程”和“面向对象”的区别是“封装”。“函数式”和“面向对象”的区别是“不使用外部状态”。 这三种编程思想真是云里雾里。
Answers
写法上:函数式编程,就是将函数作为参数传递到另一个函数里。因为js里函数也是对象,所以在js 里会经常看到这种写法。
java,c# 也有 lambda 写法,将匿名对象作为参数。其实也是函数编程的思想。
作用上: 函数式编程很清晰。在实际应用中,当你遇到需要某种方法实现一类功能,但是具体每个功能又不尽相思的情况下,函数式的写法就很优美了。 例如,我有一个计算功能。具体要加减乘除4种。我就可以这样写:
//某一类算法,这里是计算
function cal(a,b,fun){
return fun(a,b);
}
//具体算法1,加法
var add = function(a,b){
return a+b;
}
//具体算法2,减法
var reduce = function(a,b){
return a-b;
}
那么我用的时候就可以酱紫:
var result1 = cal(a,b ,add); //a+b
var result2 = cal(a,b ,reduce);//a-b
var result3 = cal(cal(a,b,add),c,reduce)//a+b-c
将函数实现的细节封装,与函数具体调用分开,,有没有觉得读起来非常方便。
看过一本电子书,说的很详细,可以只试读第一章,估计就能明白了,其实很简单
http://yuedu.baidu.com/ebook/f7c46708a26925c52cc5bff4
这个是我的理解:
coffee
# 函数式 trimLeft = (text) -> switch when text.length is 0 then text when text[0] is ' ' then trimLeft text[1..] else text # 过程式 trimLeft2 = (text) -> while (text[0]? and text[0] is ' ') text = text[1..] return text
函数式的写法, 我改成了
switch
, 因为
if
写起来有点难看,
而过程式的写法, 简直是短小精悍.. 而且对 JavaScript 来说性能也更好
注意一下代码执行的顺序,
函数式的写法, 执行过程是通过函数调用参数传递一层层展开的,
text
以参数的形式复制跟传递
过程式的写法, 执行过程是在
while
里一遍一遍进行,
text
被一遍遍赋值更新
如果你还注意到函数式写法数据不可变的话, 就更能了解怎么回事了
数据可变是很多 bug 的根源, 也是程序并行执行的巨大障碍, 函数式编程认为数据是不可以被修改的,
另一方面硬件来说, 实际上就是 CPU 寄存器内存上不断进行数据更新的, 跟函数式完全相反
单纯这一点来说, 差别的非常大的. 想想一下用你现在的语言, 变量不能修改你怎么写程序!
还有一点是函数式编程考虑的是这个问题的解决方案可以被怎么表达? 存在多少种情况? 每种怎么处理?
而过程式的代码, 需要找到一个能把事情做完的执行顺序, 然后把这个执行顺序用代码表示出来
简单的程序没什么, 但是复杂的过程用函数式来考虑, 也许可以大幅度简化问题
建议参考我校稿的这篇文章
http://python.jobbole.com/81075/
上面有很多函数式和过程式语言对比的实例,仔细看一下才能有很深的认识
当谈论函数式编程,会提到非常多的“函数式”特性。提到不可变数据,第一类对象以及尾调用优化。这些是帮助函数式编程的语言特征。提到mapping(映射),reducing(归纳),piplining(管道),recursing(递归),currying4(科里化);以及高阶函数的使用。这些是用来写函数式代码的编程技术。提到并行,惰性计算以及确定性。这些是有利于函数式编程的属性。
忽略全部这些。可以用一句话来描述函数式代码的特征:避免副作用。它不会依赖也不会改变当前函数以外的数据。所有其他的“函数式”的东西都源于此。当你学习时把它当做指引。
过程式的方法使用了状态,而不是传入参数。方法通过改变外部变量影响了附近的代码,而不是通过返回值。为了搞清楚方法做了什么,读者必须仔细阅读每行。如果发现一个外部变量,必须找他它的出处,找到有哪些方法修改了它。
函数式语言,每次一个步骤方法会产生一个状态,这个状态会直接当参数传进下一步中。而不是使用全局变量