Elisp: Types of Functions
Types of Functions
Emacs Lisp manual uses the following terms to distinguish different types of functions. For advanced lisp programing, you need to understand them.
- lambda expression
-
Anonymous function. Usually temp functions. Usually created by
lambda
. - Primitive
- (aka subr, builtin function.) elisp function implemented in C. e.g. {
list
,car
,append
,point
, etc}. Typically the most fundamental ones. - special form
-
a function that doesn't eval in the normal way and implemented in C. e.g. {
if
,cond
,and
,or
,while
,progn
}. (normally, arguments to a function are all evaluated first.) - macro
-
Similar to “special form”, but defined by lisp expression, by
defmacro
. i.e. the arguments are not eval'd, and you can manipulate them and eval them. - command
-
functions that can be called by
command-execute
. Typically,defun
with Interactive Form. All functions you can call by “M-x” are commands. - Function
-
The catch all. Lambda expression, primitive, special form, macro, command, are all functions. And a function not any of the above is also a function. Usually created by
defun
.
Note: Most of these are not mutually exclusive. For example, forward-word
is a command, but is also a primitive, and any special form by definition is also a primitive.
These distinction of functions are useful because they help you understand if arguments are evaluated in standard way or not (e.g. special form and macro do not.), and whether a function is user-oriented (e.g. command), and whether a function is a primitive, it usually means it's fast and fundamental to elisp.
Note: there are more, but the above are the basics. For detail, see What Is a Function (ELISP Manual)
Classification of Symbols in Emacs Lisp Manual
In emacs lisp manual, each symbol has one of these indicator prefix:
Kind | Predicate | Example |
---|---|---|
Special Form | special-form-p | progn |
Macro | macrop | when |
Command | commandp | count-words |
Prefix Command | none | help-command |
Function | functionp | file-name-directory |
Constant | none | dir-locals-file |
User Option | none | after-save-hook |
Variable | boundp | buffer-file-name |
Note: there are only 1 Prefix Command in elisp manual:
help-command
Note: there are only 2 constants in elisp manual: • dir-locals-file • display-buffer-fallback-action
See also: Elisp: Symbol
How to Check a Symbol's “type”
Here's how to check if a symbol is which:
;; check if a symbol is special form (special-form-p 'progn) ; t ;; check if a symbol is macro (macrop 'when ) ; t ;; check if a symbol is command (commandp 'count-words ) ; t ;; check if a symbol is function (this includes special form and macro). In other words, the symbol is callable (functionp 'buffer-file-name) ; t ;; check if a symbol is variable (boundp 'buffer-file-name) ; t
The following don't have predicate to check:
- Prefix Command
- Constant
- User Option
Most useful are fboundp
and boundp
.
fboundp
- Return true if a function is defined first. (that is, symbol's function cell is not empty. 〔see Elisp: Symbol〕 )
boundp
- Return true if a variable is defined. (That is, symbol's value cell is not empty) 〔see Elisp: Check If a Symbol is Defined〕
How to Check for Primitive
Use subrp
on a symbol's function cell to check if a function is a primitive.
;; check if a function is a elisp primitive; i.e. a elisp function written in C ;; arg to subrp must be a lisp object, not symbol ;; these are core lisp functions, implemented in C (subrp (symbol-function 'list)) ;t (subrp (symbol-function '+)) ;t ;; these are special forms, implemented in C (subrp (symbol-function 'while)) ;t (subrp (symbol-function 'save-excursion)) ;t ;; these are commands, implemented in C (subrp (symbol-function 'goto-char)) ;t (subrp (symbol-function 'beginning-of-line)) ;t (subrp (symbol-function 'forward-word)) ;t ;; lambda is a macro. (subrp (symbol-function 'lambda)) ;nil ;; Return a symbol's function cell value (symbol-function 'setq) ;#<subr setq>
Command vs Non-Command
For practical emacs lisp programing, the most important concept here is “command”. Commands are basically (defun …)
with (interactive …)
clause. Function defined without the “interactive” can only be called by other elisp functions. The “interactive” function also provide many ways to automatically feed arguments to your function when emacs user calls your function.
〔see Elisp: Get User Input〕
(
Defining Commands (ELISP Manual)
)
For search function or list functions, see Emacs: List All Functions
To search all symbols, Alt+x apropos
.