- Lisp (programming language)
Infobox programming language
name = Lisp
paradigm = multi-paradigm: functional, procedural, reflective
generation =3GL
year = 1958
designer = John McCarthy
developer =Steve Russell ,Timothy P. Hart , andMike Levin
latest release version =
latest release date =
turing-complete = Yes
typing = dynamic, strong
implementations =
dialects =Common Lisp , Scheme,Emacs Lisp , Arc,ISLISP ,Newlisp .
influenced by =
influenced = Logo,Perl , Python,Smalltalk , Ruby, Dylan,Mathematica ,Rebol Lisp (or LISP) is a family of
computer programming language s with a long history and a distinctive, fully parenthesized syntax. Originally specified in 1958, Lisp is the second-oldesthigh-level programming language in widespread use today; onlyFortran is older. Like Fortran, Lisp has changed a great deal since its early days, and a number of dialects have existed over its history. Today, the most widely known general-purpose Lisp dialects areCommon Lisp and Scheme.Lisp was originally created as a practical mathematical notation for computer programs, based on
Alonzo Church 'slambda calculus . It quickly became the favored programming language forartificial intelligence (AI) research. As one of the earliest programming languages, Lisp pioneered many ideas incomputer science , includingtree data structure s, automatic storage management, dynamic typing,object-oriented programming , and theself-hosting compiler .The name "Lisp" derives from "List Processing Language".
Linked list s are one of Lisp languages' majordata structure s, and Lispsource code is itself made up of lists. As a result, Lisp programs can manipulate source code as a data structure, giving rise to the macro systems that allow programmers to create new syntax or even newdomain-specific programming language s embedded in Lisp.The interchangeability of code and data also gives Lisp its instantly recognizable syntax. All program code is written as "
s-expression s", or parenthesized lists. A function call or syntactic form is written as a list with the function or operator's name first, and the arguments following; for instance, a function f that takes three arguments might be called using(f x y z)
.History
Lisp was invented by John McCarthy in 1958 while he was at the
Massachusetts Institute of Technology (MIT). McCarthy published its design in a paper in "Communications of the ACM " in 1960, entitled "Recursive Functions of Symbolic Expressions and Their Computation by Machine, Part I"cite web | title=Recursive Functions of Symbolic Expressions and Their Computation by Machine, Part I| author=John McCarthy | url=http://www-formal.stanford.edu/jmc/recursive.html | accessdate=2006-10-13] ("Part II" was never published). He showed that with a few simple operators and a notation for functions, one can build aTuring-complete language for algorithms.Information Processing Language was the first AI language, from 1955 or 1956, and already included many of the concepts, such as list-processing and recursion, which came to be used in Lisp.McCarthy's original notation used bracketed "
M-expression s" that would be translated intoS-expression s. As an example, the M-expression
is equivalent to the S-expressioncar [cons [A,B] (car (cons A B))
. Once Lisp was implemented, programmers rapidly chose to use S-expressions, and M-expressions were abandoned. M-expressions surfaced again with short-lived attempts ofMLISP cite web | title=MLISP Users Manual| author=David Canfield Smith | url=http://community.computerhistory.org/scc/projects/LISP/stanford/Smith-MLISP-AIM-84.pdf | accessdate=2006-10-13] byHorace Enea andCGOL byVaughan Pratt .Lisp was first implemented by
Steve Russell on anIBM 704 computer. Russell had read McCarthy's paper, and realized (to McCarthy's surprise) that the Lisp "eval" function could be implemented in machine code. [ According to what reported byPaul Graham in "Hackers & Painters ", p. 185, McCarthy said: "Steve Russell said, look, why don't I program this "eval"..., and I said to him, ho, ho, you're confusing theory with practice, this "eval" is intended for reading, not for computing. But he went ahead and did it. That is, he compiled the "eval" in my paper intoIBM 704 machine code, fixing bug , and then advertised this as a Lisp interpreter, which it certainly was. So at that point Lisp had essentially the form that it has today..."] The result was a working Lisp interpreter which could be used to run Lisp programs, or more properly, 'evaluate Lisp expressions.'Two assembly language routines for the
IBM 704 became the primitive operations for decomposing lists:car
(Contents of Address Register) andcdr
(Contents of Decrement Register). Lisp dialects still usecar
andcdr
(pronEng|ˈkɑr and IPA|/ˈkʊdər/) for the operations that return the first item in a list and the rest of the list respectively.The first complete Lisp compiler, written in Lisp, was implemented in 1962 by Tim Hart and Mike Levin at MIT.cite web | title=AI Memo 39-The new compiler| author=Tim Hart and Mike Levin | url=ftp://publications.ai.mit.edu/ai-publications/pdf/AIM-039.pdf | accessdate=2006-10-13] This compiler introduced the Lisp model of incremental compilation, in which compiled and interpreted functions can intermix freely. The language used in Hart and Levin's memo is much closer to modern Lisp style than McCarthy's earlier code.
Genealogy and variants
Over its fifty-year history, Lisp has spawned many variations on the core theme of an S-expression language. Moreover, each given dialect may have several implementations — for instance, there are more than a dozen implementations of
Common Lisp .Differences between dialects may be quite visible — for instance, Common Lisp and Scheme use different keywords to define functions. Within a dialect that is standardized, however, conforming implementations support the same core language, but with different extensions and libraries.
Historically significant dialects
*LISP 1.5 [http://community.computerhistory.org/scc/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf] – First widely distributed version, developed by McCarthy and others at MIT. So named because it contained several improvements on the original "LISP 1" interpreter, but was not a major restructuring as the planned
LISP 2 would be.
*Stanford LISP 1.6 [http://community.computerhistory.org/scc/projects/LISP/stanford/SAILON-28.6.pdf] – This was a successor to LISP 1.5 developed at theStanford AI Lab , and widely distributed toPDP-10 systems running theTOPS-10 operating system. It was rendered obsolete by Maclisp and InterLisp.
*MACLISP [http://zane.brouhaha.com/~healyzh/doc/lisp.doc.txt] – developed for MIT'sProject MAC (no relation to Apple'sMacintosh , nor to McCarthy), direct descendant of LISP 1.5. It ran on the PDP-10 andMultics systems. (MACLISP would later come to be called Maclisp, and is often referred to as MacLisp.)
*InterLisp [http://www.bitsavers.org/pdf/xerox/interlisp/1974_InterlispRefMan.pdf] – developed atBBN Technologies for PDP-10 systems running the Tenex operating system, later adopted as a "West coast" Lisp for the Xerox Lisp machines. A small version called "InterLISP 65" was published forAtari 's 6502-based computer line. For quite some time Maclisp and InterLisp were strong competitors.
*Franz Lisp – originally a Berkeley project; later developed by Franz Inc. The name is a humorous deformation of "Franz Liszt ". The name "Franz Lisp" does "not" refer toAllegro Common Lisp , the dialect of Common Lisp sold by Franz Inc. in more recent years.
*ZetaLisp – used on theLisp machine s, direct descendant of Maclisp.
*Common Lisp (1984), as described by "" – a consolidation of several divergent attempts (ZetaLisp,Spice Lisp , NIL, andS-1 Lisp ) to create successor dialects [http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node6.html] to Maclisp, with substantive influences from the Scheme dialect as well. This version of Common Lisp was available for wide-ranging platforms and was accepted by many as ade facto standard [http://www.cs.cmu.edu/Groups/AI/html/faqs/lang/lisp/part2/faq-doc-13.html] until the publication of ANSI Common Lisp (ANSI X3.226-1994).
*EuLisp – attempt to develop a new efficient and cleaned-up Lisp.
*ISLisp – attempt to develop a new efficient and cleaned-up Lisp. Standardized as [http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=22987 ISO/IEC 13816:1997] and later revised as [http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=44338 ISO/IEC 13816:2007] - "Information technology – Programming languages, their environments and system software interfaces – Programming language ISLISP".
*IEEE Scheme – IEEE standard, 1178-1990 (R1995)
*ANSI Common Lisp – anAmerican National Standards Institute (ANSI) standard for Common Lisp, created by subcommitteeX3J13 , chartered [http://www.nhplace.com/kent/CL/x3j13-86-020.html] to begin with "Common Lisp: The Language" as a base document and to work through a public consensus process to find solutions to shared issues of portability of programs and compatibility of Common Lisp implementations. Although formally an ANSI standard, the implementation, sale, use, and influence of ANSI Common Lisp has been and continues to be seen world-wide.
*arc – a new sub version of Lisp created by Paul Graham, released on January 29, 2008.Connection to artificial intelligence
Since its inception, Lisp was closely connected with the
artificial intelligence research community, especially onPDP-10 [The 36-bit word size of thePDP-6 /PDP-10 was influenced by the usefulness of having two Lisp 18-bit pointers in a single word. "The PDP-6 project started in early 1963, as a 24-bit machine. It grew to 36 bits for LISP, a design goal." [http://groups.google.com/group/alt.folklore.computers/browse_thread/thread/6e5602ce733d0ec/17597705ae289112] ] systems. Lisp was used as the implementation of the programming language Micro Planner that was the foundation for the famous AI systemSHRDLU . In the 1970s, as AI research spawned commercial offshoots, the performance of existing Lisp systems became a growing issue.Lisp was a difficult system to implement with the compiler techniques and stock hardware of the 1970s. Garbage collection routines, developed by then-
MIT graduate student Daniel Edwards, made it practical to run Lisp on general-purpose computing systems, but efficiency was still a problem. This led to the creation ofLisp machine s: dedicated hardware for running Lisp environments and programs. Advances in both computer hardware and compiler technology soon made Lisp machines obsolete, to the detriment of the Lisp market.During the 1980s and 1990s, a great effort was made to unify the numerous Lisp dialects (most notably,
InterLisp ,Maclisp ,ZetaLisp , MetaLisp, andFranz Lisp ) into a single language. The new language,Common Lisp , was essentially a compatible subset of the dialects it replaced. In 1994,ANSI published the Common Lisp standard, "ANSI X3.226-1994 Information Technology Programming Language Common Lisp." At that time the world market for Lisp was much smaller than it is today.ince 2000
Having declined somewhat in the 1990s, Lisp has experienced a regrowth of interest since 2000. Most new activity is focused around
open source implementations ofCommon Lisp , and includes the development of new portable libraries and applications. This interest can be measured partly by sales from the print version of "Practical Common Lisp " byPeter Seibel , a tutorial for new Lisp programmers published in 2004 [ [http://gigamonkeys.com/blog/2007/05/26/pcl-third-printing.html Practical Common Lisp going into 3rd printing] ] . It was brieflyAmazon.com 's second most popular programming book. It is now available online for free [ [http://gigamonkeys.com/book/ Practical Common Lisp] ] . This can also be measured by higher attendance of related conferences [ [http://www.regdeveloper.co.uk/2007/04/02/international_lisp_conference_2007/ Keeping Lisp alive and practical | Reg Developer] ] and analyzing newsgroup postings [ [http://www.complang.tuwien.ac.at/anton/comp. _st. title=The Road To Lisp Survey | url=http://wiki.alu.org/The_Road_To_Lisp_Survey | accessdate=2006-10-13] Contemporary programmers learning Lisp may also have been introduced to it byPeter Norvig 's commentary [ [http://norvig.com/Lisp-retro.html A Retrospective on PAIP ] ] , author of ' and ', orPhillip Greenspun , who has had business successes involving Lisp.This increase in awareness may be contrasted to the "
AI winter " and Lisp's brief gain in the mid-1990s. [ [http://www.faqs.org/docs/artu/ch14s05.html Trends for the Future] ]Major modern dialects
The two major dialects of Lisp used for general-purpose programming today are
Common Lisp and Scheme. These languages represent significantly different design choices.Common Lisp, descended mainly from
MacLisp ,Interlisp , andLisp Machine Lisp , is an expanded superset of earlier Lisp dialects, with a large language standard including many built-in data types and syntactic forms, as well as an object system. Scheme is a more minimalist design, with a much smaller set of standard features but with certain implementation features (such astail-call optimization and fullcontinuation s) not necessarily found in Common Lisp. Common Lisp also borrowed certain features from Scheme such as lexical scoping andlexical closure s.In addition, Lisp dialects are used as
scripting language s in a number of applications, with the most well-known beingEmacs Lisp in theEmacs editor andAutolisp inAutoCAD .Language innovations
Lisp was the first homoiconic programming language: the primary representation of program code is the same type of list structure that is also used for the main data structures. As a result, Lisp functions can be manipulated, altered or even created within a Lisp program without extensive parsing or manipulation of binary machine code. This is generally considered one of the primary advantages of the language with regards to its expressiveness, and makes the language amenable to
metacircular evaluation .The now-ubiquitous "if-then-else" structure, now taken for granted as an essential element of any programming language, was invented by McCarthy for use in Lisp, where it saw its first appearance in a more general form (the cond structure). It was inherited by Algol, which popularized it.
Lisp deeply influenced
Alan Kay , the leader of the research onSmalltalk , and then in turn Lisp was influenced by Smalltalk, by adopting object-oriented programming features (classes, instances, etc.) in the late 1970s.Largely because of its resource requirements with respect to early computing hardware (including early microprocessors), Lisp did not become as popular outside of the
AI community asFortran and theALGOL -descended C language. Newer languages such as Java and Python have incorporated some limited versions of some of the features of Lisp, but are necessarily unable to bring the coherence and synergy of the full concepts found in Lisp. Because of its suitability to ill-defined, complex, and dynamic applications, Lisp is currently enjoying some resurgence of popular interest.See also "The evolution of Lisp",cite web | title=The evolution of Lisp| author=Guy L Steele Jr, Richard P Gabriel | url=http://www.dreamsongs.com/NewFiles/HOPL2-Uncut.pdf | accessdate=2006-10-12] a paper written by
Guy L. Steele, Jr. andRichard P. Gabriel .yntax and semantics
:"Note: This article's examples are written in
Common Lisp (though most are also valid in Scheme)."Lisp is an expression-oriented language. Unlike most other languages, no distinction is made between "expressions" and "statements"; all code and data are written as expressions. When an expression is "evaluated", it produces a value (or list of values), which then can be embedded into other expressions.
McCarthy's 1958 paper introduced two types of syntax:
S-expression s (Symbolic Expressions, also called "sexps"), which mirror the internal representation of code and data; andM-expression s (Meta Expressions), which express functions of S-expressions. M-expressions never found favor, and almost all Lisps today use S-expressions to manipulate both code and data.The use of parentheses is Lisp's most immediately obvious difference from other programming language families. As a result, students have long given Lisp nicknames such as "Lost In Stupid Parentheses", or "Lots of Irritating Superfluous Parentheses".cite web | title=The Jargon File - Lisp| url=http://www.catb.org/~esr/jargon/html/L/LISP.html| accessdate=2006-10-13] However, the S-expression syntax is also responsible for much of Lisp's power; the syntax is extremely regular, which facilitates manipulation by computer. However, the syntax of Lisp is not limited to traditional parentheses notation. It can be extended to include alternative notations.
XMLisp , for instance, is a Common Lisp extension that employs the metaobject-protocol to integrate S-expressions with the Extensible Markup Language (XML).The reliance on expressions gives the language great flexibility. Because Lisp functions are themselves written as lists, they can be processed exactly like data. This allows easy writing of programs which manipulate other programs (
metaprogramming ). Many Lisp dialects exploit this feature using macro systems, which enables extension of the language almost without limit.A Lisp list is written with its elements separated by whitespace, and surrounded by parentheses. For example,
(1 2 foo)
is a list whose elements are three "atoms": the values1
,2
, andfoo
. These values are implicitly typed: they are respectively two integers and a Lisp-specific data type called a "symbol", and do not have to be declared as such.The empty list
()
is also represented as the special atomnil
. This is the only entity in Lisp which is both an atom and a list.Expressions are written as lists, using
prefix notation . The first element in the list is the name of a "form", i.e., a function, operator, macro, or "special operator" (see below.) The remainder of the list are the arguments. For example, the functionlist
returns its arguments as a list, so the expressionevaluates to the list(1 2 foo)
. The "quote" before the arguments in the preceding example is a "special operator" which prevents the quoted arguments from being evaluated (not strictly necessary for the numbers, since 1 evaluates to 1, etc). Any unquoted expressions are recursively evaluated before the enclosing expression is evaluated. For example,evaluates to the list(1 2 (3 4))
. Note that the third argument is a list; lists can be nested.Arithmetic operators are treated similarly. The expressionevaluates to 10. The equivalent under
infix notation would be "1 + 2 + 3 + 4
". Arithmetic operators in Lisp are variadic (or "n-ary "), able to take any number of arguments."Special operators" (sometimes called "special forms" by older users) provide Lisp's control structure. For example, the special operator
if
takes three arguments. If the first argument is non-nil, it evaluates to the second argument; otherwise, it evaluates to the third argument. Thus, the expressionevaluates to(3 4 "bar")
. Of course, this would be more useful if a non-trivial expression had been substituted in place ofnil
.Lambda expressions
Another special operator,
lambda
, is used to bind variables to values which are then evaluated within an expression. This operator is also used to create functions: the arguments tolambda
are a list of arguments, and the expression or expressions to which the function evaluates (the returned value is the value of the last expression that is evaluated). The expressionevaluates to a function that, when applied, takes one argument, binds it toarg
and returns the number one greater than that argument. Lambda expressions are treated no differently from named functions; they are invoked the same way. Therefore, the expressionevaluates to6
.Atoms
In the original LISP there were two fundamental
data type s: atoms and lists. A list was a finite ordered sequence of elements, where each element is in itself either an atom or a list, and an atom was anumber or a symbol. A symbol was essentially a unique named item, written as anAlphanumeric string insource code , and used either as a variable name or as a data item insymbolic processing . For example, the list(FOO (BAR 1) 2)
contains three elements: the symbol FOO, the list(BAR 1)
, and the number 2.The essential difference between atoms and lists was that atoms were immutable and unique. Two atoms that appeared in different places in source code but were written in the exact same way represented the same object, whereas each list was a separate object that could be altered independently of other lists and could be distinguished from other lists by comparison operators.
As more data types were introduced in later Lisp dialects, and
programming style s evolved, the concept of an atom lost importance. Many dialects still retained the predicate "atom" forlegacy compatibility , defining it true for any object which is not a cons.Conses and lists
A Lisp list is a
singly-linked list . Each cell of this list is called a "cons" (in Scheme, a "pair"), and is composed of twopointer s, called the "car" and "cdr". These are equivalent to thedata
andnext
fields discussed in the article "linked list ", respectively.Of the many data structures that can be built out of cons cells, one of the most basic is called a "proper list". A proper list is either the special
nil
(empty list) symbol, or a cons in which thecar
points to a datum (which may be another cons structure, such as a list), and thecdr
points to another proper list.If a given cons is taken to be the head of a linked list, then its car points to the first element of the list, and its cdr points to the rest of the list. For this reason, the
car
andcdr
functions are also calledfirst
andrest
when referring to conses which are part of a linked list (rather than, say, a tree).Thus, a Lisp list is not an atomic object, as an instance of a container class in C++ or Java would be. A list is nothing more than an aggregate of linked conses. A variable which refers to a given list is simply a pointer to the first cons in the list. Traversal of a list can be done by "cdring down" the list; that is, taking successive cdrs to visit each cons of the list; or by using any of a number of
higher-order function s to map a function over a list.Because conses and lists are so universal in Lisp systems, it is a common misconception that they are Lisp's only data structures. In fact, all but the most simplistic Lisps have other data structures – such as vectors (
array s), hash tables, structures, and so forth.-expressions represent lists
Parenthesized S-expressions represent linked list structure. There are several ways to represent the same list as an S-expression. A cons can be written in "dotted-pair notation" as
(a . b)
, wherea
is the car andb
the cdr. A longer proper list might be written(a . (b . (c . (d . nil))))
in dotted-pair notation. This is conventionally abbreviated as(a b c d)
in "list notation". An improper list [NB: a so-called "dotted list" is only one kind of "improper list". The other kind is the "circular list" where the cons cells form a loop. Typically this is represented using #n=(...) to represent the target cons cell that will have multiple references, and #n# is used to refer to this cons. For instance, (#1=(a b) #1#) would normally be printed as ((a b) a b) (without circular structure printing enabled), but makes the reuse of the cons cell clear. #1=(a . #1#) cannot normally be printed as it is circular, the CDR of the cons cell defined by #1= is itself.] may be written in a combination of the two – as(a b c . d)
for the list of three conses whose last cdr isd
(i.e., the list(a . (b . (c . d)))
in fully specified form).List-processing procedures
Lisp provides many built-in procedures for accessing and controlling lists. Lists can be created directly with the
list
procedure, which takes any number of arguments, and returns the list of these arguments.Because of the way that lists are constructed fromcons pair s, the
procedure can be used to add an element to the front of a list. Note that thecons cons
procedure is asymmetric in how it handles list arguments, because of how lists are constructed.The
procedure appends two (or more) lists to one another. Because Lisp lists are linked lists, appending two lists has asymptotic time complexity .append hared structure
Lisp lists, being simple linked lists, can share structure with one another. That is to say, two lists can have the same "tail", or final sequence of conses. For instance, after the execution of the following Common Lisp code:the lists
foo
andbar
are(a b c)
and(x b c)
respectively. However, the tail(b c)
is the same structure in both lists. It is not a copy; the cons cells pointing tob
andc
are in the same memory locations for both lists.Sharing structure rather than copying can give a dramatic performance improvement. However, this technique can interact in undesired ways with functions that alter lists passed to them as arguments. Altering one list, such as by replacing the
c
with agoose
, will affect the other:This changesfoo
to(a b goose)
, but thereby also changesbar
to(x b goose)
– a possibly unexpected result. This can be a source of bugs, and functions which alter their arguments are documented as "destructive" for this very reason.Aficionados of
functional programming avoid destructive functions. In the Scheme dialect, which favors the functional style, the names of destructive functions are marked with a cautionary exclamation point, or "bang" — such asset-car!
(read "set car bang"), which replaces the car of a cons. In the Common Lisp dialect, destructive functions are commonplace; the equivalent ofset-car!
is namedrplaca
for "replace car." This function is rarely seen however as Common Lisp includes a special facility,setf
, to make it easier to define and use destructive functions. A frequent style in Common Lisp is to write code functionally (without destructive calls) when prototyping, then to add destructive calls as an optimization where it is safe to do so.elf-evaluating forms and quoting
Lisp evaluates expressions which are entered by the user. Symbols and lists evaluate to some other (usually, simpler) expression – for instance, a symbol evaluates to the value of the variable it names;
(+ 2 3)
evaluates to5
. However, most other forms evaluate to themselves: if you enter5
into Lisp, it returns5
.Any expression can also be marked to prevent it from being evaluated (as is necessary for symbols and lists). This is the role of the
quote
special operator, or its abbreviation'
(a single quotation mark). For instance, usually if you enter the symbolfoo
you will get back the value of the corresponding variable (or an error, if there is no such variable). If you wish to refer to the literal symbol, you enter(quote foo)
or, usually,'foo
.Both Common Lisp and Scheme also support the "backquote" operator (often called "quasiquote" by Schemers), entered with the
`
character. This is almost the same as the plain quote, except it allows expressions to be evaluated and their values interpolated into a quoted list with the comma and comma-at operators. If the variablesnue
has the value(bar baz)
then`(foo ,snue)
evaluates to(foo (bar baz))
, while`(foo ,@snue)
evaluates to(foo bar baz)
. The backquote is most frequently used in defining macro expansions.Self-evaluating forms and quoted forms are Lisp's equivalent of literals. It is possible to modify the values of (mutable) literals in program code. For instance, if a function returns a quoted form, and the code that calls the function modifies the form, this will alter the behavior of the function on subsequent iterations.
Modifying a quoted form like this is generally considered bad style, and is defined by some implementations as erroneous (resulting in "undefined" behavior in compiled files, because the file-compiler can coalesce similar constants, put them in write-protected memory, etc). When behavior like this is intentional, using a closure is the explicit way to do it.
Lisp's formalization of quotation has been noted by
Douglas Hofstadter (in "Gödel, Escher, Bach ") and others as an example of the philosophical idea ofself-reference .cope and closure
The modern Lisp family splits over the use of dynamic or static (aka lexical) scope. Scheme and Common Lisp make use of static scoping by default, while
Newlisp and the embedded languages inEmacs andAutoCAD use dynamic scoping.List structure of program code
A fundamental distinction between Lisp and other languages is that in Lisp, the textual representation of a program is simply a human-readable description of the same internal data structures (linked lists) as would be used by the underlying Lisp system.
Lisp macros operate on these structures. Because Lisp code has the same structure as lists, macros can be built with any of the list-processing functions in the language. In short, anything that Lisp can do to a data structure, Lisp macros can do to code. In contrast, in most other languages the parser's output is purely internal to the language implementation and cannot be manipulated by the programmer. Macros in C, for instance, operate on the level of the "
preprocessor ", before the parser is invoked, and cannot re-structure the program code in the way Lisp macros can.In simplistic Lisp implementations, this list structure is directly interpreted to run the program; a function is literally a piece of list structure which is traversed by the interpreter in executing it. However, most actual Lisp systems (including all conforming
Common Lisp systems) also include a compiler. The compiler translates list structure into machine code orbytecode for execution.Evaluation and the Read-Eval-Print Loop
Lisp languages are frequently used with an interactive
command line , which may be combined with anintegrated development environment . The user types in expressions at the command line, or directs the IDE to transmit them to the Lisp system. Lisp "reads" the entered expressions, "evaluates" them, and "prints" the result. For this reason, the Lisp command line is called a "read-eval-print loop ", or "REPL ".The basic operation of the REPL is as follows. This is a simplistic description which omits many elements of a real Lisp, such as quoting and macros.
The
read
function accepts textual S-expressions as input, and parses them into list structure. For instance, if you type the string(+ 1 2)
at the prompt,read
translates this into a linked list with three elements: the symbol+
, the number 1, and the number 2. It so happens that this list is also a valid piece of Lisp code; that is, it can be evaluated. This is because the car of the list names a function — the addition operation.The
eval
function evaluates list structure, returning some other piece of structure as a result. Evaluation does not have to mean interpretation; some Lisp systems compile every expression to native machine code. It is simple, however, to describe evaluation as interpretation: To evaluate a list whose car names a function,eval
first evaluates each of the arguments given in its cdr, then applies the function to the arguments. In this case, the function is addition, and applying it to the argument list(1 2)
yields the answer3
. This is the result of the evaluation.It is the job of the
print
function to represent output to the user. For a simple result such as3
this is trivial. An expression which evaluated to a piece of list structure would require thatprint
traverse the list and print it out as an S-expression.To implement a Lisp REPL, it is necessary only to implement these three functions and an infinite-loop function. (Naturally, the implementation of
eval
will be complicated, since it must also implement all special operators likeif
.) This done, a basic REPL itself is but a single line of code:(loop (print (eval (read))))
.Lisp is usually evaluated eagerly. In
Common Lisp , arguments are evaluated inapplicative order ('leftmost innermost'), while in Scheme order of arguments is undefined, leaving room for optimization by a compiler.Control structures
Lisp originally had very few control structures, but many more were added during the language's evolution. (Lisp's original conditional operator,
cond
, is the precursor to laterif-then-else
structures.)Programmers in the Scheme dialect often express loops using
tail recursion . Scheme's commonality in academic computer science has led some students to believe that tail recursion is the only, or the most common, way to write iterations in Lisp; this is incorrect. All frequently seen Lisp dialects have imperative-style iteration constructs, from Scheme'sdo
loop toCommon Lisp 's complexloop
expressions. Moreover, the key issue that makes this an objective rather than subjective matter is that Scheme makes specific requirements for the handling oftail call s, and consequently the reason that the use of tail recursion is generally encouraged for Scheme is that the practice is expressly supported by the language definition itself. By contrast,ANSI Common Lisp does not require [ [http://www.lispworks.com/documentation/HyperSpec/Body/03_bbc.htm 3.2.2.3 Semantic Constraints] in [http://www.lispworks.com/documentation/HyperSpec/Front/index.htm "Common Lisp HyperSpec"] ] the optimization commonly referred to as tail call elimination. Consequently, the fact that tail recursive style as a casual replacement for the use of more traditionaliteration constructs (such asdo
,dolist
orloop
) is discouraged [4.3. Control Abstraction (Recursion vs. Iteration) in [http://www.cs.umd.edu/~nau/cmsc421/norvig-lisp-style.pdf Tutorial on Good Lisp Programming Style] by Pitman and Norvig, August, 1993.] in Common Lisp is not just a matter of stylistic preference, but potentially one of efficiency (since an apparent tail call in Common Lisp may not compile as a simple jump) and program correctness (since tail recursion may increase stack use in Common Lisp, riskingstack overflow ).Some Lisp control structures are "special operators", equivalent to other languages' syntactic keywords. Expressions using these operators have the same surface appearance as function calls, but differ in that the arguments are not necessarily evaluated — or, in the case of an iteration expression, may be evaluated more than once.
In contrast to most other major programming languages, Lisp allows the programmer to implement control structures using the language itself. Several control structures are implemented as Lisp macros, and can even be macro-expanded by the programmer who wants to know how they work.
Both Common Lisp and Scheme have operators for non-local control flow. The differences in these operators are some of the deepest differences between the two dialects. Scheme supports "re-entrant
continuation s" using thecall/cc
procedure, which allows a program to save (and later restore) a particular place in execution. Common Lisp does not support re-entrant continuations, but does support several ways of handling escape continuations.Frequently, the same algorithm can be expressed in Lisp in either an imperative or a functional style. As noted above, Scheme tends to favor the functional style, using tail recursion and continuations to express control flow. However, imperative style is still quite possible. The style preferred by many Common Lisp programmers may seem more familiar to programmers used to structured languages such as C, while that preferred by Schemers more closely resembles pure-functional languages such as Haskell.
Because of Lisp's early heritage in list processing, it has a wide array of higher-order functions relating to iteration over sequences. In many cases where an explicit loop would be needed in other languages (like a
for
loop in C) in Lisp the same task can be accomplished with a higher-order function. (The same is true of many functional programming languages.)A good example is a function which in Scheme is called
map
and in Common Lisp is calledmapcar
. Given a function and one or more lists,mapcar
applies the function successively to the lists' elements in order, collecting the results in a new list:This applies the+
function to each corresponding pair of list elements, yielding the result(11 22 33 44 55)
.Examples
Here are examples of Common Lisp code.
The basic "
Hello world " program:As the reader may have noticed from the above discussion, Lisp syntax lends itself naturally to recursion. Mathematical problems such as the enumeration of recursively defined sets are simple to express in this notation.Evaluate a number's
factorial :An alternative implementation, often faster than the previous version if the Lisp system hastail recursion optimization:Contrast with an iterative version which usesCommon Lisp 'sloop
macro:The following function reverses a list. (Lisp's built-in "reverse" function does the same thing.)
Object systems
Various object systems and models have been built on top of, alongside, or into Lisp, including:
*ObjectLisp [pg 17 of Bobrow 1986] or Object Lisp, favored byLisp Machines Incorporated
*LOOPS (Lisp Object-Oriented Programming System) and the laterCommonLOOPS
*Flavors, built at MIT, and its descendant New Flavors, which were favored bySymbolics
*TheCommon Lisp Object System , CLOS (descended from New Flavors and CommonLOOPS)
*KR (short for Knowledge Representation), aconstraint s-based object system developed to aid the writing of Garnet, a GUI library forCommon Lisp
* KEE was written similarly, but incorporating aninference engine . [Veitch, p 108, 1988] and a truth maintenance system (ATMS).
*Lush is an object-oriented lisp code with a goal of extensive programming capabilities, as it interfaces with many data libraries for math and science, but also interfaces with C code in-line, is still dynamic, and has graphics and hardware support.
*SageCLOS , an Object Oriented Interface to AutoLISP invented by Ralph GimenezCLOS featuresmultiple inheritance ,multiple dispatch ("multimethods"), and a powerful system of "method combinations". In fact,Common Lisp , which includes CLOS, was the first object-oriented language to be officially standardized.
* M&P [www.hdolder.com/ARTEC_EN.htm] "The first model driven system completely opreational" incorporates mpLISP, a minimum LISP dialect and a powerful LISP interpreter that enable a new object oriented architecture.Quotations
: "SQL, Lisp, and Haskell are the only programming languages that I've seen where one spends more time thinking than typing.": —
Philip Greenspun , March 2007, [http://blogs.law.harvard.edu/philg/2005/03/07/how-long-is-the-average-internet-discussion-forum-posting/]: "I suppose I should learn Lisp, but it seems so foreign.": —
Paul Graham , November 1983: "One can even conjecture that Lisp owes its survival specifically to the fact that its programs are lists, which everyone, including me, has regarded as a disadvantage.": — John McCarthy, Inventor of Lisp, "
Early History of Lisp ": "Any sufficiently complicated C or Fortran program contains an ad-hoc, informally-specified bug-ridden slow implementation of half of Common Lisp.": —
Philip Greenspun , often called "Greenspun's Tenth Rule of Programming" [cite web | title=Research| author=Phillip Greenspun | url=http://philip.greenspun.com/research/ | accessdate=2006-10-13]: "Please don't assume Lisp is only useful for Animation and Graphics, AI, Bioinformatics, B2B and E-Commerce, Data Mining, EDA/Semiconductor applications, Expert Systems, Finance, Intelligent Agents, Knowledge Management, Mechanical CAD, Modeling and Simulation, Natural Language, Optimization, Research, Risk Analysis, Scheduling, Telecom, and Web Authoring just because these are the only things they happened to list.": —
Kent Pitman : "Lisp has all the visual appeal of oatmeal with fingernail clippings mixed in.": —
Larry Wall , creator of thePerl programming language : "Lisp being the most powerful and cleanest of languages, that's the language that the GNU project always prefers.": —
Richard Stallman : "The greatest single programming language ever designed.": —
Alan Kay : "
Emacs is written in Lisp, which is the only computer language that is beautiful.": —Neal Stephenson , "In the Beginning...was the Command Line ": "A Lisp programmer knows the value of everything, but the cost of nothing.": —
Alan Perlis , "Epigrams on Programming ": "I think it's the only computer programming language that is mathematically respectable, because it's the only one that I can prove theorems about!": —
Gregory Chaitin : "Pascal is for building pyramids -- imposing, breathtaking structures built by armies pushing heavy blocks into place. Lisp is for building organisms -- imposing, breathtaking, dynamic structures built by squads fitting fluctuating myriads of simpler organisms into place." : —
Alan Perlis Notes
References
* "A History and Description of CLOS", by Jim Veitch. Pages 107-158 of "Handbook of Programming Languages, Volume IV: Functional and Logic Programming Languages", ed.
Peter H. Salus . 1998 (1st edition), Macmillian Technical Publishing; ISBN 1-57870-011-6
* "Structure and Interpretation of Computer Programs ", byHarold Abelson ,Gerald Jay Sussman andJulie Sussman . 1996 (2nd edition), MIT Press; ISBN 0262011530.
* [http://lispers.org/ Lispers.org] - Choice selection of Lisp quotes by eminent Lispers.
* [http://www-formal.stanford.edu/jmc/history/lisp/node3.html The implementation of LISP] , Stanford
* [http://www.gnu.org/gnu/rms-lisp.html My Lisp Experiences and the Development of GNU Emacs] ,transcript ofRichard Stallman 's speech,28 Oct 2002 , at theInternational Lisp Conference
* [http://www.defmacro.org/ramblings/lisp.html The Nature of Lisp] , DefMacro
*Paul Graham , " Hackers & Painters. Big Ideas from the Computer Age", 2004, O'Reilly, ISBN 0-596-00662-4ee also
*
Common Lisp
*Scheme (programming language)
*Object Lisp
*Artificial intelligence
* Maxima
*Fexpr External links
* [http://www-formal.stanford.edu/jmc/history/lisp/lisp.html History of Lisp]
John McCarthy (computer scientist) 's history of 12 Feb 79
* [http://www8.informatik.uni-erlangen.de/html/lisp-enter.html Lisp History] Herbert Stoyan's history compiled from the documents (acknowledged by McCarthy as more complete than his own, see: [http://www-formal.stanford.edu/jmc/history/ McCarthy's history links] )
* [http://groups.google.com/group/comp.lang.lisp/topics comp.lang.lisp]Usenet newsgroup
* [http://lisp.org Association of Lisp Users]
* [http://wiki.alu.org/ Association of Lisp Users Wiki] , a general discussion of things Lispish
* [http://community.computerhistory.org/scc/projects/LISP/ History of LISP at the Computer History Museum]
* [http://www.lispmachine.net LispMachine.net - Lisp books and information]
* [http://paulgraham.com/onlisptext.html?asdf On Lisp] , a free book byPaul Graham
* [http://se-radio.net/podcast/2008-01/episode-84-dick-gabriel-lisp Interview] withRichard P. Gabriel (Podcast)
* [http://common-lisp.net/project/lispbox/ Lisp in a Box] , a useful package for lisp beginners - for Windows or Unix
* [http://www.gigamonkeys.com/book/ Practical Common Lisp] , a free book by Peter Seibel
* [http://www.faqs.org/faqs/lisp-faq/ LISP FAQ]
* [http://arclanguage.org/ arc] , the arc homepage.
Wikimedia Foundation. 2010.