怎么理解函数式编程中的"变量也是函数"

2014-04-15 14:09:36 +08:00
 pythonee
在大多数函数式编程语言中,大多数都强调一切都是函数,函数式一等公民。
那么 "变量" 也是 "函数"

var foo = "hello world"

那么"foo"这个变量也是一个函数?

是不是可以说等价于下面的函数写法

def foo() = { "hello world" }

即变量名是方法名,变量值是返回值。
那么这样说的话,函数式和命令式的本质区别是什么呢?只是表示形式上的区别吗
7029 次点击
所在节点    程序员
40 条回复
pythonee
2014-04-15 18:29:48 +08:00
@simpx 嗯,不纠结,只是闲来给自己点思考的东西。不过还是谢谢这位同样"过来的少年",继续写代码去,另外发现scala这货挺适合拿来玩的
otbzi
2014-04-15 18:30:12 +08:00
@simpx

如果你认为java中的lambda这种feature的就是你眼中的函数式语言的话,那的确可以说得上是「非常dirty」的了。

如果你看过Paul Graham写的 the root of lisp: http://www.paulgraham.com/rootsoflisp.html

就会知道,lisp语言是如何在几个非常少的special form之上构造出一门语言的。

在lisp中,的确是如上文某位同学所说的,「函数式语言是没有变量的」。

在这个时候,如果你还要说,「计算机都是应用科学,数学才是最叼!」。如果你抱着这种想法,这个世界上我们做了这么多工作,就是为了通过思考抽象出一些概念和工具用来解决问题。你非要每个point都还「刨根问底」,把数学跟工程学科排序一下,得出一个谁谁誰是「笨拙」的结论。那真的就无解了。

前人做了那么多工作。就是让我们做的事情一步一步更加抽象。解决越来越多的问题。「一句数学最叼」,你对人类做出了什么贡献了么?这么粗暴的下结论,就明显给人智力上的懒惰的感觉。
hhkbp2
2014-04-15 19:12:15 +08:00
"变量也是函数"?
出处在哪?
jiyinyiyong
2014-04-15 19:23:32 +08:00
大多数函数式编程语言 - - - - 错, 这是函数式语言的关键, 不是大多数, 是所有
一切都是函数 - - - - 错!
函数式一等公民 - - - - "式" 改成 "是" 的话是对的
那么 "变量" 也是 "函数" - - - - 错!

一般说区分函数式编程看到是一个函数 a, a 能不能像一般的变量一样随意传递
纯函数语言里, 比如 Haskell, String, Char, Number, Bool 都是很明确的.
pythonee
2014-04-15 19:48:57 +08:00
@hhkbp2 我想起应该可以用丘奇运算(或者叫lambda运算?)来表示出处吧,在丘奇的体系中,0和1也是函数,而不是变量。
pythonee
2014-04-15 19:50:53 +08:00
@jiyinyiyong 之所以说大多数,是因为我不敢确定其他的语言是什么情况。"式"的确打错了,应该是"是"。如果函数式的重点是,函数像值一样传递的,那么内涵是不是太少了点
hhkbp2
2014-04-15 20:25:31 +08:00
@pythonee 数学定义和计算机编程语言还是有比较多区别的,不能因为lambda运算如何如何就推定函数式编程也如此
函数式编程虽然有高阶函数(可以将函数赋值给变量),但值语义是比较常见的,不推荐命令式语言中的变量用法
hhkbp2
2014-04-15 20:34:42 +08:00
@jiyinyiyong
@pythonee
讲到函数式编程内涵,并非只是常常被人提到的函数式风格,我理解至少有2层意义
1. 函数式风格(包括高阶函数,对无副作用,可重入的强调等)
2. 函数式数据结构和函数式算法

第1点广为人知,第2点则较少人讲到。其中函数式数据结构(值语义),奠定了函数式在大并发时代的优势,详细可以参考erlang或clojure的设计
Ricepig
2014-04-15 20:40:13 +08:00
@hhkbp2 其实优势不如想象的大。所谓值语义,immutable,还是无法避免并发的核心问题。还是需要我们自己发挥聪明才智,如履薄冰地解决。
pythonee
2014-04-15 22:21:15 +08:00
@hhkbp2 你说的函数式数据结构和算法是指将传统数据结构如:树、队列等这些用函数式来实现吗?我觉得Toplanguage组里有个liuxinyu前辈用haskell做了一些研究。不知道你指的是不是那个,另外,你说的值语义是什么?

