Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't application of function returned by elisp macro work?

For example, here is a macro:

(defmacro my-macro (x y)
  (if (> x 0) 
  `(lambda (z) (+ z ,y))
`(lambda (z) (+ ,x z))))

and (my-macro 2 3) returns (lambda (z) (+ z 3))

However, ((my-macro 2 3) 1) returns an error saying,

 Debugger entered--Lisp error:

 (invalid-function (my-macro 2 3))
  ((my-macro 2 3) 1)
  eval(((my-macro 2 3) 1))
  eval-last-sexp-1(nil)
  eval-last-sexp(nil)
  call-interactively(eval-last-sexp nil nil)

What am I missing?

like image 242
user328148 Avatar asked Jun 21 '11 22:06

user328148


1 Answers

Emacs Lisp requires the first element of a list form to be a built-in function (or subr), a lambda-expression (i.e. (lambda LIST . LIST)) or a macro lambda-expression (i.e. (macro lambda LIST . LIST)). The first element can also be a symbol whose function slot contains a valid first element.

(my-macro 2 3) doesn't have the required form, so it's an invalid function.

If you're used to Scheme, where the function part of a function call is evaluated normally, note that this can't work identically in Lisp where functions have a different namespace ((f 3) looks up f's function slot, whereas the value of f is normally its value slot).

If you want to evaluate a function like a normal value, you can use funcall or apply.

(funcall (my-macro 2 3) 1)
like image 106
Gilles 'SO- stop being evil' Avatar answered Nov 16 '22 19:11

Gilles 'SO- stop being evil'