ELisp: Function Types: Lambda, Primitive, Special Form, Macro, Command

By Xah Lee. Date: . Last updated: .

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. For example: {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. For example: {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 (For example, special form and macro do not.), and whether a function is user-oriented (For example, 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:

KindPredicateExample
Special Formspecial-form-pprogn
Macromacropwhen
Commandcommandpcount-words
Prefix Commandnonehelp-command
Functionfunctionpfile-name-directory
Constantnonedir-locals-file
User Optionnoneafter-save-hook
Variableboundpbuffer-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-filedisplay-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:

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 function/variable 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.

Lisp Symbol

Emacs Lisp Function