一篇有关函数式编程的形象生动教程

栏目: 编程语言 · 发布时间: 6年前

内容简介:函数式编程(FP)与面向对象编程(OOP)的诞生的时间差不多,但它最近才最受欢迎,特别是在JavaScript社区中,为什么?我在00年代早期就学麻省理工学院。计算机程序的体系结构和解释(SICP)是我的教科书。所以我的第一个正式学习的编程语言是函数性的,然后我在工业界工作了十多年,几乎没有多少时间考虑过使用FP。当得知大学的教科书被认为是“函数性编程圣经”时很震惊。别误会我的意思,这是一本很好的教科书。我敢肯定它会让我成为一个更好的程序员,但这并不是我需要经常在Java / ActionScript /

函数式编程(FP)与面向对象编程(OOP)的诞生的时间差不多,但它最近才最受欢迎,特别是在JavaScript社区中,为什么?

我在00年代早期就学麻省理工学院。计算机程序的体系结构和解释(SICP)是我的教科书。所以我的第一个正式学习的编程语言是函数性的,然后我在工业界工作了十多年,几乎没有多少时间考虑过使用FP。当得知大学的教科书被认为是“函数性编程圣经”时很震惊。

别误会我的意思,这是一本很好的教科书。我敢肯定它会让我成为一个更好的程序员,但这并不是我需要经常在Java / ActionScript / PHP / Python / Ruby / JavaScript等职业生涯中使用的东西。

然后我在Wyncode Academy任教四年,并发现自己试图向新手解释FP概念。这很难 - 比OOP更难。

为什么FP比OOP更难?

相关问题:为什么FP需要这么长时间才能流行起来?

我们编码社区需要解决为什么FP难以教授。像一个宗教说教一样传播FP重复了同样的错误,导致FP长期在这个行业中萎靡不振。

对FP的许多介绍都遗漏了一些东西。它不仅仅是一种替代编程风格。这是一种新的思维方式,它代表的类似的技巧也可以与来自OOP背景的更有经验的 程序员 一起使用。

我在Wyncode中使用的技术之一就是讲述一个难以理解的概念时,首先让学生了解概念的背景以及 这个概念的大致样子(big picture),之后就更容易解释技术细节了。

大致样子(big picture):历史背景

计算机是如何工作的?最常见的(流行的?易于理解的?)计算模型是图灵机。FP程序员抱怨的状态正在图灵机中正视着我们。用于操作该机器的算法表示不同状态之间的转换,例如从打开 / 关闭 (1或0)的一些盒子到打开 / 关闭的一些其他盒子。

如果我们试图想象两个图灵机同时在同一磁带上运行,我们就可以开始理解为什么“共享状态”和OOP中的并发性都是难题。

图灵机是一台通用机器。它可用于解决每个可有效计算的数学和逻辑问题。这是个简单的操作集: 向左移动,向右移动,写点,读点,擦除点(增删改查CRUD)。 足以(给予足够的时间和资源)来解决宇宙中的每个数学问题。

这就是艾伦·图灵在1936年所证明的。

在许多方面,图灵机是计算机“工作”的方式。但这也是计算机的工作原理。但是还有另外一种理论:

电路是不同的计算模型。每个逻辑门(AND,OR,NAND,NOR,XOR等)都是纯函数。他们接受输入并产生没有副作用的输出。如果我们只有能够创建和组合这些“函数”,我们还可以解决宇宙中每个可解决的数学问题。这也是阿隆佐·邱奇在1936年证明的。

所以我们有两种不同的计算模型:图灵机​​的0和1(对象)和阿隆佐·邱奇用逻辑门(函数)构建的lambda演算。哪一个是正确的?

有一段时间,关于抽象图灵机是否能解决与lambda演算相同的数学问题(反之亦然)的辩论。最终他们被证明是等同的。

等同意味着它们同样强大。任何可以为图灵机编写的算法也可以使用函数编写。因此,任何可以用图灵机软件编写的程序也可以用电路硬件表示。

“硬件编程”是什么意思?我们可以看到 专用集成电路(ASIC)中 体现的“硬件编程” 。可以创建“编程”的电路,以便快速完成一件事,比如 我的比特币下棋

我们现在有两种编程选择。硬件更快,软件更慢。在软件中犯了错误?只需点击删除键,然后重试。硬件出错?是时候抓烙铁了。这是一个经典的工程设计权衡。

因此,假设我们有一个以OOP风格编写的算法,我们希望将其转换为ASIC硬件编程。以FP风格重写程序可能是一个很好的策略,因此它可以更好地映射到底层电路图。

面向FP的语言往往看起来像电路。特别是Unix,Elixir,F#,JavaScript和其他“管道操作员” 使代码看起来像电路图:输入进入左侧,流过许多“门”(管道)直到它们被转换进入右边的最终输出。某些语言(|>)使用的管道运算符看起来像逻辑门,这可能不是巧合。

大致样子(big picture):哲学

我拿到了我的CS学位的哲学辅修,所以我着迷的一件事是这两个研究领域的交集。我发现在教授新程序员时,特别是那些具有人文学科而不是STEM背景的程序员,有助于在这两个领域重叠处讨论思想。

FP中一个哲学上重要的概念是“函数相等 functionally equivalent”。