erlang在大并发时代的优势应该是它的actor模型和轻量级线程、热部署等特性。但是这些好像我无法将他们与值语义联系起来。不过听说热部署特性在函数式中比在命令式语言中较容易实现
hhkbp2
2014-04-15 23:20:40 +08:00
@Ricepig
你所说并发的核心问题是指?
hhkbp2
2014-04-15 23:25:47 +08:00
@pythonee
liuxinyu从拼音来看,没猜错的话,应该就是同我认识的同一个人
functional算法和数据结构,之前就有人研究过,并且出过书的

值语义是指immutable,clojure里面有一整套的persistent data structure。有兴趣的话可以找些相关的书或资料深入了解一下它里面的实现
pythonee
2014-04-16 09:31:26 +08:00
@hhkbp2 我理解的并发核心应该是现有使用共享状态来进行多线程通信时导致的锁争用、线程等待这些问题,erlang通过消息传递和变量不可变解决了这个问题,但是又引进了另外的问题
pythonee
2014-04-16 09:32:06 +08:00
@hhkbp2 "clojure里面有一整套的persistent data structure" 这个第一次听说,有相关资料看吗,最好入门级的
simpx
2014-04-16 09:58:27 +08:00
[OT]
@otbzi 我只同意你”在这个时候“之前的话,因为我并没有试图得出哪种思想更笨拙、或者没有意义。限于篇幅,我也没办法让你觉得我不是在粗暴的下结论。

实际上,我认真学习过lisp,也分别用python、javascript自己实现过不完备的lisp解释器,我反而根本不会Java :)

但当我深入下去,试图实现纯粹的万物皆函数,比如用邱奇数来表示数字,我发现我实现的这门lisp方越来越徒有其表,只能算用各种dirty模拟了一个完美的概念,毕竟我是在图灵机上实现,而不是Lisp machine。我也不得不造出一些二流的概念,误导后人,当然,如果有人用我的方言的话。

保留个人观点,纯粹的函数式思想是用来带给我们MapReduce这样的运算架构的,而不是用来在图灵机上实现的。在现实的函数式语言中寻找纯粹的概念,是白费力气,要么接受dirty,要么钻研纸上完美的lisp。
edison0951
2014-04-16 10:15:36 +08:00
函数式编程和函数式语言还是有些许出入的吧。
zinking
2014-04-16 12:13:29 +08:00
其实还是个蛮有意思的哲学话题 静跟动的关系

比如一开始学习线性空间的时候,我们能够理解先行空间里的点的意思。 突然有一天,说函数也是线性空间里的点的时候,突然就产生了像楼主这样的冲击感。 不过深入下去很快就理解了
pythonee
2014-04-16 12:46:36 +08:00
@zinking 线性空间我就记得矩阵了,矩阵是描述线性空间运动的极好工具,其他的都忘了。不过听你这么一说,好像有点印象
wity_lv
2014-04-16 14:30:13 +08:00
从数学的角度理解.
函数. f(x) = x + 1;
普通理解, x = 1,2,3,4,5 .... 整数.
f(2) = 2 + 1; 计算结果为3.


如果 x 是另外一个函数.
x = f(a, b) = a + b;
f(x) = f(2, 3) + 1 = (2 + 3) + 1 = 5 + 1; 输出结果为6


再说一个不好理解的case:
y = f(a, b) = a + b;
x = f(a) = y(a, 4);
f(x) = x + 1 = f(a) + 1 = a + 4 + 1

1. 函数可以用来计算
2. 函数可以作为参数(变量也是函数)
3. 函数可以用来生成函数(变量也是函数)

用mit-scheme实现.
1. 函数可以用来计算
(define plus1(x) (+ x 1)
(plus1 2) #> 输出3

2. 函数可以作为参数(变量也是函数)
(define plus-both(a b) (+ a b)
(plus1 (plus-both 2 3) ) #> 输出 6

3. 函数可以用来生成函数(变量也是函数)
(define generated_fun(a) (plus1 (plus-both a 4) ) #> a + 4 + 1
(generate_fun 1) #> 1 + 4 + 1 输出 6


函数式编程语言能够很容易使用数学的方式来思考。
Cbdy
2017-07-25 10:08:07 +08:00
只是先求值和后求值的区别
一切都是对象(值,先求值),一切都是函数(后求值)

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/108653

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX