elisp中的Y组合子

elisp中的Y组合子,lisp,elisp,lambda-calculus,combinators,y-combinator,Lisp,Elisp,Lambda Calculus,Combinators,Y Combinator,我们可以通过YCombinator定义递归函数,factorial作为示例,如下所示 ;;;艾利斯普 ;;; 这个代码有效。幸亏 ;;; https://www.diegoberrocal.com/blog/2015/10/12/y-combinator-in-emacs-lisp/ (setq词法绑定t);;;词法==静态?? (反联合联合比较器(f) (funcall#’(lambda(x)(funcall f #'(lambda(y)(funcall(funcall x)y))) #"(

我们可以通过
YCombinator
定义递归函数,
factorial
作为示例,如下所示

;;;艾利斯普
;;; 这个代码有效。幸亏
;;; https://www.diegoberrocal.com/blog/2015/10/12/y-combinator-in-emacs-lisp/ 
(setq词法绑定t);;;词法==静态??
(反联合联合比较器(f)
(funcall#’(lambda(x)(funcall f
#'(lambda(y)(funcall(funcall x)y)))
#"(λ(x)(f)
#'(lambda(y)(funcall(funcall x)y)))
)
)
(setq)元因子
#"(lambda(f)"(lambda(n)(如果(eq n 0)1(*n(funcall f(1-n)))
(funcall(YCombinator元阶乘)4);=>24
我已经了解了什么是Y组合子,并且知道它是如何用数学方法定义的

Y: f -> ( (x -> f(x x)) (x -> f(x x)) )
但我发现很难实施。特别是,我对
YCombinator
的定义似乎更接近数学定义,但未能定义
factorial


;; 此代码失败!
(反联合联合比较器(f)
(funcall#’(lambda(x)(funcall f
#'(funcall x)))
#"(λ(x)(f)
#'(funcall x)))
)
)
问题
  • 为什么会这样?我错过什么了吗
  • 为什么我们需要将
    词法绑定设置为
    t
  • (e)lisp翻译程序是否有lambda表达式

  • 你说你理解这个定义:

    Y: f -> ( (x -> f(x x)) (x -> f(x x)) )
    
    您可以在其中展开
    x x
    s以获得以下内容:

    Y: f -> ( (x -> f(y -> x x y)) (x -> f(y -> x x y)) )
    
    你应该看到,这和工作状态是一样的。因此,在纯数学的lambda微积分世界中,您的定义和工作定义是相同的。这导致了一个结论,你的不工作,因为Lisp不生活在一个纯数学的lambda微积分世界。事实确实如此,具体的区别在于Lisp是严格的,这导致它过早地计算
    x
    s,从而无限递归而没有任何结果。用一个数学上不必要的lambda来包装它们,可以解决严格性的问题。最后,如果您试图用一种懒惰的语言实现它,您就不需要这种变通方法。例如,这里有一个代码到Lazy Racket的音译,没有它也可以正常工作:

    #lang lazy
    (定义(YCombinator f)((lambda(x)(f(x)))(lambda(x)(f(xЮЮЮ)))
    (定义元阶乘(lambda(f)(lambda(n)(如果(=n0)1(*n(f(-n1щ)))))
    ((YCombinator元阶乘)4)
    

    至于你的代码为什么使用词法绑定,简单的答案是lambda演算就是这样工作的,试图让它与动态绑定一起工作会使一切变得非常复杂,但没有任何好处。

    如果你想探索Y,我建议不要使用elisp。使用Scheme或其他东西。@tfb很有意思!请你再详细说明一下为什么这个方案是一个更好的选择?我在两种语言中都写Y…一般来说,您应该避免在emacs lisp:1中尖锐地引用lambdas。在我发布的工作代码中,还有
    (funcall x)
    。为什么评估得太早?2.在Haskell中这样做会直接导致错误,因为它是键入的。这很棘手,但可以解决,请参见我的.1。因为它被包装在
    lambda(y)
    的内部,并且lambda的主体在被调用之前不会被计算。2.是的,也许Haskell不是最好的具体例子,因为它的类型系统。不过,我想不出有哪种语言同时具备惰性和足够弱的类型系统来编写它。答案很好!今天我学习了如何使用lambda表达式生成(e)lisp。第二点。。是的,我想知道为什么没有语言可以让我们自由选择是否要打印/未打印、懒惰/不吉利…@Joseph:Monica:你可以在lazy Racket中写出明显的Y。@tfb谢谢。答案已编辑,以用作示例。