编程|程序员为何与函数式编程“坠入爱河”?


编程|程序员为何与函数式编程“坠入爱河”?
文章图片
编程|程序员为何与函数式编程“坠入爱河”?
文章图片
编程|程序员为何与函数式编程“坠入爱河”?
文章图片
编程|程序员为何与函数式编程“坠入爱河”?
文章图片
编程|程序员为何与函数式编程“坠入爱河”?

全文共3588字 , 预计学习时长9分钟

图源:unsplash
函数式编程发展至今已有60年的历史 , 但是截至目前 , 它仍然算是比较小众 。 尽管像Google这样的大公司依赖于函数式编程的关键概念 , 但是普通程序员对此几乎一无所知 。
这种情况即将改变了 。 不仅是Java或Python这样的语言越来越多地采用了函数式编程的概念 , 类似Haskell这样的新语言也正在完全实现函数式编程 。
简单来说 , 函数式编程就是为不可变变量构建函数 。 与之相反 , 面向对象的编程则是有一组相对固定的函数 , 而用户主要是修改或添加新变量 。
由于函数式编程的特性 , 它非常适合完成诸如数据分析和机器学习之类的需求任务 。 但是这并不意味着用户要告别面向对象的编程 , 转而完全使用函数式编程 。 但用户需要了解其基本原理 , 以便在适当的时候使用它们以发挥优势 。
一切都是为了消除副作用要了解函数式编程 , 首先需要了解函数 。 函数是将输入转换为输出的东西 , 它并不总是这么简单 。 下面看一个Python中的函数:
def square(x):
   return x*x

这个函数很简单 。 它需要一个变量 x , 或者是一个int , 又或者是float或double , 然后输出该变量的平方 。
现在再思考这个函数:
lobal_list = [
def append_to_list(x):
   global_list.append(x)

乍一看 , 该函数看起来像是接受了一个任意类型的变量x , 并且由于没有 return 语句 , 它不会返回任何值 。
请等一下!如果未事先定义global_list , 那么该函数将不起作用 , 并且在经过修改后仍输出相同的列表 。 尽管global_list从未被视为函数的输入 , 但使用函数时它也会发生改变:
append_to_list(1)
append_to_list(2)
global_list

它将返回[12
而不是一个空列表 。 即使我们对此并不明确 , 但这表明该列表确实是该函数的输入 。 这种不明确可能会造成问题 。
图源:GitHub
不忠实于函数
这些隐含的输入 , 或在其他情况下的输出 , 有一个官方的名称:side effects(副作用) 。 虽然本文所举的只是一个简单的示例 , 但是在更复杂的程序中 , 这些副作用可能会导致真正的困难 。
请思考一下如何测试append_to_list:用户不仅需要阅读第一行并使用任意的x来测试函数 , 还需要阅读整个定义 , 理解其作用 , 定义global_list并且以这种方式进行测试 。 当需要处理带有数千行代码的程序时 , 此示例中的简单操作可能很快就会变得乏味无趣 。
有一个简单的解决方法:忠于函数认定为输入的内容 。
newlist = [
def append_to_list2(x some_list):
  some_list.append(x)append_to_list2(1newlist)


推荐阅读