如何改一段Scheme的closure代码到elisp?

在尝试改一段scheme代码

#+BEGIN_SRC scheme
(define (average-damp f)
  (lambda (x) (average x (f x))))
(define (average x y)
  (/ (+ x y) 2))
(define (square x)
  (* x x))
((average-damp square) 10)
#+END_SRC

#+RESULTS:
: 55

开始以为可能很简单,
define --> defun
/ 2 --> / 2.0

#+begin_src emacs-lisp :session sicp
(defun average-damp(f)
  (lambda (x) (average x (f x))))
(defun average(x y)
     (/ (+ x y) 2.0))
(defun square(x)
  (* x x))
((average-damp 'square) 10)
#+end_src

报错rogn: Invalid function: (average-damp square) 后, 读了读funcall和apply文档,

试着改了改, 但越改越复杂.

求解法,

另外, elisp里的closure一般怎么写? 求个推荐博文.


(defun average-damp (f)
  (lambda (x) (average x (funcall f x))))

(defun average (x y)
  ;; Keep the float
  (/ (+ x y) 2.0))

(defun square (x)
  (* x x))

(funcall (average-damp #'square) 10)

什么叫closure怎么写?closure不是写lambda时的副产物吗,又没有人会直接手写closure。


   When you write a list as an expression in your program, you specify
which function to call, and how many arguments to give it, in the text
of the program.  Usually that’s just what you want.  Occasionally you
need to compute at run time which function to call.  To do that, use the
function ‘funcall’.  When you also need to determine at run time how
many arguments to pass, use ‘apply’.

Funcall怎么用我觉得这里应该说清楚了,当你需要运行时构造一个函数,并调用的时候,就用funcall。

1 个赞

需要加 ’ :lexical t`, 不然报错.

emacs lisp 的 closure 不是这么写的么 (滑稭 (每日迷惑行为 1/1

(closure ((x . 1) t) (x) 1)
(defun average-damp (f*)
  `(closure (,(cons 'f f*) t) (x) (average x (funcall f x))))

写成这样不用

也可以运行。

阿伟,你又想手写闭包哦

可以是可以,但是这算实现细节吧。手写闭包不加lexical binding感觉有点糙快猛。