elisp functions as parameters and as return value

前端 未结 2 1378
庸人自扰
庸人自扰 2021-01-02 05:26

I have the following code

(defun avg-damp(f) 
    #\'(lambda(x) (/ (+ (funcall f x) x) 2.0)))

A call

(funcall (avg-damp #         


        
相关标签:
2条回答
  • 2021-01-02 05:41

    A tricky question, but finally got this figured out. The problem is that #' in the definition of avg-damp makes the compiler compile the lambda function at the time when avg-damp itself is compiled, before the actual value of f is known. You need to delay the compilation of this function to a later point in time, when avg-damp is called, like this:

    (defun avg-damp (f)
       `(lambda(x) (/ (+ (funcall ,f x) x) 2.0)))
    
    (funcall (avg-damp #'(lambda(v) (* v v))) 10)
    

    Backquoting does the trick.

    Edit: Of course, the whole problem goes away if you define avg-damp in an uncurried form, such as this:

    (defun avg-damp (f x)
       (/ (+ (funcall f x) x) 2.0))
    
    (funcall 'avg-damp #'(lambda(v) (* v v)) 10)
    

    But I guess you have your reasons not to do so.

    0 讨论(0)
  • 2021-01-02 05:51

    This style of programming does not work in plain Emacs Lisp. Emacs Lisp uses dynamic binding and languages like Scheme and Common Lisp are using lexical binding. Your code exposes the difference. See: Extent in Emacs Lisp

    See also this question: How do I do closures in Emacs Lisp? and the 'solution' with lexical-let. lexical-let is an extension for Emacs Lisp in the "cl" package.

    See also: since Emacs 24.1 there is optional lexical binding. Learn how to use it: using lexical binding.

    0 讨论(0)
提交回复
热议问题