We can define a recursive function, factorial
as an example, by YCombinator
as follows
;;; 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
I have learned what a Y combinator is, and knew how it is defined in a mathematical way.
Y: f -> ( (x -> f(x x)) (x -> f(x x)) )
But I found it hard to implement. In particular, my definition of YCombinator
, which seems more closer to the mathematical definition, fails to define factorial
.
;; this code fails!
(defun YCombinator (f)
(funcall #'(lambda (x) (funcall f
#'(funcall x x)))
#'(lambda (x) (funcall f
#'(funcall x x)))
)
)
Questions
- Why is this the case? Did I miss something?
- Why do we need to set
lexical-binding
tot
? - Is there a lambda-expression to (e)lisp translator?