V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
abersheeran
V2EX  ›  Python

Python lambda:纯正的 λ 演算味儿

  •  1
     
  •   abersheeran ·
    abersheeran · 9 天前 · 2983 次点击

    最近看了一下 λ 演算。比如说,众所周知的 λ 演算里没有 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 条附言  ·  9 天前
    当然,如果啥时候能出 x -> x**2 这种 shortcut 语法,那就好了。lambda 这个单词确实比较长。
    第 2 条附言  ·  9 天前
    上一条附言只是个感慨哈。真想用 x -> x**2 的朋友可以试试 https://github.com/evhub/coconut 一个 Python 超集语言,支持 |> 管道 -> 匿名函数。可以编译到 Python 。
    41 条回复    2021-04-12 12:22:27 +08:00
    bleepbloop
        1
    bleepbloop   9 天前   ❤️ 1
    生活已经很艰难了,为什么要给自己添堵(狗头)
    atuocn
        2
    atuocn   9 天前   ❤️ 1
    只能写一行,难不难用?
    hsfzxjy
        3
    hsfzxjy   9 天前 via Android
    没有 Monad 语法糖就很难受 :doge:
    avastms
        4
    avastms   9 天前
    就这可读性,告别工作了
    exceldream
        5
    exceldream   9 天前 via Android
    不应该是 haskell 吗
    wellsc
        6
    wellsc   9 天前
    python 的 lambda 就算了,就一玩具
    aguesuka
        8
    aguesuka   9 天前 via Android
    @exceldream 纯正的 lambda 演算就是λ,而没有λ2,λω,λP 。很合理
    iintothewind
        9
    iintothewind   9 天前
    fib(99) 会不会很慢?
    还是来个伪递归优化的版本吧
    CismonX
        10
    CismonX   9 天前 via iPhone   ❤️ 3
    纯正的 lambda 演算,当然要看 Unlambda 语言。这个语言只有组合子,其他什么都没有 [doge]

    它的设计理念基于 SKI combinator calculus,只用其中的 s 和 k 两个组合子,就能做到图灵完备。当然 Unlambda 还有 call/cc,有 promise,有 I/O 函数,所以写起来也挺有趣的

    我之前还写过 Unlambda 的几个实现,(见我发过的帖子),实现起来也很有趣
    abersheeran
        11
    abersheeran   9 天前
    @atuocn 但凡你学过一点语言相关的东西,就知道,这不是只允许一行,是只允许一个表达式,至于你用几行,那是你的自由。而但凡看过 λ 演算,你应该知道那玩意里就不存在什么过程(多表达式),一个表达式就够用了。

    @hsfzxjy 哈哈哈,确实是有 Python 的库支持 Monad,不过我觉得在 Python 里太多余了。
    abersheeran
        12
    abersheeran   9 天前
    @avastms 函数式编程宗教教徒震怒!什么,你居然理解不了 Y 组合子,这是你的问题,不是我代码的问题!😀😀😀
    abersheeran
        13
    abersheeran   9 天前   ❤️ 1
    @CismonX 嗯嗯,只是想给 Python lambda 正名一下,倒也不是想在 Python 里复兴 λ 演算。

    几个大佬说不好用,一群菜鸟跟着说不好用。自己也不想想不好用在哪儿。一群人,人云亦云。上一次遇到这事,还是 C 里的 goto 。
    aaaron7
        14
    aaaron7   9 天前
    正不正宗的,重要吗,只支持表达式本来就是很不好用的体现。

    这和大不大佬,菜不菜鸡没关系,是个人都能用出来 python 的 lambda 难用的一笔。对比 swift 的 closure,c++的 lambda 。
    abersheeran
        15
    abersheeran   9 天前   ❤️ 1
    @aaaron7 一个语言有一个语言的风格。Python 本身就不鼓励大量使用 lambda,而应该直接 def function 。你拿着其他语言的使用经验来说 Py 匿名函数不好用,那确实不好用。你用 Python 的思维去写 Python,这玩意才好用。明白吗?

    我写 Python 就是 Python,写 JavaScript 就是 JavaScript 。我从来不写 JavaScript 风格的 Python,也不写 Python 风格的 JavaScript 。所以我从不觉得 Python lambda 难用,也从不觉得 JavaScript 的箭头匿名函数用不上。
    guyeu
        16
    guyeu   9 天前
    这不 pythonic
    nthhdy
        17
    nthhdy   9 天前
    理解 lambda calculus 本身有难度。
    用 python 写 lambda calculus 的难度相比之下不算什么。
    chanchan
        18
    chanchan   9 天前
    函数式教徒不应该来这
    aaaron7
        19
    aaaron7   9 天前
    @abersheeran 那为啥 java 、c++、swift 、js 都能解决好的需求,到 python 这就不行了呢?

    认可一个语言有一个语言的风格,但 python 的这个“风格”还不让人觉得难用吗?

    咱能用直觉来看问题吗?
    abersheeran
        20
    abersheeran   9 天前
    @aaaron7 喔。C 连 lambda 都不能写,那可真是一个“垃圾”,Python 深受 C 思想荼毒,lambda 也不支持过程,也是个垃圾。你已经得到满意的回答了,可以继续用你的直觉写代码去了。
    abersheeran
        21
    abersheeran   9 天前
    @guyeu 确实,正经写代码,没人这么玩儿。
    aaaron7
        22
    aaaron7   9 天前
    @abersheeran
    你看清楚我说的话把,我说的是 python 的 lambda 很难用

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

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

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

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

    你说的这些缺点都是客观存在的,所以 Python 代码一般也不鼓励大量使用 lambda 。这个 Y 组合子纯粹是我写着练手,当智力游戏玩的。让你误会了,不好意思啊。
    abersheeran
        39
    abersheeran   8 天前
    @atuocn 😂其实你看我最近的一篇博客就知道,我和你的观点是差不多的。
    nthhdy
        40
    nthhdy   5 天前
    @abersheeran #23

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

    我理解研究人员可能会用吧,现在的程序员普遍程序员普遍用不到。
    像 Y combinator 这种东西,就算不知道它是啥也能写出递归。
    abersheeran
        41
    abersheeran   5 天前
    @nthhdy 是的。所以我当它是智力游戏嘛。现实编程里我或许用不到里面任何一个东西,但可以汲取它的思想。
    关于   ·   帮助文档   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2196 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 13:58 · PVG 21:58 · LAX 06:58 · JFK 09:58
    ♥ Do have faith in what you're doing.