I have the following code
(defun avg-damp(f)
#'(lambda(x) (/ (+ (funcall f x) x) 2.0)))
A call
(funcall (avg-damp #'(lambda(v) (* v v))) 10)
returns 55.0 (the correct value) in SBCL but crashes with the following stack in emacs lisp
Debugger entered--Lisp error: (void-variable f)
(funcall f x)
(+ (funcall f x) x)
(/ (+ (funcall f x) x) 2.0)
(lambda (x) (/ (+ ... x) 2.0))(10)
funcall((lambda (x) (/ (+ ... x) 2.0)) 10)
eval((funcall (avg-damp (function ...)) 10))
eval-last-sexp-1(nil)
eval-last-sexp(nil)
call-interactively(eval-last-sexp)
How can I make it work in Emacs lisp?
Calling a function is also known as invocation. The most common way of invoking a function is by evaluating a list. For example, evaluating the list (concat "a" "b") calls the function concat with arguments "a" and "b" . See Evaluation, for a description of evaluation.
To define a function, we use the special form defun. It's followed by the function name and its arguments. The arguments are private, so it does not change anything outside the function. Any other symbol called inside a function will bring its value from outside since Elisp has global scope.
defun is the usual way to define new Lisp functions. It defines the symbol name as a function with argument list args (see Features of Argument Lists) and body forms given by body . Neither name nor args should be quoted.
The let expression is a special form in Lisp that you will need to use in most function definitions. let is used to attach or bind a symbol to a value in such a way that the Lisp interpreter will not confuse the variable with a variable of the same name that is not part of the function.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With