我们可以通过Y组合子
定义递归函数,以阶乘
为例,如下所示:
;;; elisp
;;; This code works. Thanks to
;;; https://www.diegoberrocal.com/blog/2015/10/12/y-combinator-in-emacs-lisp/
(setq lexical-binding t) ;;; lexical == static ??
(defun YCombinator (f)
(funcall #'(lambda (x) (funcall f
#'(lambda (y) (funcall (funcall x x) y))))
#'(lambda (x) (funcall f
#'(lambda (y) (funcall (funcall x x) y))))
)
)
(setq meta-factorial
#'(lambda (f) #'(lambda (n) (if (eq n 0) 1 (* n (funcall f (1- n)))))))
(funcall (YCombinator meta-factorial) 4) ;; ===> 24
我已经了解了什么是Y组合子,并知道它如何以数学方式定义。
Y: f -> ( (x -> f(x x)) (x -> f(x x)) )
但我发现它很难实现。特别是,我的YCombinator
的定义似乎更接近数学定义,无法定义factorial
。
;; this code fails!
(defun YCombinator (f)
(funcall #'(lambda (x) (funcall f
#'(funcall x x)))
#'(lambda (x) (funcall f
#'(funcall x x)))
)
)
问题
- 为什么会出现这种情况?我有什么遗漏吗?
- 为什么我们需要将
lexical-binding
设置为t
? - 是否存在将 lambda 表达式转换成 (e)lisp 的翻译器?