函数式编程的优与劣

如今函数式编程越来越流行。越来越多的编程语言支持函数式编程风格,人们学习如何使用它们。函数式编程已不像以前那么小众——现在Ruby,Java和JavaScript都使用了函数式编程思想。

这些语言都有函数式的特性,但不是函数式语言。我的经验之谈,函数式语言,如Erlang或ML拥有其他主流语言缺少的特性,能让编程更加安全的特性。其中之一便是使用递归和参数模式匹配(argument pattern matching)控制循环。你也可以将这些设计用于流控制( flow control)。另一个便是认真对待常量赋值。我这里提到常量赋值因为在这些语言中,一旦你给变量绑定一个值,直到离开作用域前会一直绑定。这个特性带来的弊端就是学习如何使用它们开发软件很困难。对于我们这些用强类型语言的开发者,尤其困难。

递归和模式匹配

函数式编程语言特性是运行期优化递归。使用尾调用优化,运行期提供高效的回调环境,使每个回调用相同的栈帧(stack frame)。再加上参数模式匹配,你可以像写归纳法证明(高中数学的归纳法)那样写表达式函数。你有一个基础步骤和归纳步骤。基础步骤结束递归,归纳步骤重复递归。通过这种方式,你可以定义函数处理列表或集合。函数的每个变量在每次调用中绑定,这使得变量绑定更易于管理。下面是个伪代码例子:

这里,我们定义了一个函数looper()对列表内容求和。

第一个步骤是基础步骤——如果列表为空,我们返回0。第二个步骤是归纳步骤——如果列表有头元素和尾元素,然后我们把尾元素通过递归调用looper()方法求和。如果列表中只剩一个元素,这个元素绑定到变量t,递归调用匹配基础步骤(因为变量h为空),然后递归展开。

在函数式语言中,尾调用优化确保了栈帧重复使用,所以本质上结构和for、while循环一样,比如C语言。

如果你在Ruby或JavaScript中使用它,你必须确保在使用函数循环列表前尾递归优化是可用的。如果没有,你将在递归中遇到性能问题。你在Ruby或JavaScript中只需要把基础步骤放在归纳步骤前面就行。

常量赋值

这点在函数式语言中很难实现。毕竟用不可变的值表示可变的状态非常困难。你又该怎么办呢?

记住,变量赋值只在当前作用域有效。所以你如何应对这种情况?你让作用域很小,只在函数调用时绑定必须的变量。你不能编写修改状态的代码,比如在一系列循环中。你只能在函数调用时绑定状态,然后递归。通过这种方式,你可以维护状态改变,在绑定状态变量值时很难出现错误。

不要使用全局变量。它会跑到作用域外。

相比那些所谓拥有函数式编程的语言,这就是你将在真正函数式语言中看到的两点关键不同点。函数式程序设计让你的重用能力更上一层楼,使代码更清晰,不过在没有优化的运行环境中会有潜在的性能代价。

原文发布于微信公众号 - java一日一条(mjx_java)

原文发表时间:2016-09-10

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏noteless

原型模式 prototype 创建型 设计模式(七)

用原型实例指定需要创建的对象的类型,然后使用复制这个原型对象的方法创建出更多同类型的对象

11520
来自专栏我是攻城师

你不知道的Java的split的小问题

28760
来自专栏向治洪

迭代器模式

迭代器模式(Iterator): 提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。 用途:在软件构建过程中,集合对象内部结构常常变化各异。...

198100
来自专栏C语言及其他语言

[每日一题]排列

题目描述 有4个互不相同的数字,输出由其中三个不重复数字组成的排列。 输入 4个整数。 输出 所有排列 样例输入 1 2 3 4 样例输出 1 2 3 1 3 ...

37770
来自专栏北京马哥教育

Python新手常见错误之默认值设定错误

文章来源 |伯乐在线 云豆贴心提醒,本文阅读时间5分钟,文末有秘密! Python初学者通常会犯一些错误,甚至会因此损失很大的自信心。 不过你不必过多的担...

36160
来自专栏WeTest质量开放平台团队的专栏

【《Effective C#》提炼总结】提高Unity中C#代码质量的21条准则

我们知道,在C++领域,作为进阶阅读材料,必看的书是《Effective C++》。 而《Effective C#》之于C# ,是类似《Effective C+...

13130
来自专栏C/C++基础

C++智能指针

C++中,动态内存的管理是通过一对运算符来完成的,new用于申请内存空间,调用对象构造函数初始化对象并返回指向该对象的指针。delete接收一个动态对象的指针,...

31610
来自专栏机器学习算法与Python学习

6个鲜为人知的 Python 语法,你知道几个?

所有人(好吧,不是所有人)都知道 Python 是一门用途广泛、易读、而且容易入门的编程语言。

14440
来自专栏JavaQ

烂代码吐槽汇 | 奇葩命名

代码首先是给人看的,其次才是给机器看的。 烂代码特征:可读性差、逻辑混乱、性能低下。 1.奇葩项目(模块)名 项目(模块)名称使用汉语拼音、英汉双拼、超长的字母...

35750
来自专栏java一日一条

函数式编程的优与劣

如今函数式编程越来越流行。越来越多的编程语言支持函数式编程风格,人们学习如何使用它们。函数式编程已不像以前那么小众——现在Ruby,Java和JavaScrip...

8310

扫码关注云+社区

领取腾讯云代金券