3

How does one access the declare specification of a function?

Edit: After the answer of npostavs I have to correct myself.

As long as a function is not byte-compiled the declare forms are still in its symbol-function. Where do they go after byte-compilation?

Example: (content of scratch buffer with lisp code and evaluation results)

(defun test (&rest args)
  "Function with declare form."
  (declare (indent 1))
  (interactive)
  (message args))
;; repl: test

(symbol-function 'test)
;; repl: (lambda (&rest args) "Function with declare form." (interactive) (message args))

(symbol-plist 'test)
;; repl: (lisp-indent-function 1)

That means the declare forms are not contained in the function cell of the symbol after the defun.

(defun test (&rest args)
  "Function with declare form."
  (interactive)
  (declare (indent 1))
  (message args))

(symbol-function 'test)
(lambda (&rest args) "Function with declare form." (interactive) (declare (indent 1)) (message args))

(setf f (byte-compile 'test))
#[(&rest args) "\301!\207" [args message] 2 "Function with declare form." nil]

What is the right way to access the declare information of a function in elisp?

1
  • Good question.. – Drew Jan 3 '16 at 3:49
6

Actually you have the declare in the wrong place, it should go before (interactive):

(defun test (&rest args)
  "Function with declare form."
  (declare (indent 1))
  (interactive)
  (message args))

Then if you macroexpand you can see what it does:

(prog1
    (defalias 'test
      #'(lambda
          (&rest args)
          "Function with declare form."
          (interactive)
          (message args)))
  (put 'test 'lisp-indent-function '1))

As you can see, the declare form itself is not stored, but defun interprets and rewrites it into code with the needed effect. Also note that the effect works on the symbol, not the function itself.

To reconstruct a declare form you would have to see what each kind of declaration does; the effects are listed in defun-declarations-alist and macro-declarations-alist (you can see this by looking at the definitions of defun and defmacro). Almost all work by putting a property on the symbol, so you could just get the corresponding property. The only exception (as of Emacs 24.5) is advertised-calling-convention which stores the preferred signature in advertised-signature-table, a hash table with the function itself as the key.

3
  • And a good answer. – Drew Jan 3 '16 at 3:49
  • This is almost the right answer and I will mark it as such primarily because of its simplicity. You ask: "Why the 'almost'?" Because the information could be stored at some other place, e.g., an hash-table that captures all functions with declare forms. The right path to go is to look at defmacro, defun and most important defun-declarations-alist where the function properties and their actions are defined. Maybe, it is even possible to reconstruct the declare forms via the comparison of the symbol properties with the elements of defun-declarations-alist. Difficult: (e.g., debug). – Tobias Jan 3 '16 at 6:05
  • @Tobias ah, good point about defun-declarations-alist, I added some info about that to the answer. debug is not more difficult than the other declarations though. – npostavs Jan 3 '16 at 13:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.