Emacs Lisp
Developer GNU Project | | |
First appeared | 1985 | |
---|---|---|
Stable release | 29.4
/ 22 June 2024 | |
strong | ||
Scope | Dynamic, optionally lexical | |
Platform | Emacs | |
OS | Cross-platform | |
License | GPLv3 | |
Filename extensions | .el, .elc, .eln | |
Website | www | |
Influenced by | ||
Common Lisp, Maclisp |
Emacs Lisp is a
Emacs Lisp code is used to modify, extend and customize Emacs. Those not wanting to write the code themselves the Customize function can be used. It provides a set of preferences pages allowing the user to set options and preview their effect in the running Emacs session. When the user saves their changes, Customize simply writes the necessary Emacs Lisp code to the user's
Besides being a
andEmacs Lisp is also termed Elisp, although there are also older, unrelated Lisp dialects with that name.[3][4]
Compared to other Lisp dialects
Emacs Lisp is most closely related to Maclisp, with some later influence from Common Lisp.[5] It supports imperative and functional programming methods. Lisp was the default extension language for Emacs derivatives such as EINE and ZWEI. When Richard Stallman forked Gosling Emacs into GNU Emacs, he also chose Lisp as the extension language, because of its powerful features, including the ability to treat functions as data. Although the Common Lisp standard had yet to be formulated, Scheme existed at the time but Stallman chose not to use it because of its comparatively poor performance on workstations (as opposed to the minicomputers that were Emacs' traditional home), and he wanted to develop a dialect which he thought would be more easily optimized.[6]
The Lisp dialect used in Emacs differs substantially from the more modern Common Lisp and Scheme dialects used for applications programming. A prominent characteristic of Emacs Lisp is in its use of dynamic rather than lexical scope by default. That is, a function may reference local variables in the scope it is called from, but not in the scope where it was defined. Recently, there has been an ongoing effort to update code to use lexical scoping, for reasons outlined below.
1958 | 1960 | 1965 | 1970 | 1975 | 1980 | 1985 | 1990 | 1995 | 2000 | 2005 | 2010 | 2015 | 2020 | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
LISP 1, 1.5, LISP 2(abandoned) | |||||||||||||||
Maclisp | |||||||||||||||
Interlisp | |||||||||||||||
MDL | |||||||||||||||
Lisp Machine Lisp | |||||||||||||||
Scheme | R5RS | R6RS | R7RS small | ||||||||||||
NIL | |||||||||||||||
ZIL (Zork Implementation Language) | |||||||||||||||
Franz Lisp | |||||||||||||||
Common Lisp | ANSI standard | ||||||||||||||
Le Lisp | |||||||||||||||
MIT Scheme
| |||||||||||||||
XLISP | |||||||||||||||
T | |||||||||||||||
Chez Scheme | |||||||||||||||
Emacs Lisp | |||||||||||||||
AutoLISP | |||||||||||||||
PicoLisp | |||||||||||||||
Gambit | |||||||||||||||
EuLisp | |||||||||||||||
ISLISP | |||||||||||||||
OpenLisp | |||||||||||||||
PLT Scheme
|
Racket | ||||||||||||||
newLISP | |||||||||||||||
GNU Guile | |||||||||||||||
Visual LISP | |||||||||||||||
Clojure | |||||||||||||||
Arc | |||||||||||||||
LFE | |||||||||||||||
Hy | |||||||||||||||
Chialisp |
Example
The development of Emacs Lisp was guided by the goal of providing data structures and features specific to making a versatile text editor over implementing a general-purpose programming language. For example, Emacs Lisp cannot easily read a file a line at a time—the entire file must be read into an Emacs buffer. However, Emacs Lisp provides many features for navigating and modifying buffer text at a sentence, paragraph, or higher syntactic level as defined by modes.
Here follows a simple example of an Emacs extension written in Emacs Lisp. In Emacs, the editing area can be split into separate areas called windows, each displaying a different buffer. A buffer is a region of text loaded into Emacs' memory (possibly from a file) which can be saved into a text document.
Users can press the default C-x 2
split-window-below
. Normally, when the new window appears, it displays the same buffer as the previous one. Suppose we wish to make it display the next available buffer. In order to do this, the user writes the following Emacs Lisp code, in either an existing Emacs Lisp source file or an empty Emacs buffer:
(defun my-split-window-func ()
(interactive)
(split-window-below)
(set-window-buffer (next-window) (other-buffer)))
(global-set-key (kbd "C-x 2") #'my-split-window-func)
The first statement, (defun ...)
, defines a new function, my-split-window-func
, which calls split-window-below
(the old window-splitting function), then tells the new window to display another (new) buffer. The second statement, (global-set-key ...)
re-binds the key sequence "C-x 2" to the new function.
This can also be written using the feature called
(defadvice split-window-below
(after my-window-splitting-advice first () activate)
(set-window-buffer (next-window) (other-buffer)))
This instructs split-window-below
to execute the user-supplied code whenever it is called, after executing the rest of the function. Advice can also be specified to execute before the original function, around it (literally wrapping the original), or to conditionally execute the original function based on the results of the advice.
Emacs 24.4 replaces[8] this defadvice
mechanism with advice-add
, which is claimed to be more flexible and simpler.[9] The advice above could be reimplemented using the new system as:
(defun switch-to-next-window-in-split ()
(set-window-buffer (next-window) (other-buffer)))
(advice-add 'split-window-below :before #'switch-to-next-window-in-split)
These changes take effect as soon as the code is
Source code
Emacs Lisp code is stored in
In order to save time and memory space, much of the functionality of Emacs loads only when required. Each set of optional features shipped with Emacs is implemented by a collection of Emacs code called a
Emacs developers write certain functions in C. These are primitives, also termed built-in functions or subrs. Although primitives can be called from Lisp code, they can only be modified by editing the C source files and recompiling. In
However, because errors in C code can easily lead to
Byte code
Byte-compiling can make Emacs Lisp code execute faster. Emacs contains a
.elc
". Compared to source files, bytecode files load and run faster, occupy less disk space, and use less memory when loaded.
Bytecode still runs more slowly than primitives, but functions loaded as bytecode can be easily modified and re-loaded. In addition, bytecode files are platform-independent. The standard Emacs Lisp code distributed with Emacs is loaded as bytecode, although the matching source files are usually provided for the user's reference as well. User-supplied extensions are typically not byte-compiled, as they are neither as large nor as computationally intensive.
Language features
Notably, the "cl-lib" package implements a fairly large subset of Common Lisp. This package replaces an earlier "cl" package, which would overwrite existing Emacs Lisp function definitions with ones more similar to those found in Common Lisp. The "cl-lib" package, on the other hand, follows Emacs Lisp style guidelines more closely and prefixes each function and macro it defines with "cl-" (e.g., cl-defun
, which doesn't conflict with the name of the built-in defun
), avoiding the unexpected changes in behavior that could occur whenever the "cl" package was loaded.
Emacs Lisp (unlike some other Lisp implementations) does not do
The apel library aids in writing portable Emacs Lisp code, with the help of the polysylabi platform bridge.
Emacs Lisp is a Lisp-2 like Common Lisp, meaning that it has a function namespace which is separate from the namespace it uses for other variables.[11]
From dynamic to lexical scoping
Like MacLisp, Emacs Lisp uses dynamic scope, offering static (or lexical) as an option starting from version 24.[12] It can be activated by setting the file local variable lexical-binding
.[13][14] Before this option was added, one could use the lexical-let
macro from the (now deprecated) "cl" package to provide effective lexical scope.[15]
In dynamic scoping, if a programmer declares a variable within the scope of a function, it is available to subroutines called from within that function. Originally, this was intended as an
See also
- Vim script
References
- ^ "Byte compiling Emacs Lisp". GNU Emacs manual. Retrieved 2024-06-14.
- ^ "Compilation of Emacs Lisp to native code". GNU Emacs manual. Retrieved 2024-06-14.
- ^ "HEDRICK at RUTGERS (Mngr DEC-20's/Dir LCSR Comp Facility" (1981-12-18). ""information about Common Lisp implementation"". Letter to "rpg at SU-AI, jonl at MIT-AI". Archived from the original on 2016-09-20. Retrieved 2019-07-28.
We have some experience in Lisp implementation now, since Elisp (the extended implementation of Rutgers/UCI Lisp) is essentially finished.
{{cite press release}}
: CS1 maint: numeric names: authors list (link) - ^ "Ad for CCA EMACS". Unix Review. December 1984. p. 16.
CCA EMACS and Elisp are trademarks of CCA Uniworks, Inc.
- ^ "GNU Emacs Lisp is largely inspired by Maclisp, and a little by Common Lisp. If you know Common Lisp, you will notice many similarities. However, many features of Common Lisp have been omitted or simplified in order to reduce the memory requirements of GNU Emacs. Sometimes the simplifications are so drastic that a Common Lisp user might be very confused. We will occasionally point out how GNU Emacs Lisp differs from Common Lisp." – from the "History" section of the "Introduction" to the Emacs Lisp Manual, as of Emacs 21
- ^ "So the development of that operating system, the GNU operating system, is what led me to write the GNU Emacs. In doing this, I aimed to make the absolute minimal possible Lisp implementation. The size of the programs was a tremendous concern. There were people in those days, in 1985, who had one-megabyte machines without virtual memory. They wanted to be able to use GNU Emacs. This meant I had to keep the program as small as possible." – from "My Lisp Experiences and the Development of GNU Emacs"
- ^ "Re: [Emacs-diffs] /srv/bzr/emacs/trunk r111086: gmm-utils.el (gmm-flet". Lists.gnu.org. 2012-12-05. Retrieved 2013-08-18.
- ^ "NEWS.24.4".
- ^ "Porting old advice".
- ^ "Appendix C Porting Common Lisp". Gnu.org. Retrieved 2019-10-28.
Lisp programmers will want to note that the current Emacs Lisp compiler does not optimize tail recursion
- ^ "Google Groups". groups.google.com.
- ^ "Emacs 24.1 released". Lists.gnu.org. Retrieved 2013-08-18.
- ^ "Lexical binding". Lists.gnu.org. 2011-04-01. Retrieved 2013-08-18.
- ^ "Dynamic Binding Vs Lexical Binding". EmacsWiki. 2013-05-17. Retrieved 2013-08-18.
- ^ "Obsolete Lexical Binding". GNU Emacs Common Lisp Emulation. GNU Press. Retrieved 27 May 2021.
- ^ "T". People.csail.mit.edu. Retrieved 2013-08-18.
- ISBN 978-3-11-021614-1.
External links
- Official website, GNU Project