CommonLisp, the mud ball of strength, [is] the acting patriarch of the Lisp family. CL was shaped by engineering concerns more than by the quest for conceptual clarity. But despite its practical applicability, CL offers DEFUN sadly absent from mainstream hacking.
-- the TaoOfRecursion
Descended from one of the oldest surviving programming languages (only Fortran is older), CommonLisp
is the first language with integrated support for ObjectOrientedProgramming
to get ANSI standardized.
I thought Ada 95 was... Actually it was maybe the first ISO standardized one.
It is a rich language with clear semantics which allows programming in procedural, functional, object oriented and logical (rule based) style all in the same program.
It's big, making it somewhat of a CareerLanguage
. Depending on your viewpoint, CommonLisp
is either a very large language, or a very small language with a single big library. Opinions about it are often polarised: what one man calls "the sum of years of wisdom as to what actually works and is needed in production systems", another may characterise as "decades worth of ad-hoc fudges" and reminiscent of Fortran.
has, at least (standardized)
- A well designed, well integrated object system (CommonLispObjectSystem, short CLOS)
- A well designed exception/condition handling mechanism
- A not so easy to use/understand, but working, Package system
- Support for RuntimeCompilation
- Multi-threading (every commercial vendor)
- A MetaObjectProtocol (the MOP is supplied in most implementations)
For further information:
For a much smaller and arguably more elegant language, also see SchemeLanguage
. There is an interesting comparison between the CommonLisp
and Scheme communities in the WorseIsBetter
paper. Fans of both languages often fail to communicate because they've got different standards and goals.
Based on contributions by KeithBraithwaite
, Lieven and others.
has first class
functions, i.e. functions are objects which can be created at runtime, and passed as arguments to other functions. --AlainPicard
These first-class functions also have their own state, so they are functors. All Lisp functions are functors; there is no separation between functions that are "just code" and "function objects".
The state takes the form of captured lexical variable bindings. You don't need to use LAMBDA to capture bindings; a top-level DEFUN can do it too:
(let ((private-variable 42))
(defun foo ()
The code in the place of ... sees private-variable in its lexical scope. There is one instance of this variable associated with the one and only function object that is globally tied to the symbol FOO; the variable is captured at the time the DEFUN expression is evaluated. This variable then acts something like a static variable in C. Or, alternately, you can think of FOO as a "singleton" object with an "instance variable".
functions are closures (see LexicalClosure
s are first-class functions also. This means you can indirect upon generic functions. This is what the VisitorPattern
is all about; but it's built into the Lisp language so you can do it in one line. (walk-my-object #'with-this-gf my-object)
In fact, with plain old MAPCAR you can do the visitor pattern:
;; ``visit'' every element of the list, which can be heterogeneous collection of CLOS
;; objects or built-in types.
(mapcar #'foo-generic-function object-list)
Now foo-generic-function can be specialized for different types. A good example of this is the standard PRINT-OBJECT, which is what you specialize with a method to allow an object to be printable to a stream.
(mapcar #'print-object object-list) ;; visit each object and print it.
This practice is not only common, but institutionalized. For example, in the OO world you hear a good deal about "patterns". I wonder if these patterns are not sometimes evidence of case (c), the human compiler, at work. When I see patterns in my programs, I consider it a sign of trouble. The shape of a program should reflect only the problem it needs to solve. Any other regularity in the code is a sign, to me at least, that I'm using abstractions that aren't powerful enough-- often that I'm generating by hand the expansions of some macro that I need to write.
The first time I used CommonLisp
, I was surprised to see people using symbols where I would have used strings. Sometimes these symbols don't have values at all (or their values are themselves). It reminds me of WikiTag
Lisp is an interesting and fairly controversial language. Perhaps some of the SmugLispWeenie
s could have a crack at LispQuestions
to elucidate us all.
the mudball of strength
: see JoelMosesOnAplAndLisp
I'd dispute the hard-to-understandness of the package system: Most often it seems to be simply misunderstood due to
books on CL leaving it too late, so that by the time it is explained the reader has already developed mental models about
it that are both wrong and hard to break. The package system is essential enough that it should be dealt with right
after explaining REPL interaction, sexps, defun, and other basics -- probably before getting to lambda and defmacro, I'd say.
(SWIG) can be used to make calls to CeeLanguage
See also: LispLanguage