最近看了一下 λ 演算。比如说,众所周知的 λ 演算里没有 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))
1
bleepbloop 2021-04-08 11:32:09 +08:00 1
生活已经很艰难了,为什么要给自己添堵(狗头)
|
2
atuocn 2021-04-08 11:41:22 +08:00 1
只能写一行,难不难用?
|
3
hsfzxjy 2021-04-08 11:51:32 +08:00 via Android
没有 Monad 语法糖就很难受 :doge:
|
4
EPr2hh6LADQWqRVH 2021-04-08 11:57:43 +08:00
就这可读性,告别工作了
|
5
exceldream 2021-04-08 11:59:48 +08:00 via Android
不应该是 haskell 吗
|
6
wellsc 2021-04-08 12:00:41 +08:00
python 的 lambda 就算了,就一玩具
|
7
hahastudio 2021-04-08 12:05:50 +08:00
|
8
aguesuka 2021-04-08 12:07:19 +08:00 via Android
@exceldream 纯正的 lambda 演算就是λ,而没有λ2,λω,λP 。很合理
|
9
iintothewind 2021-04-08 12:08:54 +08:00
fib(99) 会不会很慢?
还是来个伪递归优化的版本吧 |
10
CismonX 2021-04-08 12:18:34 +08:00 via iPhone 3
纯正的 lambda 演算,当然要看 Unlambda 语言。这个语言只有组合子,其他什么都没有 [doge]
它的设计理念基于 SKI combinator calculus,只用其中的 s 和 k 两个组合子,就能做到图灵完备。当然 Unlambda 还有 call/cc,有 promise,有 I/O 函数,所以写起来也挺有趣的 我之前还写过 Unlambda 的几个实现,(见我发过的帖子),实现起来也很有趣 |
11
abersheeran OP |
12
abersheeran OP @avastms 函数式编程宗教教徒震怒!什么,你居然理解不了 Y 组合子,这是你的问题,不是我代码的问题!😀😀😀
|
13
abersheeran OP @CismonX 嗯嗯,只是想给 Python lambda 正名一下,倒也不是想在 Python 里复兴 λ 演算。
几个大佬说不好用,一群菜鸟跟着说不好用。自己也不想想不好用在哪儿。一群人,人云亦云。上一次遇到这事,还是 C 里的 goto 。 |
14
aaaron7 2021-04-08 12:35:28 +08:00
正不正宗的,重要吗,只支持表达式本来就是很不好用的体现。
这和大不大佬,菜不菜鸡没关系,是个人都能用出来 python 的 lambda 难用的一笔。对比 swift 的 closure,c++的 lambda 。 |
15
abersheeran OP @aaaron7 一个语言有一个语言的风格。Python 本身就不鼓励大量使用 lambda,而应该直接 def function 。你拿着其他语言的使用经验来说 Py 匿名函数不好用,那确实不好用。你用 Python 的思维去写 Python,这玩意才好用。明白吗?
我写 Python 就是 Python,写 JavaScript 就是 JavaScript 。我从来不写 JavaScript 风格的 Python,也不写 Python 风格的 JavaScript 。所以我从不觉得 Python lambda 难用,也从不觉得 JavaScript 的箭头匿名函数用不上。 |
16
guyeu 2021-04-08 13:05:14 +08:00
这不 pythonic
|
17
nthhdy 2021-04-08 13:07:49 +08:00
理解 lambda calculus 本身有难度。
用 python 写 lambda calculus 的难度相比之下不算什么。 |
18
chanchan 2021-04-08 13:24:03 +08:00
函数式教徒不应该来这
|
19
aaaron7 2021-04-08 13:32:41 +08:00
@abersheeran 那为啥 java 、c++、swift 、js 都能解决好的需求,到 python 这就不行了呢?
认可一个语言有一个语言的风格,但 python 的这个“风格”还不让人觉得难用吗? 咱能用直觉来看问题吗? |
20
abersheeran OP @aaaron7 喔。C 连 lambda 都不能写,那可真是一个“垃圾”,Python 深受 C 思想荼毒,lambda 也不支持过程,也是个垃圾。你已经得到满意的回答了,可以继续用你的直觉写代码去了。
|
21
abersheeran OP @guyeu 确实,正经写代码,没人这么玩儿。
|
22
aaaron7 2021-04-08 13:40:34 +08:00
@abersheeran
你看清楚我说的话把,我说的是 python 的 lambda 很难用 这不妨碍我觉得 python 是一门非常好用的语言,并且也是我在工作中用的最多的语言之一,用的越多越觉得它的 lambda 很垃圾。 |
23
abersheeran OP @nthhdy 确实 λ 演算的衍生品很复杂,但它本身还是很简单的。我暂时把它的衍生品当一种智力游戏在玩,不会真的去应用。所以目前来看,挺有趣的。
|
24
abersheeran OP @aaaron7 我都说了,Python 的设计就没打算你多用 lambda 。擦汗。你非要把其它语言的 lambda 对应过来,那确实难用的很。你把它当作一个增加了单条语句函数可以不写名称的语法糖的 C 来写,这个东西就好用多了。
|
25
bleepbloop 2021-04-08 13:45:11 +08:00
|
26
abersheeran OP @bleepbloop 这还用翻 PEP 看“Lambdas are neutered anyway.”吗?我以为 python 不鼓励使用 lambda 是一个人尽皆知的事。
|
27
xuegy 2021-04-08 13:51:48 +08:00 via iPhone
想起来第一次学把 MATLAB 代码翻译到 numpy,然后变量名 lambda 就冲突了。我只能说这个名字起得真不好...
|
28
bleepbloop 2021-04-08 13:53:20 +08:00
@abersheeran 其实我是想说->被用掉了。。。
|
29
abersheeran OP @bleepbloop 哈哈哈我误会你了。只是个感概罢了,其实我知道肯定不会出 shortcut 的。-> 用掉了倒在其次,这玩意根据上下文不同,可以编译成不同含义。
|
30
abersheeran OP @bleepbloop 这个 PEP 里的 “Lambdas are neutered anyway” 也很明确态度了。lambda 这玩意以后就这样了,啥东西都不加了。
|
31
ychost 2021-04-08 13:58:31 +08:00
py 的 lambda 可读性太低了
|
32
bleepbloop 2021-04-08 13:58:45 +08:00
@abersheeran 你可以自己改 cpython
|
33
BeautifulSoap 2021-04-08 14:00:31 +08:00 via Android 1
道理我懂,但问题是这和一坨 lambda 难读之间没关系啊
|
34
abersheeran OP @bleepbloop 然后 Guido:Closed. 哈哈哈。上次我提的这个问题 https://v2ex.com/t/765531 Coconut 直接 Python 超集语法,香的很,改 CPython 不如直接用它,然后编译到 Python 。
|
35
SjwNo1 2021-04-08 14:08:50 +08:00
python3.8 好像可以 lambda : (x := 1)
|
37
atuocn 2021-04-09 13:49:03 +08:00
@abersheeran 太激动了吧,这就冒犯你了。看看我写的帖子,用 lamba 做的自然数演算实验。想弄函数式, schema 比这好多了伐,python 连个尾递归优化都没,好意思说函数式。
函数是 first class, python 做到了吗,至少函数定义没有,你必须得先定义函数名字,才能被传参,被使用。弄个半吊子 lamba 来凑活,就不用拿来吹了。一个表达式写多行,被迫续行,还得兼顾缩进,要不然没法读,写起来好玩吗?我看 python 没搞匿名函数,就是缩进语法害的。js 写起来舒服多了。 还有函数式就一定要排斥过程?只要你的过程,中间产物全封闭在函数局部作用域,对外就是个抽象函数,没有副作用。函数是过程的抽象,你管人家怎么实现的。为了你的装逼,写成一个表达式,要搞多少弯弯绕绕。先搞几个 let,loop 宏出来再说。可惜,python 没有宏,恭喜你一行一行写。最后恭喜你,堆栈溢出。 不是一定要夸或者贬低什么,python lambda 就是个补充,解决了一些问题。但也没必要非拿短板来硬套吧。 |
38
abersheeran OP @atuocn 不是……我上面是开玩笑的。我不是函数式教徒,只是模仿一些某些人的口吻。
你说的这些缺点都是客观存在的,所以 Python 代码一般也不鼓励大量使用 lambda 。这个 Y 组合子纯粹是我写着练手,当智力游戏玩的。让你误会了,不好意思啊。 |
39
abersheeran OP @atuocn 😂其实你看我最近的一篇博客就知道,我和你的观点是差不多的。
|
40
nthhdy 2021-04-12 12:05:06 +08:00
@abersheeran #23
它的代换规则确实很简单,但是这种从简单的元素开始“构建一切”的东西,理解如何构建很难。 不怕笑话,我觉得挺难的。比如纯粹用函数表示整数、加减乘除。都写成 lambda,看起来都差不多。 我理解研究人员可能会用吧,现在的程序员普遍程序员普遍用不到。 像 Y combinator 这种东西,就算不知道它是啥也能写出递归。 |
41
abersheeran OP @nthhdy 是的。所以我当它是智力游戏嘛。现实编程里我或许用不到里面任何一个东西,但可以汲取它的思想。
|