Elisp (Emacs Lisp) is a dialect of the LispLanguage
. It is the extension language of Emacs, as well as the language that most of the editor as-distributed is written in. It is as portable as Emacs itself; i.e. it runs on just about any computer you can think of. It has distinct function and value cells, like CommonLisp
. (There are actually 4 cells.)
Elisp is byte-compiled, and thus fairly slow. However, the ByteCode
s are architecture independent, and thus are also portable.
Elisp is a rather old-fashioned Lisp dialect, based on MacLisp
(named for MitProjectMac
not for AppleMac?
). Most importantly:
I revised this list to reflect the clarifications made below. I believe that Elisp is one of the most underappreciated languages around - it's very good, and the development environment is absolutely excellent. -- LukeGorrie
It should also be noted that Elisp is very well suited for writing interactive text-based programs. It includes:
- A string datatype that supports key-value dictionaries over ranges of characters. Some keys, like face, are specially interpreted by the display code; others can be used to record any state/context that a program wants to associate with text (whether in a string or a buffer.)
- A powerful "buffer" datatype, which has efficient text-manipulation operations, its own scope for variables, its own keymap, and its own hooks for modification and so on. Buffers are a powerful program structuring construct - somewhat similar to an object system. Buffers used by your program need not be visible to or accessible by the user.
- A simple and uniform programming interface for writing individual commands that operate on buffers and interact with a user.
- A rich set of user-input commands with validation (interactive). Asking the user to input a file or directory name, open buffer name, number, character or string are all 1-line operations using the same interface and enhancements as the rest of Emacs.
- A simple windowing system, with operations like "show this buffer somewhere on the screen" and "show this message to the user".
- Timers that can execute code at a certain time (expressed as an interval or absolute time), as well as after n seconds of idle time. There is also a with-timeout handler that will give up and execute a default action after waiting for input.
- The virtual machine runs on every platform ever, in multiple graphical and text-based environments.
- As of version 24 Emacs has a package manager which you can use to distribute your program as well as for dependency resolution.
Tutorials can be found at:
Just a comment on elisp's dynamic scope. You can use lexical scope with the macro lexical-let
GNU Emacs version 24 lets you specify -*- lexical-binding: t -*- in the first line. -- Devon
And XEmacs has hash tables, at least. So does GNU, as of version 21.
You can also get structures with defstruct (like lexical-let, a part of the cl
;-) -- LukeGorrie
Elisp can be made to approximate CommonLisp
with the CL package. There's even a (very incomplete) implementation of the CommonLispObjectSystem
implementation called EIEIO.
Yes, you can build all these things on top of elisp. That's when an implementation issue, not mentioned above, bites you: elisp has no native-code compiler, and what it does
have is really very slow. So yes, you can build these other things, but there tends to be a performance penalty. Elisp is slow enough already :-). -- GarethMcCaughan
In one sense, this is an advantage - it means the compiled files are portable across architectures. Some people think emacs is an editor. This is wrong. Just think of emacs as a portable development environment. :-) -- AlainPicard
Oh yes, portability is a huge advantage and it's worth giving up some performance for. But, having made that trade-off, it stops being true that not having a decent range of data structures and control structures implemented in the language itself isn't a problem. (Incidentally, I have no idea why you apparently think I think Emacs is only an editor...) -- GarethMcCaughan
I don't think that the performance issue is as bad as that. Yes, the compiler only produces ByteCode
, and the byte-code interpreter is not very fast (overhead to ease debugging etc.) The compiler does some optimization, it is quite good with control structures but it can't eliminate any variables and that limits what it can optimize. When you define your own control structures you usually do this using macros, and the built in control structures. As the macros are expanded at compile time and the compiler optimizes, the result is usually as fast as using the primitives. Thus there is no runtime penalty for defining your own control structures. -- LennartStaflin
Quite so, and worth mentioning that CommonLisp
's fancy control structures are also implemented with macros. It's just TheLispWay?
I looked briefly at EIEIO, which is not so much an implementation of CLOS as a class system with a lot of shared syntax. It lacks MultipleDispatch
, the ability to dispatch on built-in types, and MetaObjectProtocol
. (But it got method combinations.) It seems to lack both the power of CLOS and the simplicity of the surrounding language. For myself, I'm writing (as an exercise) simple macro similar to OCaml's 'object' to play with instead. -- JesseMillikan
Note that variables bound with lexical-let are never released, even if they are never used. Try
(loop for i from 1 to 100000 collect (lexical-let ((x i)) '()))
and watch it eat memory. So making infinity (ZeroOneInfinity
) lexical variables is out of the question except for very small values of infinity. --JesseMillikan
The above statement seems to be false. See the related StackOverflow
What do the square brackets mean?
(vector 'a 'b 'c)
[a b c]
While editing my source files in Emacs, I would like to do code analysis in the background. As far as I can tell, Elisp does not have anything like threads. Any suggestions or pointers to how I can do a time-consuming operation in the background?
Use the start-process function (and associated process control functions - there is an example in the definition of compile-internal in the compile.el file.
might also be useful.
Parts of Elisp will feel familiar to anyone who has programmed using ObjectiveCee
. This is because much of the Cocoa text system is a reimplementation of Emacs, and Objc lends itself to a nested Lisp-like calling style.
See also: SampleEmacsConfig