也许证明这种等价性的最好例子是 汤姆斯图尔特的 伟大文章 “从无开始编程” 。这里借用他对数字如何完全用函数表示的方式来解释编码:

首先将数字0的概念定义为接受函数参数但不对其执行任何操作的函数。

# Ruby
ZERO = -> (func) { 
  # does nothing
  func
}

类似地,我们可以将所有自然数定义为接受函数参数的函数,并将它们调用n次。

ONE = -> (func) {
  # calls it once
  # same as func.call()
  func[];
  func
}

TWO = -> (func) {
  # calls it twice
  func[]
  func[]
  func
}

要测试这些“函数数字”,请将它们传递给测试函数。

HELLO = ->() { puts <font>"hello"</font><font> }

# same as: ZERO.call(HELLO)
ZERO[HELLO] # nothing displayed
ONE[HELLO]  # one </font><font>"hello"</font><font> displayed
TWO[HELLO]  # </font><font>"hello"</font><font> twice
</font>

这种函数数字符号表示法其实很难玩和调试。因此,为了更容易使用,我们可以定义一个函数,将这些函数数转换为我们习惯使用的对象数字。

# convert number function into number object
def to_integer(func)
  # count how many times counter is called
  n = 0
  counter = ->() { n += 1 }
  func[counter]
  n
end

p to_integer(ZERO) # 0
p to_integer(ONE)  # 1
p to_integer(TWO)  # 2

这个转换器创建计数功能并将其传递给数字函数。ZERO函数将调用它为零次,ONE函数将调用它一次,等等。我们跟踪计数器被调用多少次以获得结果。

对于这些函数数字定义,我们可以实现添加各种功能:ADD SUM统计等。

ADD = -> (func1, func2) {
  -> (f) { func1[func2[f]] }
}

sum = ADD[ZERO, ZERO]
p to_integer(sum) # 0

sum = ADD[ZERO, ONE]
p to_integer(sum) # 1

sum = ADD[ONE, ONE]
p to_integer(sum) # 2

如果TWO调用一个函数两次,那么ADD[TWO, TWO]将返回一个调用其参数四次的函数数字(函数数字FOUR)。

这是一个令人费解的方式。当我看完“从无开始编程”这本书时,我感觉这是一个巧妙应用基本计算机科学概念的有趣书籍,但不是我在日常工作中可以使用的东西。

而这正是我(我怀疑很多其他人)对FP一般的感觉 - 它很聪明,但似乎没有用。这是我们需要解决的问题。

所以,教FP更好的开始地方是“黑客帝国3:矩阵革命”。

什么是矩阵与FP呢? 这部电影告诉我们:我们没有证据证明我们周围的世界是真实的。也许世界上有实际的物体,或者我们只是 在罐子里的大脑

因此,至少有两个相互矛盾的理论,例如,第一个是什么。我们可以与之交互(触摸和感觉)是一种(名词,对象)吗?或者它是一个动作(一个动词,一个函数),一个作用于世界的东西,但没有实在的呈现?

函数数字one是数字1的模拟,它是在函数等同 functionally equivalent于对象数字one,意味着它可以做对象数字one做的任何事情。

但是OOP中的对象“存在”并不是真的“存在”。这是一个矩阵模拟。它没有固有属性 - 它不是x,它只是像x。

打个比喻,你坐在真正的椅子上只是一种 用力按压你的身体 功能?“椅子”可以是存在于现实世界中的椅子这个对象,也可以是一种椅子功能:一种希望用舒适的力量推动你的功能,并没有潜在的客观基础。

想想颜色,红色美味的苹果真的是红色的(形容词、描述名词)还是扮演红色(动词)?颜色是真正的底层苹果对象的固有属性,还是仅仅是当光照在它上面时执行函数的动作结果呢?苹果真的还是模拟的呢?

解释这个哲学概念的难度是解释为什么FP难以教授的好隐喻。为了帮助学生理解,首先要开放他们的想法,让世界完全由“功能/函数”组成。从样子big picture概念开始,然后转向世界的FP模型:它们与OOP表示的区别以及它们如何具有相同的结果。(banq注:从概念开始转向有两个:一个是名词,一个是动词,FP是转向到动词,而我们日常是转向名词,但是很多人没有意识到这种转向,所以很难转到动词方向去接受函数编程)


以上所述就是小编给大家介绍的《一篇有关函数式编程的形象生动教程》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

零售的哲学:7-Eleven便利店创始人自述

零售的哲学:7-Eleven便利店创始人自述

[日] 铃木敏文 / 顾晓琳 / 江苏文艺出版社 / 2014-12-1 / 36

全球最大的便利店连锁公司创始人——铃木敏文,结合40多年零售经验,为你讲述击中消费心理的零售哲学。铃木敏文的很多创新,现在已经成为商界常识,本书把那些不可思议的零售创新娓娓道来。关于零售的一切:选址、订货、销售、物流、管理……他一次又一次地在一片反对声中创造出零售界的新纪录。 翻开本书,看铃木敏文如何领导7-11冲破层层阻碍,成为世界第一的零售哲学。一起来看看 《零售的哲学:7-Eleven便利店创始人自述》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

URL 编码/解码
URL 编码/解码

URL 编码/解码