转:浅析函数式编程与命令式编程的区别(三)风格的区别

原文网址:http://www.cnblogs.com/lisperl/archive/2011/11/23/2259363.html

重点段落:

面向过程和面向对象是命令式语言主要的两种风格。编程语言一直都在进化,而且现在的趋势是命令式语言正在想函数式语言靠拢。

首先我们来看看函数式编程的一些典型特征:

  1. 函数作为第一级的值(第一类对象)和高阶函数
  2. 广泛的多态
  3. 递归
  4. 机构性的函数返回
  5. 递归
  6. 表类型和表操作
  7. 结构性对象的构造符(聚集值)
  8. 废料收集(垃圾回收机制)
函数被作为 第一类对象 处理(第一类对象是指可以作为参数传递、从函数里返回、可以(在有副作用的语言里)赋值给变量的东西,更严格的定义还要求第一类对象能在运行时创建(计算出)一个新值的能力)。 比如comman Lisp内置的sort函数就接受一个谓词函数作为参数对列表排序:

  CL-USER> (sort '(2 1 3 4) #'<)

  (1 2 3 4)

  再比如我们可以定义一个返回函数的函数:

  CL-USER> (defun make-adder(n)

  #'(lambda (x) (+ x n)))
  MAKE-ADDER

  这个函数接受一个参数n然后返回一个加法函数。这个加法函数将返回参数加上n的值。比如我们可以这样使用它: 

  CL-USER> (funcall (make-adder 2) 2)
  4

高阶函数是一个可以去函数为参数或产生一个函数为结果或者两者皆有的函数。一种常见的类型就是函数复合(和数学的复合函数差不多),它有两个函数参数,并且产生一个函数,这个结果函数的值是将第一个实参数函数应用到第二个函数的结果上产生的。比如:h(x)=f(g(x))。另一个常见的类型是:应用到所有参数。它取一个函数作为参数,将这个函数应用到自变量表中的每一个值。比如Lisp中的mapcar函数: 

  CL-USER> (mapcar #'(lambda(x)(+ 3 x)) '( 1 2 3))
  (4 5 6)

  这里mapcar第一个参数就是一个函数(这里是一个匿名函数),第二个参数是一个表,然后mapcar将函数应用到每一个列表元素上。

  多态性在函数式语言中极为重要,因为这样能使得函数尽可能广泛的一大类参数上。像Lisp这样的动态语言,内在就是多态的。ML语言有类型系统,但是它的类型系统是多态性的,它忽略掉无关的数据类型,在编译时进行类型推理来支持多态性。

  递归可以说是函数式语言用得最多的特性了。在函数式程序中,变量是通过外部传入或者申明获得值的。变量不能被改变,只能通过递归调用可以制造一系列变化的参数值。而且在没有副作用的情况下,是不可能实现循环的,递归成了重复做一件事情的唯一选择。从某种意义上讲,递归的语义比循环很容易理解。

   可以说是天生的函数式语言的数据结构,因为它们有自然的递归定义,很容易基于第一个元素和(递归地)对表中其他元素的操作的方式完成各种处理。Lisp语言就将表作为数据和程序的基本结构,实际上Lisp原本的意思就是表处理语言。

  最后我们来总结一下到底什么是函数式编程风格:纯函数式编程不使用变量或赋值语句产生结果,它们使用函数的应用条件表达式递归来作为执行的控制,并且使用函数形式来构造复杂的函数。这样的好处就是纯函数式编程不会产生副作用,当给予同样的参数时,函数的执行总是会产生同样的结果。这种特征被称为引用透明性

函数式编程风格的核心就在于无副作用编程,而函数式语言诸多的特性也都是围绕这一核心设计的。


例如,定义一个按某种格式返回数组各个元素的函数formatArgs

scala> def formatArgs(args: Array[String]) = args.mkString("\n")
formatArgs: (args: Array[String])String

scala> formatArgs(Array("werw","dddd"))
res29: String =
werw
dddd

scala> print(formatArgs(Array("werw","dddd")))
werw
dddd

没有副作用的代码可以使程序变得更容易测试

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值