Next: Obsolete Features, Previous: Common Lisp Compatibility, Up: GNU Emacs Common Lisp Emulation [Contents][Index]
This package is meant to be used as an extension to Emacs Lisp, not as an Emacs implementation of true Common Lisp. Some of the remaining differences between Emacs Lisp and Common Lisp make it difficult to port large Common Lisp applications to Emacs. For one, some of the features in this package are not fully compliant with ANSI or Steele; see Common Lisp Compatibility. But there are also quite a few features that this package does not provide at all. Here are some major omissions that you will want to watch out for when bringing Common Lisp code into Emacs.
foo
in one place and Foo
or FOO
in another.
Emacs Lisp will treat these as three distinct symbols.
Some Common Lisp code is written entirely in upper case. While Emacs
is happy to let the program’s own functions and variables use
this convention, calls to Lisp builtins like if
and
defun
will have to be changed to lower case.
let
bindings apply only to references physically within their bodies (or
within macro expansions in their bodies). Traditionally, Emacs Lisp
uses dynamic scoping wherein a binding to a variable is visible
even inside functions called from the body.
See Dynamic Binding in GNU Emacs Lisp Reference Manual.
Lexical binding is available since Emacs 24.1, so be sure to set
lexical-binding
to t
if you need to emulate this aspect
of Common Lisp. See Lexical Binding in GNU Emacs Lisp Reference Manual.
Here is an example of a Common Lisp code fragment that would fail in
Emacs Lisp if lexical-binding
were set to nil
:
(defun map-odd-elements (func list) (loop for x in list for flag = t then (not flag) collect (if flag x (funcall func x)))) (defun add-odd-elements (list x) (map-odd-elements (lambda (a) (+ a x)) list))
With lexical binding, the two functions’ usages of x
are
completely independent. With dynamic binding, the binding to x
made by add-odd-elements
will have been hidden by the binding
in map-odd-elements
by the time the (+ a x)
function is
called.
Internally, this package uses lexical binding so that such problems do
not occur. See Obsolete Lexical Binding, for a description of the obsolete
lexical-let
form that emulates a Common Lisp-style lexical
binding when dynamic binding is in use.
'
,
whereas Emacs Lisp’s parser just treats quote as a special case.
Some Lisp packages use reader macros to create special syntaxes
for themselves, which the Emacs parser is incapable of reading.
#
that the Emacs Lisp parser
won’t understand. For example, ‘#| … |#’ is an
alternate comment notation, and ‘#+lucid (foo)’ tells
the parser to ignore the (foo)
except in Lucid Common
Lisp.
package:symbol
or package::symbol
.
Emacs Lisp has a single namespace for all interned symbols, and
then uses a naming convention of putting a prefix like cl-
in front of the name. Some Emacs packages adopt the Common Lisp-like
convention of using cl:
or cl::
as the prefix.
However, the Emacs parser does not understand colons and just
treats them as part of the symbol name. Thus, while mapcar
and lisp:mapcar
may refer to the same symbol in Common
Lisp, they are totally distinct in Emacs Lisp. Common Lisp
programs that refer to a symbol by the full name sometimes
and the short name other times will not port cleanly to Emacs.
Emacs Lisp does have a concept of “obarrays”, which are package-like collections of symbols, but this feature is not strong enough to be used as a true package mechanism.
format
function is quite different between Common
Lisp and Emacs Lisp. It takes an additional “destination”
argument before the format string. A destination of nil
means to format to a string as in Emacs Lisp; a destination
of t
means to write to the terminal (similar to
message
in Emacs). Also, format control strings are
utterly different; ~
is used instead of %
to
introduce format codes, and the set of available codes is
much richer. There are no notations like \n
for
string literals; instead, format
is used with the
“newline” format code, ~%
. More advanced formatting
codes provide such features as paragraph filling, case
conversion, and even loops and conditionals.
While it would have been possible to implement most of Common
Lisp format
in this package (under the name cl-format
,
of course), it was not deemed worthwhile. It would have required
a huge amount of code to implement even a decent subset of
format
, yet the functionality it would provide over
Emacs Lisp’s format
would rarely be useful.
#(a b c)
notation in Common Lisp. To further complicate
matters, Emacs has its own #(
notation for
something entirely different—strings with properties.
#\A
in Common Lisp
where Emacs Lisp uses ?A
. Also, string=
and
string-equal
are synonyms in Emacs Lisp, whereas the latter is
case-insensitive in Common Lisp.
defconstant
where Emacs Lisp uses defconst
. Similarly, make-list
takes its arguments in different ways in the two Lisps but does
exactly the same thing, so this package has not bothered to
implement a Common Lisp-style make-list
.
compiler-let
, prog
, ldb/dpb
, cerror
.
(defun sum-list (list) (if list (+ (car list) (sum-list (cdr list))) 0))
where a more iteratively-minded programmer might write one of these forms:
(let ((total 0)) (dolist (x my-list) (incf total x)) total) (loop for x in my-list sum x)
While this would be mainly a stylistic choice in most Common Lisps, in Emacs Lisp you should be aware that the iterative forms are much faster than recursion. Also, Lisp programmers will want to note that the current Emacs Lisp compiler does not optimize tail recursion.
Next: Obsolete Features, Previous: Common Lisp Compatibility, Up: GNU Emacs Common Lisp Emulation [Contents][Index]