Python lambda:纯正的 λ 演算味儿

2021-04-08 11:27:24 +08:00
 abersheeran

最近看了一下 λ 演算。比如说,众所周知的 λ 演算里没有 a = b,赋值都靠函数参数来搞定。而 Python 也不允许你在 lambda 里写赋值操作,如果学习过 λ 演算,写 Python 的 lambda 其实感觉还行,至少不会说它难用。

看的时候顺便整了个活,Y 组合子。https://gist.github.com/abersheeran/80709d4ffd7e83c1206dbcc8df11d4d5

Y = lambda g: (lambda f: g(lambda arg: f(f)(arg))) (lambda f: g(lambda arg: f(f)(arg)))

if __name__ == "__main__":
    fib = Y(lambda f: lambda n: (1 if n < 3 else f(n-1) + f(n-2)))
    print(fib(10))
4594 次点击
所在节点    Python
41 条回复
abersheeran
2021-04-08 13:37:06 +08:00
@guyeu 确实,正经写代码,没人这么玩儿。
aaaron7
2021-04-08 13:40:34 +08:00
@abersheeran
你看清楚我说的话把,我说的是 python 的 lambda 很难用

这不妨碍我觉得 python 是一门非常好用的语言,并且也是我在工作中用的最多的语言之一,用的越多越觉得它的 lambda 很垃圾。
abersheeran
2021-04-08 13:42:14 +08:00
@nthhdy 确实 λ 演算的衍生品很复杂,但它本身还是很简单的。我暂时把它的衍生品当一种智力游戏在玩,不会真的去应用。所以目前来看,挺有趣的。
abersheeran
2021-04-08 13:44:48 +08:00
@aaaron7 我都说了,Python 的设计就没打算你多用 lambda 。擦汗。你非要把其它语言的 lambda 对应过来,那确实难用的很。你把它当作一个增加了单条语句函数可以不写名称的语法糖的 C 来写,这个东西就好用多了。
bleepbloop
2021-04-08 13:45:11 +08:00
abersheeran
2021-04-08 13:48:17 +08:00
@bleepbloop 这还用翻 PEP 看“Lambdas are neutered anyway.”吗?我以为 python 不鼓励使用 lambda 是一个人尽皆知的事。
xuegy
2021-04-08 13:51:48 +08:00
想起来第一次学把 MATLAB 代码翻译到 numpy,然后变量名 lambda 就冲突了。我只能说这个名字起得真不好...
bleepbloop
2021-04-08 13:53:20 +08:00
@abersheeran 其实我是想说->被用掉了。。。
abersheeran
2021-04-08 13:55:49 +08:00
@bleepbloop 哈哈哈我误会你了。只是个感概罢了,其实我知道肯定不会出 shortcut 的。-> 用掉了倒在其次,这玩意根据上下文不同,可以编译成不同含义。
abersheeran
2021-04-08 13:56:47 +08:00
@bleepbloop 这个 PEP 里的 “Lambdas are neutered anyway” 也很明确态度了。lambda 这玩意以后就这样了,啥东西都不加了。
ychost
2021-04-08 13:58:31 +08:00
py 的 lambda 可读性太低了
bleepbloop
2021-04-08 13:58:45 +08:00
@abersheeran 你可以自己改 cpython
BeautifulSoap
2021-04-08 14:00:31 +08:00
道理我懂,但问题是这和一坨 lambda 难读之间没关系啊
abersheeran
2021-04-08 14:01:03 +08:00
@bleepbloop 然后 Guido:Closed. 哈哈哈。上次我提的这个问题 https://v2ex.com/t/765531 Coconut 直接 Python 超集语法,香的很,改 CPython 不如直接用它,然后编译到 Python 。
SjwNo1
2021-04-08 14:08:50 +08:00
python3.8 好像可以 lambda : (x := 1)
no1xsyzy
2021-04-08 14:30:01 +08:00
@SjwNo1 不会影响父作用域
atuocn
2021-04-09 13:49:03 +08:00
@abersheeran 太激动了吧,这就冒犯你了。看看我写的帖子,用 lamba 做的自然数演算实验。想弄函数式, schema 比这好多了伐,python 连个尾递归优化都没,好意思说函数式。

函数是 first class, python 做到了吗,至少函数定义没有,你必须得先定义函数名字,才能被传参,被使用。弄个半吊子 lamba 来凑活,就不用拿来吹了。一个表达式写多行,被迫续行,还得兼顾缩进,要不然没法读,写起来好玩吗?我看 python 没搞匿名函数,就是缩进语法害的。js 写起来舒服多了。

还有函数式就一定要排斥过程?只要你的过程,中间产物全封闭在函数局部作用域,对外就是个抽象函数,没有副作用。函数是过程的抽象,你管人家怎么实现的。为了你的装逼,写成一个表达式,要搞多少弯弯绕绕。先搞几个 let,loop 宏出来再说。可惜,python 没有宏,恭喜你一行一行写。最后恭喜你,堆栈溢出。

不是一定要夸或者贬低什么,python lambda 就是个补充,解决了一些问题。但也没必要非拿短板来硬套吧。
abersheeran
2021-04-09 14:26:06 +08:00
@atuocn 不是……我上面是开玩笑的。我不是函数式教徒,只是模仿一些某些人的口吻。

你说的这些缺点都是客观存在的,所以 Python 代码一般也不鼓励大量使用 lambda 。这个 Y 组合子纯粹是我写着练手,当智力游戏玩的。让你误会了,不好意思啊。
abersheeran
2021-04-09 14:27:29 +08:00
@atuocn 😂其实你看我最近的一篇博客就知道,我和你的观点是差不多的。
nthhdy
2021-04-12 12:05:06 +08:00
@abersheeran #23

它的代换规则确实很简单,但是这种从简单的元素开始“构建一切”的东西,理解如何构建很难。
不怕笑话,我觉得挺难的。比如纯粹用函数表示整数、加减乘除。都写成 lambda,看起来都差不多。

我理解研究人员可能会用吧,现在的程序员普遍程序员普遍用不到。
像 Y combinator 这种东西,就算不知道它是啥也能写出递归。

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

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

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

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

© 2021 V2EX