Currying,闭包, Partially applied functions和Curried functions的区别

42 views
Skip to first unread message

Xuefeng Wu

unread,
Dec 1, 2009, 10:17:01 PM12/1/09
to ScalaCn
这几个名字什么概念?以前不知其解,现在有一些理解不知道对不对,请大家讨论一下。

Currying:Currying是为了纪念美帝数学家Haskell Brooks Curry而命名的,所以想翻译成中文估计最好是音译了。它的基础是λ演算
在计算机语言就是一个函数可以带多个参数列表,注意是多个参数列表,而不是多个参数。如def foo(x: Int)(y: Int)(z: Int){}。
这是一种能力表述,对应的函数称之为Curried function。但是Scala骨子里不是函数式语言,它是用OO实现的,而且是建立在JAVA虚拟机上,
于是Scala就提出了Partially applied function,我的理解他就是Scala的Curried function的实现方式,而且创新性的提出Partially Function,其实它对应的还是一个OO的Class或对象。Partially Function应该翻译成偏函数,caoyuan同时提出这样翻译是有数学背景的。但是纯的函数式语言没有这个概念是因为它能很自然的实现Curried function。


再剩下闭包,在编程语言闭包有两个讲述方式,1是匿名函数,2是带有自由(未绑定)变量的函数块。
这两个表述方式根据不同的编程语言略有不同,在Scala应该是后者包含前者。也就是说如果这个函数块没有名字,那么它就是匿名函数,如果有那它还是闭包但不是匿名函数。
Python3.0之前支持匿名函数但不能真正处理闭包。

将了半天闭包还没点到它的实质,我对闭包的理解是:闭包是OO的产物,是OO对函数式编程λ演算的一种变形实现。
为什么这么说呢?
首先闭包不是函数式的:函数式是没有变量一说的,那么从闭包的概念可以得知闭包是为了处理自由变量而提出的,既然连变量都没有就更谈不上闭包。
第二OO是不支持只传递运算的:OO的思想核心是对象,传递的全是对象,但运算函数不是对象,他只是对象的一部分。但现实有只传递运算的需求,于是就需要创造,就出了闭包。

以上是我对这些概念的理解,没有在哪本书或哪篇文章找到过相应的论述,恐有理解偏差还请大家多多包涵。



--
Scala中文社区:  http://groups.google.com/group/scalacn

Xuefeng Wu

unread,
Dec 1, 2009, 10:27:02 PM12/1/09
to ScalaCn
所以闭包和currying是两个不同的能力,在Scala的实现方式都是Partially Function

2009/12/2 Xuefeng Wu <ben...@gmail.com>



--
Scala中文社区:  http://groups.google.com/group/scalacn

Caoyuan

unread,
Dec 1, 2009, 11:54:00 PM12/1/09
to sca...@googlegroups.com
2009/12/2 Xuefeng Wu <ben...@gmail.com>:

> 这几个名字什么概念?以前不知其解,现在有一些理解不知道对不对,请大家讨论一下。
>
> Currying:Currying是为了纪念美帝数学家Haskell Brooks
> Curry而命名的,所以想翻译成中文估计最好是音译了。它的基础是λ演算。
> 在计算机语言就是一个函数可以带多个参数列表,注意是多个参数列表,而不是多个参数。如def foo(x: Int)(y: Int)(z: Int){}。
> 这是一种能力表述,对应的函数称之为Curried function。但是Scala骨子里不是函数式语言,它是用OO实现的,而且是建立在JAVA虚拟机上,
> 于是Scala就提出了Partially applied function,我的理解他就是Scala的Curried
> function的实现方式,而且创新性的提出Partially Function,其实它对应的还是一个OO的Class或对象。Partially
> Function应该翻译成偏函数,caoyuan同时提出这样翻译是有数学背景的。但是纯的函数式语言没有这个概念是因为它能很自然的实现Curried
> function。

偏函数在数学上是一个传统的概念,一般而言,某個函數所有的輸入值的集合被稱作這個函數的定義域,但有一类函数,它的定义域可以是所有可能的输入值的一部分,比如我讲过的一个例子:本来输入域是全部的整数,但现在只对大于等于0的整数有定义:

def check: PartialFunction[Int, String] = {
case n if n > 0 => println("P")
case 0 => println("Zero")
}

对小与零的整数则没有定义,所以:
check.isDefinedAt(-1) 会返回false

可以看到,Scala中的偏函数和数学上的偏函数在概念上基本是一致的。
Scala使用偏函数来实现某些curry功能是比较自然的,Python也这么干过。

Reply all
Reply to author
Forward
0 new messages