Emacs Lisp Symbol (tutorial)

Buy Xah Emacs Tutorial. Master emacs benefits for life.
,

Lisp has symbols concept. Lisp's concept of “symbols” is somewhat like identifiers in other languages, except that lisp symbol stores more than one value. Each lisp symbol has the following “cells” to store things: {name, value, function, property list}.

A symbol's {value, function} cell may be empty, it's said to be “void”. When you try to get a cell's value that's void, it's a lisp error. (a empty cell is not the same as having value of nil.)

In normal coding, you don't need to worry about any of these. The only thing that's useful for most elisp code is property list, but many other higher-level functions do it for you. (i.e. add, remove, properties.) (☛ (info "(elisp) Property Lists"))

Understanding Lisp Symbol cells is important when you do advanced lisp programing. ⁖ macros, create and calling functions at run-time, function inside functions, manipulate evaluation, implementing a language, or any sort of meta-programing. If you don't have a need, you should not exploit these facilities in your program. keep your program normal and simple.

Here's ways to get cell values.

;; check if a variable eval to a lisp symbol
(setq x1 123 )
(symbolp x1)                            ;nil
(setq x2 'xx )
(symbolp x2)                            ;t

;; get a symbol's cell values
(symbol-name 'x1)                       ; "x1"
(symbol-value 'x1)                      ; 123
(symbol-function 'x1)                   ; error. because it's void.
(symbol-plist 'x1)                      ;nil

;; set a symbol's cell values
(symbol-name 'setq)                  ; "setq"
(symbol-value 'setq)                 ; error. because it's void.
(symbol-function 'setq)              ;#<subr setq>
(symbol-plist 'setq)                 ;(byte-compile byte-compile-setq)

Because a symbol can both hold a value and a function, a symbol can be both a variable and function. For example, the symbol buffer-file-name is both a variable and function. (info "(elisp) Symbols") (info "(elisp) Function Cells")

Emacs lisp property list is used extensively in emacs. It is also very useful if you want to write a function with state. For examples, see:

Classification of Emacs Lisp Function

On a separate subject, Emacs Lisp functions are classified into several types.

(info "(elisp) What Is a Function")

;; check if a function is a elisp primitive; i.e. a elisp function written in C
;; arg to subrp is a lisp object, not symbol
(subrp (symbol-function 'goto-char))    ;t
(subrp (symbol-function 'defun))        ;t
(subrp (symbol-function 'list))         ;t
(subrp (symbol-function 'while))        ;t
(subrp (symbol-function '+))            ;t
(subrp (symbol-function 'goto-char))    ;t
(subrp (symbol-function 'beginning-of-line)) ;t
(subrp (symbol-function 'forward-word)) ;t
(subrp (symbol-function 'save-excursion)) ;t

(subrp (symbol-function 'lambda))       ;nil

;; Return SYMBOL's function definition.  Error if that is void.
(symbol-function 'setq)                 ;#<subr setq>

You can use fboundp to check if a function is defined first (it checks a symbol's definition cell), and use boundp to check if a variable is defined (it checkes a symbol's value cell) 〔➤ Emacs Lisp: Check If a {function, variable, feature} is Defined/Loaded

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. 〔➤ Emacs Lisp Idioms: Prompting for User Input〕 ((info "(elisp) Defining Commands"))

When looking for command by apropos-command, you can call it with 【Ctrl+u】 first. It'll then also list functions. 〔➤ Emacs: Finding Functions and Documentation Lookup

Primitive

When coding emacs lisp, it's always good to use elisp Primitive, because Primitive usually means it's fast. You can usually find out whether a function is a primitive by calling describe-function.

(info "(elisp) Functions")

Like it?
Buy Xah Emacs Tutorial
or share
blog comments powered by Disqus