在方言間的差異可能是非常顯眼的,例如定義一個函式[29],Common Lisp使用Maclisp在1969年介入的關鍵字defun[30],而Scheme使用它在1975年介入的define[31]。Richard P. Gabriel(英語:Richard P. Gabriel)和Kent Pitman(英語:Kent Pitman)在1998年的一篇論文中,按採用統一的還是分立的函式與值命名空間,將Lisp家族語言劃分為Lisp1和Lisp2(或寫為Lisp-1和Lisp-2)[32]。
Common Lisp開源社群建立了至今仍活躍的支援基礎有:CLiki(英語:CLiki),它是收集Common Lisp相關資訊的維基;Planet Lisp,它是收集了各種Lisp相關部落格的內容;Common-lisp.net,它是開源專案的代管站點;Quicklisp,它是含括了許多函式庫的裝載管理器。在Common-lisp.net上,推薦了6種開源和2種商業Common Lisp實現[51]。
大量而單一的使用圓括號,是Lisp與其他程式語言家族最直接明顯的差別。為此學生們一直將Lisp戲稱為:「迷失在愚蠢的括號中」(Lost In Stupid Parentheses),或「大量煩人的多餘括號」(Lots of Irritating Superfluous Parentheses)[71]。但是S-表達式語法也承擔了Lisp多數能力:語法極其正規,利於電腦操縱。然而Lisp的語法不局限於傳統的括號表示法,它可以擴充為包括可替代表示法。例如,XMLisp是Common Lisp擴充,它採用元對象協定,整合了S-表達式和可延伸標記式語言(XML)。
Common Lisp和Scheme二者還支援「反引述」(backquote)算符(在Scheme中叫做准引述(英語:quasiquote)(quasiquote),這時錄入`字元(重音符)。它幾乎同於普通引述,除了它允許表達式被求值,並將它們的值插入到引述列表之中,這些表達式標記了,(逗號)表示去引述(unquote),或,@(逗號-at)表示拼接算符(unquote-splicing)。如果變數snue有值(barbaz),則`(foo,snue)求值為(foo(barbaz)),而`(foo,@snue)求值為(foobarbaz)。反引述經常用於定義宏展開[84][85]。
Julia Documentation - Introduction. [2022-11-16]. (原始內容存檔於2021-01-11). Julia builds upon the lineage of mathematical programming languages, but also borrows much from popular dynamic languages, including Lisp, Perl, Python, Lua, and Ruby. …… some advantages of Julia over comparable systems include: …… Lisp-like macros and other metaprogramming facilities.
Wolfram Language Q&A. Wolfram Research. [2022-11-16]. (原始內容存檔於2022-09-20). LISP and APL were two early influences, as was Stephen Wolfram's 1981 SMP symbolic computation language.
John McCarthy. History of Lisp(PDF). Artificial Intelligence Laboratory, Stanford University. 12 February 1979 [2021-10-25]. (原始內容(PDF)存檔於2020-11-07). There were two motivations for developing a language for the IBM 704. First, IBM was generously establishing a New England Computation Center at M.I.T. …… Second, IBM was undertaking to develop a program for proving theorems in plane geometry (based on an idea of Marvin Minsky’s), ……. …… In connection with IBM’s plane geometry project, Nathaniel Rochester and Herbert Gelernter(英語:Herbert Gelernter) (on the advice of McCarthy) decided to implement a list processing language within FORTRAN, ……. This work was undertaken by Herbert Gelernter and Carl Gerberich at IBM and led to FLPL, standing for FORTRAN List Processing Language. …… I spent the summer of 1958 at the IBM Information Research Department at the invitation of Nathaniel Rochester and chose differentiating algebraic expressions as a sample problem. It led to the following innovations beyond FLPL: a. Writing recursive function definitions using conditional expressions. …… b. The maplist function that forms a list of applications of a functional argument to the elements of a list. …… c. To use functions as arguments, one needs a notation for functions, and it seemed natural to use the λ-notation of Church (1941). …… d. The recursive definition of differentiation made no provision for erasure of abandoned list structure. …… The implementation of LISP began in Fall 1958. …… LISP is now the second oldest programming language in present widespread use (after FORTRAN and not counting APT, which isn’t used for programming per se).
SICP: Foreword. (原始內容存檔於2001-07-27). Lisp is a survivor, having been in use for about a quarter of a century. Among the active programming languages only Fortran has had a longer life.
Guy L. Steele Jr., Gerald J. Sussman. The Art of the Interpreter of the Modularity Complex (Parts Zero, One, and Two). MIT Libraries. May 1978 [2020-08-01]. hdl:1721.1/6094. (原始內容存檔於2021-01-24). Contrary to popular belief, LISP was not originally derived from Church's λ-calculus [Church] [LISP History]. The earliest LISP did not have a well-defined notion of free variables or procedural objects. Early LISP programs were similar to recursion equations, defining functions on symbolic expressions ("S-expressions"). They differed from the equations of pure recursive function theory Kleene by introducing the conditional expression construction (often called the "McCarthy conditional"), to avoid "pattern-directed invocation". That is, in recursive function theory one would define the factorial function by the following two equations: factorial(0) = 1 factorial(successor(x)) = successor(x) * factorial(x) In early LISP, however, one would have written: factorial[x] = [x=0 → 1; T → x*factoria1[x-1]] where "[a → b; T → c]" essentially means "if a then b else c". The recursive function theory version depends on selecting which of two equations to use by matching the argument to the left-hand sides (such a discipline is actually used in the PROLOG language [Warren]); the early LISP version represents this decision as a conditional expression. The theory of recursion equations deals with functions over the natural numbers. In LISP, however, one is interested in being able to manipulate algebraic expressions, programs, and other symbolic expressions as data structures. While such expressions can be encoded as numbers (using the technique of "arithmetization" developed by Kurt Gödel), such an encoding is not very convenient. Instead, a new kind of data called "S-expressions" (for "symbolic expressions") is introduced specifically to provide convenient encodings. S-expressions can be defined by a set of formal inductive axioms analogous to the Peano postulates used to define natural numbers.
John McCarthy. History of Lisp(PDF). Artificial Intelligence Laboratory, Stanford University. 12 February 1979 [2021-10-25]. (原始內容存檔(PDF)於2020-11-07). To use functions as arguments, one needs a notation for functions, and it seemed natural to use the λ-notation of Church (1941). I didn’t understand the rest of his book, so I wasn’t tempted to try to implement his more general mechanism for defining functions. Church used higher order functionals instead of using conditional expressions. Conditional expressions are much more readily implemented on computers. …… One mathematical consideration that influenced LISP was to express programs as applicative expressions built up from variables and constants using functions. I considered it important to make these expressions obey the usual mathematical laws allowing replacement of expressions by expressions giving the same value. The motive was to allow proofs of properties of programs using ordinary mathematical methods. This is only possible to the extent that side-effects can be avoided. Unfortunately, side-effects are often a great convenience when computational efficiency is important, and 「functions」 with side-effects are present in LISP. However, the so-called pure LISP is free of side-effects, and (Cartwright 1976) and (Cartwright and McCarthy 1978) show how to represent pure LISP programs by sentences and schemata in first order logic and prove their properties. …… Free variables. In all innocence, James R. Slagle(英語:James Robert Slagle) programmed the following LISP function definition and complained when it didn’t work right ……. …… In modern terminology, lexical scoping was wanted, and dynamic scoping was obtained. I must confess that I regarded this difficulty as just a bug and expressed confidence that Steve Russell would soon fix it. He did fix it but by inventing the so-called FUNARG device that took the lexical environment along with the functional argument. Similar difficulties later showed up in Algol 60, and Russell’s turned out to be one of the more comprehensive solutions to the problem. While it worked well in the interpreter, comprehensiveness and speed seem to be opposed in compiled code, and this led to a succession of compromises. …… the interested reader is referred to (Moses 1970) as a place to start. David Turner(英語:David Turner (computer scientist)). Some History of Functional Programming Languages(PDF). [2021-10-25]. (原始內容(PDF)存檔於2020-04-15). The data on which LISP works is the S-language. …… The M-language defines computations on S-expressions. …… This is computationally complete. McCarthy (1960, Sect. 6) showed an arbitrary flowchart can be coded as mutually recursive functions. The M-language of McCarthy (1960) is first order, as there is no provision to pass a function as argument or return a function as result. However, McCarthy shows that M-language expressions and functions can be easily encoded as S-expressions and then defines in the M-language functions, eval and apply, that correctly interpret these S-expressions. Thus LISP allows meta-programming, that is treating program as data and vice versa, by appropriate uses of eval and quote. The 1960 paper gives the impression, quite strongly, that McCarthy saw this as removing any limitation stemming from the M-Language itself being first order. It was originally intended that people would write programs in the M-language, in an Algol-like notation. In practice LISP programmers wrote their code directly in the S-language form, and the M-language became a kind of ghost that hovered in the background — theoretically important but nobody used it. In LISP 1.5 (McCarthy et al. 1962) atoms acquired property lists, which serve several purposes and numbers appeared, as another kind of atom, along with basic arithmetic functions. …… LISP was not based on the lambda calculus, despite using the word 「LAMBDA」 to denote functions. At the time he invented LISP, McCarthy was aware of (Church 1941) but had not studied it. The theoretical model behind LISP was Kleene’s theory of first order recursive functions. (McCarthy made these statements, or very similar ones, in a contribution from the floor at the 1982 ACM symposium on LISP and functional programming in Pittsburgh. No written version of this exists, as far as know.) The M-language was first order, as already noted, but you could pass a function as a parameter by quotation, i.e. as the S-expression which encodes it. Unfortunately, this gives the wrong binding rules for free variables (dynamic instead of lexicographic). …… McCarthy (1978) reports that this problem (wrong binding for free variables) showed up very early in a program of James Slagle. At first McCarthy assumed it was a bug and expected it to be fixed, but it actually springs from something fundamental — that meta-programming is not the same as higher order programming. Various devices were invented to get round this FUNARG problem, as it became known. Not until SCHEME (Sussman 1975) did versions of LISP with default static binding appear. Today all versions of LISP are lambda calculus based.
John McCarthy. Recursive functions of symbolic expressions and their computation by machine, Part I.(PDF). Communications of the ACM (ACM New York, NY, USA). 1960, 3 (4): 184–195 [2021-09-23]. doi:10.1145/367177.367199. (原始內容存檔(PDF)於2021-02-19). A conditional expression has the form (p1 → e1, …, pn → en) where the p's are propositional expressions and the e's are expressions of any kind. It may be read, 「If p1 then e1 otherwise if p2 then e2, …, otherwise if pn then en,」 or 「p1 yields e1, …, pn yields en.」 I sent a proposal for conditional expressions to a CACM forum on what should be included in Algol 60. Because the item was short, the editor demoted it to a letter to the editor, for which CACM subsequently apologized. The notation given here was rejected for Algol 60, because it had been decided that no new mathematical notation should be allowed in Algol 60, and everything new had to be English. The if...then...else that Algol 60 adopted was suggested by John Backus. John McCarthy, Paul W. Abrahams, Daniel J. Edwards, Timothy P. Hart, Michael I. Levin. LISP 1.5 Programmer's Manual(PDF) 2nd. MIT Press. 1985 [1962] [2021-10-25]. ISBN 0-262-13011-4. (原始內容存檔(PDF)於2021-03-02). The conditional expression [p1 → e1; …; pn → en] is translated into (COND (p1* e1*) … (pn* en*)).
John McCarthy, Paul W. Abrahams, Daniel J. Edwards, Timothy P. Hart, Michael I. Levin. LISP 1.5 Programmer's Manual(PDF) 2nd. MIT Press. 1985 [1962] [2021-10-25]. ISBN 0-262-13011-4. (原始內容存檔(PDF)於2021-03-02). Mathematically, it is possible to have functions as arguments of other functions. For example, in arithmetic one could define a function operate [op;a;b], where op is a functional argument that specifies which arithmetic operation is to be performed on a and b. …… In LISP, functional arguments are extremely useful. A very important function with a functional argument is maplist. Its M-expression definition is maplist[x;fn]=[null[x]→NIL; T→cons[fn[x];maplist[cdr[x];fn]]] …… The functional argument is, of course, a function translated into an S-expression. It is bound to the variable fn and is then used whenever fn is mentioned as a function. The S-expression for maplist itself is as follows: (MAPLIST (LAMBDA (X FN) (COND ((NULL X) NIL) (T (CONS (FN X) (MAPLIST (CDR X) FN))) ))) …… Using maplist, we define change by change[a]=maplist[a;λ[[j];cons[car[j];X]]] This is not a valid M-expression as defined syntactically in section 1.5 because a function appears where a form is expected. This can be corrected by modifying the rule defining an argument so as to include functional arguments: <argument> ::= <form> | <function> We also need a special rule to translate functional arguments into S-expression. If fn is a function used as an argument, then it is translated into (FUNCTION fn*). Example (CHANGE (LAMBDA (A) (MAPLIST A (FUNCTION (LAMBDA (J) (CONS (CAR J) (QUOTE X))) ))) An examination of evalquote shows that QUOTE will work instead of FUNCTION, provided that there are no free variables present. Special Operator FUNCTION. Common Lisp HyperSpec. [2022-11-21]. (原始內容存檔於2022-11-30). Syntax: functionname ⇒ function Arguments and Values: name - a function name or lambda expression. function - a function object. Description: The value of function is the functional value of name in the current lexical environment. …… Notes: The notation #' name may be used as an abbreviation for (function name). Function FUNCALL. Common Lisp HyperSpec. [2022-12-14]. (原始內容存檔於2022-12-25). Syntax: funcallfunction&restargs ⇒ result* Arguments and Values: function - a function designator. args - arguments to the function. results - the values returned by the function. Description: funcall applies function to args. If function is a symbol, it is coerced to a function as if by finding its functional value in the global environment.
John McCarthy, Paul W. Abrahams, Daniel J. Edwards, Timothy P. Hart, Michael I. Levin. LISP 1.5 Programmer's Manual(PDF) 2nd. MIT Press. 1985 [1962] [2021-09-23]. ISBN 0-262-13011-4. (原始內容(PDF)存檔於2021-03-02). A function can be simply a name. In this case its meaning must be previously understood. A function may be defined by using the lambda notation and establishing a correspondence between the arguments and the variables used in a form. If the function is recursive, it must be given a name by using a label. …… When a symbol stands for a function, the situation is similar to that in which a symbol stands for an argument. When a function is recursive, it must be given a name. This is done by means of the form LABEL, which pairs the name with the function definition on the a-list. The name is then bound to the function definition, just as a variable is bound to its value. In actual practice, LABEL is seldom used. It is usually more convenient to attach the name to the definition in a uniform manner. This is done by putting on the property list of the name, the symbol EXPR followed by the function definition. The pseudo-function define used at the beginning of this section accomplishes this. When apply interprets a function represented by an atomic symbol, it searches the p-list of the atomic symbol before searching the current a-list. Thus a define will override a LABEL. The fact that most functions are constants defined by the programmer, and not variables that are modified by the program, is not due to any weakness of the system. On the contrary, it indicates a richness of the system which we do not know how to exploit very well.
John McCarthy. Recursive functions of symbolic expressions and their computation by machine, Part I.(PDF). Communications of the ACM (ACM New York, NY, USA). 1960, 3 (4): 184–195 [2021-09-23]. doi:10.1145/367177.367199. (原始內容(PDF)存檔於2021-02-19). In this article, we first describe a formalism for defining functions recursively. …… Next, we describe S-expressions and S-functions, give some examples, and then describe the universal S-function apply which plays the theoretical role of a universal Turing machine and the practical role of an interpreter. Then we describe the representation of S-expressions in the memory of the IBM 704 by list structures similar to those used by Newell, Shaw(英語:Cliff Shaw) and Simon, and the representation of S-functions by program. Then we mention the main features of the LISP programming system for the IBM 704. Next comes another way of describing computations with symbolic expressions, and finally we give a recursive function interpretation of flow charts. …… We shall need a number of mathematical ideas and notations concerning functions in general. Most of the ideas are well known, but the notion of conditional expression is believed to be new, and the use of conditional expressions permits functions to be defined recursively in a new and convenient way. …… We shall first define a class of symbolic expressions in terms of ordered pairs and lists. Then we shall define five elementary functions and predicates, and build from them by composition, conditional expressions, and recursive definitions an extensive class of functions of which we shall give a number of examples. We shall then show how these functions themselves can be expressed as symbolic expressions, and we shall define a universal function apply that allows us to compute from the expression for a given function its value for given arguments. Finally, we shall define some functions with functions as arguments and give some useful examples. …… The LISP programming system is a system for using the IBM 704 computer to compute with symbolic information in the form of S-expressions. …… The basis of the system is a way of writing computer programs to evaluate S-functions. …… In addition to the facilities for describing S-functions, there are facilities for using S-functions in programs written as sequences of statements along the lines of FORTRAN or ALGOL. …… There are a number of ways of defining functions of symbolic expressions which are quite similar to the system we have adopted. Each of them involves three basic functions, conditional expressions, and recursive function definitions, but the class of expressions corresponding to S-expressions is different, and so are the precise definitions of the functions. We shall describe one of these variants called linear LISP. …… Since both the usual form of computer program and recursive function definitions are universal computationally, it is interesting to display the relation between them. The translation of recursive symbolic functions into computer programs was the subject of the rest of this report. In this section we show how to go the other way, at least in principle.
Michael J. Fischer(英語:Michael J. Fischer). Lambda-Calculus Schemata(PDF). LISP AND SYMBOLIC COMPUTATION: An International Journal, 6, 259–288. 1993 [2021-11-10]. (原始內容(PDF)存檔於2022-03-02). Two general approaches were taken in order to have programming languages with fully specified semantics: (i) Better specification methods were developed that were adequate to fully describe existing large programming languages such as PL/1. (ii) New languages were developed with clean mathematical structure that were more amenable to formal description. McCarthy pioneered the latter approach in basing the LISP 1.5 programming language on a simpler functional language, sometimes called 「pure LISP」 or M-expressions, that was defined in a mathematical style, independent of a particular machine or implementation. Pure LISP allows the definition and evaluation of functions over S-expressions. The lambda notation for functional abstraction is borrowed from Church’s lambda calculus, but otherwise there is little similarity between the two systems. Pure LISP has no higher-order functions, and call-by-value evaluation order is implicitly assumed. Two special constructs, conditional expressions and the label operator, allow recursive functions to be defined. Limited as it is, pure LISP is nevertheless powerful enough to express all partial recursive functions and hence provides an adequate basis for a theory of computation. The LISP 1.5 programming language extends pure LISP in many ways that make it more useful in practice but at the same time tend to destroy its clean mathematical properties. Its semantics is defined by an interpreter written in a mixture of pure LISP and English. The distinction between programs and data is blurred. Higher-order functions, assignment, and a global symbol table are added.
John McCarthy. History of Lisp(PDF). Artificial Intelligence Laboratory, Stanford University. 12 February 1979 [2021-10-25]. (原始內容存檔(PDF)於2020-11-07). The programs to be hand-compiled were written in an informal notation called M-expressions(英語:M-expression) intended to resemble FORTRAN as much as possible. Besides FORTRAN-like assignment statements and go tos, the language allowed conditional expressions and the basic functions of LISP. Allowing recursive function definitions required no new notation from the function definitions allowed in FORTRAN I - only the removal of the restriction - as I recall, unstated in the FORTRAN manual - forbidding recursive definitions. The M-notation also used brackets instead of parentheses to enclose the arguments of functions in order to reserve parentheses for list-structure constants. It was intended to compile from some approximation to the M-notation, but the M-notation was never fully defined, because representing LISP functions by LISP lists became the dominant programming language when the interpreter later became available. A machine readable M-notation would have required redefinition, because the pencil-and-paper M-notation used characters unavailable on the IBM 026 key punch(英語:Keypunch). The READ and PRINT programs induced a de facto standard external notation for symbolic information, e.g. representing x + 3y + z by (PLUS X (TIMES 3 Y) Z) and (∀x)(P (x) ∨ Q(x, y) by (ALL (X) (OR (P X) (Q X Y))). …… Many people participated in the initial development of LISP, and I haven’t been able to remember all their contributions and must settle, at this writing, for a list of names. I can remember Paul Abrahams, Robert Brayton, Daniel Edwards, Patrick Fischer, Phyllis Fox, Saul Goldberg, Timothy Hart, Louis Hodes, Michael Levin, David Luckham, Klim Maling, Marvin Minsky, David Park, Nathaniel Rochester of IBM, and Steve Russell.
Stoyan, Herbert. Early LISP history (1956–1959). LFP '84: Proceedings of the 1984 ACM Symposium on LISP and functional programming. Association for Computing Machinery: 307. 1984-08-06. doi:10.1145/800055.802047. (原始內容存檔於2005-04-05). It was McCarthy's fortune that he found a financial basis for his work: The MIT Artificial Intelligence Project was founded on the first of September, 1958. McCarthy became an assistant professor in the department of Electrical Engineering (his branch was communication sciences), Minsky was already assistant professor in the department of mathematics. They received support from the Research Laboratory for Electronics in the form of the two programmers, a secretary, a typewriter and six graduate students. When Maling started his job at the first of September he met S. Russell who seems to have something to do already. Maling remembers: "We were housed in an office in the basement of one of MIT's buildings, near the computer center. Initially there was John, Steve Russell, Carol - a buxom Boston Irish secretary and I. Steve was a brilliant programmer who had worked for John at Dartmouth (I believe). He was what we then called a 'Programming bum' ...".
Stoyan, Herbert. Early LISP history (1956–1959). LFP '84: Proceedings of the 1984 ACM Symposium on LISP and functional programming. Association for Computing Machinery: 307. 1984-08-06. doi:10.1145/800055.802047. (原始內容存檔於2005-04-05). As far as we know the first universal function was indeed apply - eval was not present at all or not seen to be important. When McCarthy was working on this function S. Russel saw it and suggested translating it by hand - as he had done so often - and adding it to the program system. McCarthy recalls: "… this EVAL was written and published in the paper and Steve Russell said, look, why don't I program this EVAL and you remember the interpreter, 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 into 704 machine code fixing bugs 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 S-expression form ...".
John McCarthy. History of Lisp(PDF). Artificial Intelligence Laboratory, Stanford University. 12 February 1979 [2021-10-25]. (原始內容存檔(PDF)於2020-11-07). Another way to show that LISP was neater than Turing machines was to write a universal LISP function and show that it is briefer and more comprehensible than the description of a universal Turing machine. This was the LISP function eval[e,a], which computes the value of a LISP expression e - the second argument a being a list of assignments of values to variables. (a is needed to make the recursion work). Writing eval required inventing a notation representing LISP functions as LISP data, and such a notation was devised for the purposes of the paper with no thought that it would be used to express LISP programs in practice. Logical completeness required that the notation used to express functions used as functional arguments be extended to provide for recursive functions, and the LABEL notation was invented by Nathaniel Rochester for that purpose. …… S.R. Russell noticed that eval could serve as an interpreter for LISP, promptly hand coded it, and we now had a programming language with an interpreter. …… Once the eval interpreter was programmed, it became available to the programmer, and it was especially easy to use because it interprets LISP programs expressed as LISP data. In particular, eval made possible FEXPRS and FSUBRS which are 「functions」 that are not given their actual arguments but are given the expressions that evaluate to the arguments and must call eval themselves when they want the expressions evaluated. The main application of this facility is to functions that don't always evaluate all of their arguments; they evaluate some of them first, and then decide which others to evaluate. This facility resembles Algol's call-by-name but is more flexible, because eval is explicitly available. A first order logic treatment of 「extensional」 FEXPRs and FSUBRs now seems possible.
John McCarthy, Paul W. Abrahams, Daniel J. Edwards, Timothy P. Hart, Michael I. Levin. LISP 1.5 Programmer's Manual(PDF) 2nd. MIT Press. 1985 [1962] [2021-10-25]. ISBN 0-262-13011-4. (原始內容存檔(PDF)於2021-03-02).「 A form is an expression that can be evaluated. A form that is merely a constant has that constant as its value. If a form is a variable, then the value of the form is the S-expression that is bound to that variable at the time when we evaluate the form. …… A function can be simply a name. In this case its meaning must be previously understood. A function may be defined by using the lambda notation and establishing a correspondence between the arguments and the variables used in a form. If the function is recursive, it must be given a name by using a label. …… An interpreter or universal function is one that can compute the value of any given function applied to its arguments when given a description of that function. (Of course, if the function that is being interpreted has infinite recursion, the interpreter will recur infinitely also.) We are now in a position to define the universal LISP function evalqyote[fn;args]. When evalquote is given a function and a list of arguments for that function, it computes the value of the function applied to the arguments. LISP functions have S-expressions as arguments. In particular, the argument "fn" of the function evalquote must be an S-expression. Since we have been writing functions as M-expressions, it is necessary to translate them into S-expressions. …… evalquote is defined by using two main functions, called eval and apply. apply handles a function and its arguments, while eval handles forms. Each of these functions also has another argument that is used as an association list for storing the values of bound variables and function names. …… A variable is a symbol that is used to represent an argument of a function. …… The formalism for variables in LISP is the Church lambda notation. The part of the interpreter that binds variables is called apply. When apply encounters a function beginning with LAMBDA, the list of variables is paired with the list of arguments and added to the front of the a-list During the evaluation of the function, variables may be encountered. They are evaluated by looking them up on the a-list. If a variable has been bound several times, the last or most recent value is used. The part of the interpreter that does this is called eval. The following example will illustrate this discussion. Suppose the interpreter is given the following doublet: fn:(LAMBDA (X Y) (CONS X Y)) args:(A B) evalquote will give these arguments to apply. (Look at the universal function of Section I.) apply[(LAMBDA (X Y) (CONS X Y)); (A B);NIL] apply will bind the variables and give the function and a-list to eval. eval[(CONS X Y); ((X . A) (Y . B))] eval will evaluate the variables and give it to cons. cons[A;B] = (A . B) The actual interpreter skips one step required by the universal function, namely, apply[CONS;(A B);((X . A) (Y . B))]. …… It is sometimes assumed that a constant stands for itself as opposed to a variable which stands for something else. …… It seems more reasonable to say that one variable is more nearly constant than another if it is bound at a higher level and changes value less frequently. In LISP, a variable remains bound within the scope of the LAMBDA that binds it. When a variable always has a certain value regardless of the current a-list, it will be called a constant. This is accomplished by means of the property list (p-list) of the variable symbol. Every atomic symbol has a p-list. When the p-list contains the indicator APVAL, then the symbol is a constant and the next item on the list is the value. eval searches p-lists before a-lists when evaluating variables, thus making it possible to set constants. …… An interesting type of constant is one that stands for itself. NIL is an example of this. It can be evaluated repeatedly and will still be NIL. T, F. NIL, and other constants cannot be used as variables. …… The program form has the structure - (PROG, list of program variables, sequence of statements and atomic' symbols…) …… Program variables are treated much like bound variables, but they are not bound by LAMBDA. The value of each program variable is NIL until it has been set to something else. To set a program variable, use the form SET. To set variable PI to 3.14 write (SET (OUOTE PI) 3.14). SETQ is like SET except that it quotes its first argument. Thus (SETQ PI 3.14). SETQ is usually more convenient. SET and SETQ can change variables that are on the a-list from higher level functions. The value of SET or SETQ is the value of its second argument. …… Every atomic symbol has a property list. When an atomic symbol is read in for the first time, a property list is created for it. A property list is characterized by having the special constant 777778 (i.e., minus 1) as the first element of the list. The rest of the list contains various properties of the atomic symbol. Each property is preceded by an atomic symbol which is called its indicator. Some of the indicators are: PNAME - the BCD(英語:BCD (character encoding)) print name of the atomic symbol for input-output use. EXPR - S-expression defining a function whose name is the atomic symbol on whose property list the EXPR appears. SUBR - Function defined by a machine language subroutine. APVAL - Permanent value for the atomic symbol considered as a variable. The atomic symbol NIL has two things on its property list - its PNAME, and an APVAL that gives it a value of NIL. Its property list looks like this:
……
The indicator EXPR points to an S-expression defining a function. The function define puts EXPR's on property lists. After defining ff, its property list would look like this
……
An indicator on a property list that does not have a property following it is called a flag. …… Numbers are represented by a type of atomic symbol in LISP. This word consists of a word with -1 in the address, certain bits in the tag which specify that it is a number and what type it is, and a pointer to the number itself in the decrement of this word. Unlike atomic symbols, numbers are not stored uniquely. For example, the decimal number 15 is represented as follows:
special[x]SUBRpseudo-function The list x contains the names of variables that are to be declared SPECIAL. …… common[x]SUBRpseudo-function The list x contains the names of variables that are to be declared COMMON. …… PROG feature is an FSUBR coded into the system. …… When a set or a setq is encountered, the name of the variable is located on the a-list. The value of the variable (or cdr of the pair) is actually replaced with the new value. …… The following points should be noted concerning declared variables. 1. Program variables follow the same rules as λ variables do. a. If a variable is purely local, it need not be declared. b. Special variables can be used as free variables in compiled functions. They may be set at a lower level than that at which they are bound. c. Common program variables maintain complete communication between compiled programs and the interpreter. 2. set as distinct from setq can only be used to set common variables.」
Timothy P. Hart, Michael I. Levin. AI Memo 39-The new compiler(PDF). [2022-11-24]. (原始內容存檔(PDF)於2022-04-19). The purpose of the LISP Compiler is to replace S-expression definitions of functions with efficient machine language subroutines. A subroutine can be expected to run about 40 times as fast as the interpreter can execute the same function from its S-expression definition. Subroutines typically take 70-80 per cent of the storage required by their corresponding S-expressions.
Timothy P. Hart, Michael I. Levin. LISP 1.5 compiler. [2022-11-24]. (原始內容存檔於2022-08-13).
Gerald J. Sussman, Guy L. Steele Jr.The Revised Report on SCHEME: A Dialect of LISP. 1978 [2021-10-26]. (原始內容存檔於2022-04-06). SCHEME is a dialect of LISP. It is an expression-oriented, applicative order, interpreter-based language which allows one to manipulate programs as data. It differs from most current dialects of LISP in that it closes all lambda-expressions in the environment of their definition or declaration, rather than in the execution environment. This has the consequence that variables are normally lexically scoped, as in ALGOL. However, in contrast with ALGOL, SCHEME treats procedures as a first-class data type. They can be the values of variables, the returned values of procedures, and components of data structures. Another difference from LISP is that SCHEME is implemented in such a way that tail-recursions execute without net growth of the interpreter stack. The effect of this is that a procedure call behaves like a GOTO and thus procedure calls can be used to implement iterations, as in PLASMA.
Gerald Jay Sussman, Terry Winograd. Micro-planner Reference Manual. AI Memo No, 203, MIT Project MAC. 1970 [2022-12-07]. (原始內容存檔於2022-12-07). Micro-Planner is an implementation of a subset of Cal Hewitt's language, PLANNER by Gerald Jay Sussman, Terry Winograd, and Eugene Charniak on the AI group computer in LISP.
Guy L.Steele, Jr., Richard P. Gabriel. The evolution of Lisp. The second ACM SIGPLAN conference on History of programming languages. ACM: 231–270. 1993 [2022-11-19]. (原始內容存檔於2022-11-12). In this history of the evolution of Lisp, we have seen that Lisp seems to have a more elaborate and complex history than languages with wider usage. It would seem that almost every little research group has its own version of Lisp and there would appear to be as many Lisps as variations on language concepts. It is natural to ask what is so special or different about Lisp that explains it. There are six basic reasons: …… Its theoretical foundations. Lisp was founded on the footing of recursive function theory and the theory of computability. The work on Scheme aligned it with Church's lambda calculus and denotational semantics. Its purest form is useful for mathematical reasoning and proof. …… Its expressiveness. Lisp has proved itself concerned more with expressiveness than anything else. …… Its malleability. It is easy with Lisp to experiment with new language features, because it is possible to extend Lisp in such a way that the extensions are indistinguishable to users from the base language. Primarily this is accomplished through the use of macros, which have been part of Lisp since 1963 [Hart 1963]. …… Its interactive and incremental nature. It is easy to explore the solutions to programming problems in Lisp, because it is easy to implement part of a solution, test it, modify it, change design, and debug the changes. …… Its operating system facilities. Many Lisp implementations provide facilities reminiscent of operating systems: a command processor, an automatic storage management facility, file management, display (windows, graphics, mouse) facilities, multitasking, a compiler, an incremental (re)linker/loader, a symbolic debugger, performance monitoring, and sometimes multiprocessing. …… Its people. Of course, languages do not diversify themselves; people diversify languages. ……Lisp is the language of artificial intelligence, among other things. …… Another attraction is that Lisp is a language of experts, which for our purposes means that Lisp is not a language designed for inexpert programmers to code robust reliable software.
John McCarthy, Paul W. Abrahams, Daniel J. Edwards, Timothy P. Hart, Michael I. Levin. LISP 1.5 Programmer's Manual(PDF) 2nd. MIT Press. 1985 [1962] [2021-10-25]. ISBN 0-262-13011-4. (原始內容(PDF)存檔於2021-03-02).「 To define these functions, we use the pseudo-function define. …… A pseudo-function is a function that is executed for its effect on the system in core memory, as well as for its value. define causes these functions to be defined and available within the system. Its value is a list of the functions defined ……. …… define[x]:EXPRpseudo-function The argument of define, x, is a list of pairs ((u1 v1) (u2 v2) … (un vn)) where each u is a name and each v is a λ-expression for a function. For each pair, define puts an EXPR on the property list for u pointing to v. The function of define puts things on at the front of the property list. The value of define is the list of u's. define[x] = deflist[x;EXPR] deflist[x;ind]:EXPRpseudo-function The function deflist is a more general defining function. Its first argument is a list of pairs as for define. Its second argument is the indicator that is to be used. After deflist has been executed with (ui vi) among its first argument, the property list of ui will begin:
Kent M. Pitman(英語:Kent Pitman). The Revised Maclisp Manual. 1983, 2007 [2021-10-26]. (原始內容存檔於2022-03-28). DEFUNSpecial Form(DEFUN namespec . definitionspec) DEFUN offers a way of associating a functional definition with a symbol. …… DEFUN can be used to define both normal functions and special forms (fexprs and macros). …… ;; Normal expr or lexpr function definitions (DEFUN name bvl . body) …… If name is a symbol and bvl is a list of symbols which is free of &keywords (to be described below), the definition is an expr or lexpr definition. In Maclisp, this would be essentially equivalent to writing (DEFPROP name (LAMBDA bvl . body) EXPR). …… Note also that the keyword EXPR is used for both expr and lexpr definitions. The only distinction between expr and lexpr definitions is whether the bvl is a symbol or a list, but they are specified in the same way and looked up from the same property. …… A fexpr(英語:fexpr) is a function for which the formal parameters are not evaluated. The form of a fexpr definition is: (DEFUN name FEXPR (sym) . body). The lambda expression which describes a fexpr should expect to receive exactly one argument which will be the list of (unevaluated) arguments given in the call to the fexpr, so usually there is only one bound variable (sym) in the bound variable list. …… DEFUN can also be used to instantiate a MACRO definition. …… The syntax for a macro definition is (DEFUN name MACRO (sym) . body), where sym will become bound to the whole macro form to be expanded (including the name). Note that this argument convention is different than fexprs, which only receive the cdr of the call form. …… DEFUN was introduced into Maclisp in March, 1969. Although now it is recognized as the standard function defining form because it shields the user from the implementational details of how the function is defined ……. …… DEFPROP Function (DEFPROP sym val indicator) Gives sym a property called indicator with value val. The arguments are not evaluated. DEFPROP should not be used imbedded in other expressions. It is intended to occur at toplevel to assign properties that are set up once and never changed. In other places, use PUTPROP with three quoted arguments.請檢查|date=中的日期值 (幫助)