满血复活的函数式编程(组合软件)
Posted 奇舞周刊
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了满血复活的函数式编程(组合软件)相关的知识,希望对你有一定的参考价值。
编者按:本文由网络埋伏纪事在众成翻译平台上翻译。节后第一天,是不是感觉困困哒?不如先看看周刊,放松一下~
注:这是从头开始学习 javascript ES6+ 中函数式编程和组合软件技术的 “组合软件” 系列教程的第一部分。请继续关注。后面会有更多部分出来!
我 6 岁的时候,花了很多时间与最好的哥们一起玩电脑游戏。他家里有一个满是电脑的房间。它们对于我来说是无法抵御的、神奇的。我花了很多时间探索所有游戏。有一天我问我哥们,“我们做一个游戏怎么样?”。
他也不知道怎么做,所以我们就问他老爸。他老爸爬上一个高架子,拿出一本用 Basic 编写的游戏书。于是我们就开始了编程之旅。等到公立学校开始教代数时,我已经对代数掌握的不错了,因为编程基本上都是代数。大致就是这样的。
可组合软件的兴起
在计算机科学的开始,在大多数计算机科学可以实际在计算机上完成之前,有两个伟大的计算机科学家:Alonzo Church(阿伦佐.邱奇)和 Alan Turing(艾兰.图灵)。他们发明了两种不同的,但是等效的通用计算模型。这两种模型都可以计算任何可以被计算的东西(因此称为通用的)。
Alonzo Church 发明了 lambda 演算,这是一种基于函数应用的通用计算模型。而 Alan Turing 以图灵机闻名。图灵机是一种通用的计算模型,它定义了一种通过操作纸带上的符号进行计算的理论设备。
他们在一起协作展示 lambda 演算和图灵机在功能上是等效的。
Lambda 演算都是与函数组合有关。以函数组合来思考是一种相当有表现力和说服力的组合软件的方式。在本文中,我们将讨论函数组合在软件设计中的重要性。
有三个要点让 Lambda 演算变得很特别:
函数总是匿名的。在 JavaScript 中,
const sum = (x, y) => x + y
的右边是匿名函数表达式(x, y) => x + y
。Lambda 演算中的函数只接受一个输入。它们是一元的(unary)。如果需要多个形参,函数会带一个输入,并返回一个带有下一个形参的新函数,依此类推。多元函数
(x, y) => x + y
可以被表示为一个一元函数,比如:x => y => x + y
。这种从多元函数到一元函数的转换被称为柯里化(currying)。函数是头等的,意思是说函数可以用作为其它函数的输入,以及函数可以返回函数。
这些特性用在一起,形成一种简单,不过依然是富有表现力的词汇,使用函数作为主要的构造单元来组合软件。在 JavaScript 中,匿名函数和柯里化的函数是可选的特性。虽然 JavaScript 支持 lambda 演算的重要特性,但是并不强制使用它们。
传统的函数组合用一个函数的输出作为另一个函数的输入。例如,组合:
f . g
可以被写为:
compose2 = f => g => x => f(g(x))
如下是使用它的方式:
double = n => n * 2
inc = n => n + 1
compose2(double)(inc)(3)
compose2()
函数将 double
函数作为第一个实参,将 inc
函数作为第二个,然后将这两个函数的组合应到到实参 3
。再看阿卡你 compose2()
的签名,f
是 double()
,g
是 inc()
,x
是 3
。函数调用 compose2(double)(inc)(3)
实际上是 3 个不同的函数调用:
先传递
double
并返回一个新函数。返回的函数以
inc
为参数,并返回一个新函数。下一个返回函数以
3
为参数,并求现在变为double(inc(3))
的f(g(x))
的值。x
求值为3
,并传递到inc()
。inc(3)
求值为4
。double(4)
求值为8
。8
从函数返回。
当软件被组合时,可以用函数组合图来表示。考虑如下的函数组合:
append = s1 => s2 => s1 + s2 append('Hello, ')('world!')
可以用如下的图形可视化表示它:
Lambda 演算在软件设计上产生了巨大影响,在 1980 年之前,很多有重大影响的计算机科学象征都是用函数组合来构建软件。Lisp 是在 1958 年发明的,是深受 lambda 演算的影响。今天,Lisp 是依然在广泛使用的第二种最古老的语言。
我接触它是通过 AutoLisp,它是最流行的计算机辅助设计(CAD)软件 AutoCAD 的脚本语言。AutoCAD 是如此流行,以至于几乎所有其它 CAD 应用程序都支持 AutoLISP,以相互兼容。Lisp 也是计算机科学课程中的一种热门教学语言,这主要有三个原因:
其简单性让学习 Lisp 的基础语法和语义变得很容易,大约一天就可以搞定。
Lisp 都是与函数组合有关,而函数组合是一种组织应用程序的优雅方式。
我知道的使用 Lisp 的最佳计算机科学教材是:。
可组合软件的衰落
在 1970 到 1980 之间的某个时候,软件创建的方式渐渐远离简单的组合,开始变成一个计算机要听从的线性指令列表。然后面向对象编程出来了,这是一种关于组件封装和消息传递的不错的理念,不过被流行语言扭曲成一种为特性重用而实现的继承层次结构和 "is-a" 关系的糟糕理念。
函数式编程被打入冷宫和学术界,只有最极客的编程爱好者、常春藤大学中的教授,以及一些在二十世纪九十年代到二十一世纪十年代间逃脱 Java 强迫喂养的幸运的学生,还在幸福地痴迷着。
对于我们大多数人来说,这三十年间创建软件是个噩梦。这是黑暗的年代。
可组合软件的兴起
2010 年左右,一些伟大的事情开始发生了:JavaScript 爆发了。大约 2006 年之前,JavaScritp 被广泛当作是一门玩具语言,用来在浏览器中创建卡通动漫,不过它有一些强大的特性被埋没了。那就是,最重要的 lambda 演算特性。人们开始暗中窃窃私语 “函数式编程” 的这种很酷的新东西。
到了 2015 年,用函数组合来创建软件的理念再度流行。为让它更简单,JavaScript 规范做了十年来第一次重大升级,并添加了箭头函数,而箭头函数让创建和读函数、柯里化以及 lambda 表达式变得更简单。
箭头函数像函数式编程的火箭推进剂一样,在 JavaScript 中爆发。现在不大量使用函数式编程技术的大型应用程序已经很罕见了。
组合是一种为软件的行为清晰建模的简单、优雅而富于表现力的方式。组合小的、确定性的函数,来创建更大的软件组件和功能的过程,会生成更容易组织、理解、调试、扩展、测试和维护的软件。
在阅读后续的文章时,请用示例来实验。在学习时,请回忆孩童时代拆掉东西、探索和玩是什么感觉。重拾童年探索的欢乐。让我们来施点魔法吧。
奇舞周刊
——————————————————
领略前端技术 阅读奇舞周刊
长按二维码,关注奇舞周刊
▼
以上是关于满血复活的函数式编程(组合软件)的主要内容,如果未能解决你的问题,请参考以下文章