Lisp's roots [Repost]

xiaoxiao2021-03-05  29

The root of Lisp

Paul Graham

John McChalli published an extraordinary papers in 1960. He has contributed to the contribution of the program in this paper. 1 He showed us that only a simple operator On the basis of a symbol indicating the function, how to construct a complete programming language. McCarti said that this language is LISP, meaning list processing, because one of his main thinking is to use a simple data structure table (List ) To represent code and data.

It is worth noting that McCartin's discovery is not only a big event in the era of computer history, but also a model that is increasingly tended in our time. I think there are only two truly clean and neat, consistent programming mode. : C language mode and Lisp language mode. These two are like two highlands, which is especially the lowland of the swamp. As the computer is getting stronger, the newly developed language has been firmly tending to LISP mode For twenty years, a popular secret that develops new programming languages ​​is to take C language computing mode, gradually add the characteristics of the LISP mode, such as runtime type, and unwanted unit collection.

In this article, I use the simplest terminology to explain the discovery of John McCarti. The key is that we must not only learn some interesting theory results, but also present the development direction of programming languages. LISP The different ordinary things - it is its quality definition - it is to write yourself. In order to understand this feature expressed by John McCha, we will trace his pace and convert his mathematical markers into the operation. Common Lisp code.

Seven original operators

Start us first define expressions. Expressions or one atom (Atom), is a letter sequence (such as foo), or a table (List) composed of zero or multiple expressions (List), between expressions Space is separated, put in a pair of brackets. Here are some expressions:

foo

()

(foo)

(Foo Bar)

(A b (c) d)

The last expression is a table consisting of four elements, and the third element itself is a table consisting of one element.

Expression 1 1 in arithmetic 2. The correct LISP expression also has a value. If the expression e is V, we say that E returns v. Next We will define several expressions and their return values .

If an expression is a table, we call the first element as the operator, the rest of the element is an independent variable. We will define seven original (in the sense of axiology) Operator: Quote, Atom, EQ, Car, CDR CONS, and COND.

(quote X) Returns x. For readability, we will make (quote a) to 'x.> (quote a)

a

> 'a

a

> (Quote (A B C))

(a b c)

(Atom x) Returns Atom Terry If the value of X is an atom or a blades, it returns (). In the LISP, we use the convention to use the atomic T true, and use the blank.> (atom 'a)

t

> (atom '(A b C))

()

> (atom '())

t

Since there is an operator that needs to be evaluated by a variable, we can take a look at the role of Quote. By reference (quote) a table, we avoid it to be evaluated. An unfounded table as an argument to analog Atom The operator will be considered as code:> (Atom (atom 'a))

t

In contrast, the referenced table is only considered to be a table, in which the table has two elements:> (atom 'a))

()

This is consistent with us using quotation marks in English. Cambridge (Cambridge) is a town in Massachusetts with a 90,000 population. The `` cambridge '' is a word consisting of 9 letters. Quote looks likely It is a bit surprising to have similar concepts with little other languages. It is closely related to the most distinctive features of LISP: code and data consist of the same data structure, and we use the quote operator to distinguish them. (EQ XY) Return T If the value of X and Y is the same atom or a holiday, it will return ().> (EQ 'A' a)

t

> (EQ 'A' B)

()

> (EQ '()' ())

t

(Car x) The value of the expected x is a table and returns the first element of x.> (car '(a b c)) a

(CDR X) The value of the expected x is a table and returns all elements after the first element of X.> (CDR '(A B C))

(b c)

(consx x y) The value of the expectation Y is a table and returns a new table. Its the first element is the value of X, followed by each element of the value of Y.> (CONS 'A' (B C))

(a b c)

> (Cons 'A (cons' B (CONS 'C' ()))))))

(a b c)

> (CAR (CONS 'A' (B C)))))

a

> (CDR (CONS 'A' (B C))))))

(b c)

(Cond (...) ...) The evaluation rules are as follows. The P expression requests to a return t. If such a P expression is found, the corresponding E expression value Return value for the entire COND expression.> (Cond ((EQ 'a' b) 'first)

((atom 'a)' second))

SECOND

When the expression starts in the five beginning in seven original operators, its own variable always requires a value. 2 We call such an operator as a function.

The representation of the function will then define a mark to describe the function. The function is represented as (Lambda)

...

)

e)

...

Atom (called

parameter),

E is an expression. If the first element of the expression is as above

((Lambda (...) ...)

The function call is called. Its value is calculated as follows. Each expression first requests, then EQ, then the value of each appearing in E, the value of each appearing is the corresponding one Value in the function call.

> ((Lambda (x) (consx x '(b)))' a)

(a b)

> ((Lambda (X Y) (CONS X (CDR Y)))

'z

'(a b c))

(z b c)

If an expression is the first element

F is atomic and

f is not the original operator

(f ...)

And the value of f is a function (lambda (...), then the value of the above expression is

((Lambda (...) ...)

The value. In other words, the parameter can not only be used as an operator in the expression:

> ((Lambda (f) (f '(b c))))

(Lambda (X) (CONS 'A X))))))

(a b c)

There is another function mark that makes the function mentioned itself so that we can easily define the recursive function. 3 mark

(Label F (lambda (...)))

Represents a function like a log (...), plus such features: Any F appearing in E will evaluate this Label expression, as if f is the parameter of this function.

Suppose we want to define a function (Subst X Y, it takes the expression X, the atomies y, and the table z do parameters, returns a table like Z, but the Y appears in Z (at any nested level) is replaced by X.

> (Subst 'M' B '(A B (A B C) D))

(a m (a m c) d)

We can represent this function like this

(Label Subst (Lambda (X Y Z)

(COND (atom z)

(COND ((EQ Z Y) x)

('T Z))))))

('T (Subst X Y (CAR Z))

(Subst x y (cdr z)))))))))))

We are notified

f = (label

f (lambda)

...

)

e))

(Defun f (...) e)

then

(Defun Subst (x y z)

(COND (atom z)

(COND ((EQ Z Y) x)

('T Z))))))

('T (Subst X Y (CAR Z))

Subst X Y (CDR Z)))))))))) Easy we see how to write a COND expression default clause. The first element is the clause of 'T always succeed.

(Cond (x y) ('t z))

I am equivalent to writing in some languages.

IF x Then Y else z

Some functions have since we have a method of representing a function, we define some new functions based on seven original operators. In order to facilitate our briefs to introduce some common modes. We use C

XR, where

X is a sequence of A or D to briefly record the combination of CAR and CDRs. For example (CADR

e) Yes (Car (CDR)

e) news, it returns

E The second element.

> (CADR '((A b) (C D) e)))

(C D)

> (Caddr '((A b) (C D) E)))

e

> (CDAR '((A b) (C D) E)))

(b)

We still use (List

...

Representation (cons)

... (cons)

'()) ...).

> (Cons 'A (cons' B (CONS 'C' ()))))))

(a b c)

> (List 'A' B 'C)

(a b c)

Now we define some new functions. I add some points behind the function name to distinguish between the function and define their original functions, and avoid conflicts with existing Common Lisp.

(NULL. X) Test if its own variable is empty. (Defun null. (x)

(EQ x '())))

> (NULL. 'a)

()

> (NULL. '())

t

(AND. x y) Returns T If its two arguments are T, it returns (). (Defun and. (x y)

(Cond (Cond ('t)))))))

('t' ()))))))))))

> (AND. (atom 'a) (EQ' A 'A))

t

> (AND. (atom 'a) (EQ' A 'b)))

()

(NOT. X) Returns T If its argument returns (), returns () if its argument returns T. (Defun Not. (x)

(COND (x '())

('t' t))))))))

> (not. (EQ 'A' a))

()

> (not. (EQ 'A' b))

t

(Append. x y) Take two tables and return their links. (Defun append. (x y)

(Cond (null. x) y)

('T (CAR X) (append. (cdr x) y))))))))))))))

> (append. '(a b)' (C D)))

(a b c d)

> (append. '()' (C D)))

(C D)

(Pair. x y) Take two tables of the same length, returns a table composed of two-element table, the dual element table is an element pair of x, y, (DEFUN Pair. (x y)

(Cond ((NULL. x) (NULL. Y)) '())

((NOT. (atom x)) (not. (atom y))))))

(Cons (List (car x) (car y)

(Pair. (CDR) (CDR Y)))))))))))))))))))))))

> (Pair. '(x y z)' (a b c))

((x a) (y b) (z c))

Take the atom x and shape such as the table y returned by the form, returns the second element of the table that meets the following conditions: Its first element is X. (Defun Assoc. (xy)

(Cond ((CAAR Y) (Cadar Y))

( 'T (assoc. X (cdr y)))))> (assoc.' X '((x a) (y b)))

a

> (Assoc. 'x' ((x a) (y b)))))

New

A surprise, therefore we can define a function to connect the table, replace the expression, and so on. Maybe it is a beautiful representation, then the next step? Now we can write a function as our language interpreter: This function takes place Any LISP expression is made from variables and returns its value. As shown below:

(Defun EVAL. (E a)

(COND)

((Atom E) (Assoc. E)))

((ATOM (CAR E))

(COND)

((EQ (Car E) 'Quote (CADR E))

((EQ (CAR E) 'Atom) (Atom (EVAL. (CADR E) a))))))))

(EQ (CAR E) 'EQ) (EQ (EVAL. (CADR E) a)

(EVAL. (CADDR E) a))))))

((EQ (Car E) 'Car) (Car (EVAL. (CADR E) a))))))))))

((EQ (CAR E) 'CDR) (CDR (EVAL. (CADR E) a)))))))))

((EQ (CAR E) 'CONS) (CONS (EVAL. (CADR E) a)

(EVAL. (CADDR E) a))))))

((EQ (CAR E) 'COND) (EVCON. (CDR E) a)))

('T (EVAL. (CAR E) a)

(CDR E))

a))))))))))))))))

((EQ (Caar E) 'Label

(EVAL. (CDDAR E) (CDR E))

(CONS (List (Cadar E)) A))))

((EQ (Caar E) 'Lambda)

(EVAL. (CADDAR E)

(Append. (Cadar E) (EVLIS. (CDR E) a)))

a)))))))))))))))))))))))

(Defun Evcon. (C A)

(Cond ((CAAR C) a)

(EVAL. (Cadar C) a)))

('T (Evcon (CDR C) a))))))))))))))

(Defun evlis. (m a)

(Cond (NULL. m) '())

('T (EVAL. (Car M) a)

(EVLIS. (CDR M) a))))))))))))))

The definition is longer than we have seen before. Let us consider how it works.

Two arguments: E is the expression of the required value, A is a table consisting of a value assigned to the atom, which is a bit icon function call in the function call. This form is called the return value of the pair. Environment. It is to construct and search this table we wrote Pair. And Assoc ..

The skeleton of EVAL is a COND expression with four clauses. How to evaluate the expression depends on its type. The first clause handling the atom. If e is atom, we look for its value in the environment:

> (EVAL. 'X' ((x a) (y b))))))

a

The second clause is another COND that handles the expression of (a ...), where A is atom. This includes all original operators, each corresponding one clause.

> (EVAL. '(EQ' A 'A)' ())

t

> (EVAL. '(CONS X' (B C))

'((x a) (y b)))))))))

(a b c)

These clauses (except quote) are called EVAL. To find the value of the argument.

The last two clauses are more complicated. In order to seek a COND expression, we call a secondary function called EVCON. It is recursively evaluated to the COND clause, find the first element to return the clause. If you find The clause has returned the second element of this clause.> (EVAL. '(Cond (atom x)' Atom)

('t' list))

'((x' (a b))))))))))))

List

The last part of the second clause is handled. It replaces the atom as its value (should be a lambda or label expression) and then evaluate the result expression.

(EVAL. '(f' (b c))

((F (Cons' a x)))))))))))))

Become

(EVAL. '((Lambda (X) (CONS' A X)) '(B C))

((F (Cons' a x)))))))))))))

It returns (A b c).

The last COND two clauses process the first element is a function call for Lambda or Label. In order to evaluate the Label expression, first press the function name and the function itself into the environment, then call EVAL. In an interior, there is lambda expression Value. That is:

(Eval. '(Label Firstatom (lambda (x)

(Cond (atom x) x)

('T (firsttatom (car x))))))))))

Y)

'((y (((((((((A b) (C D)))))))))

Become

(Eval. '((Lambda (X)

(Cond (atom x) x)

('T (firsttatom (car x))))))))))

Y)

'((FIRSTATOM)

(label firstatom (lambda (x)

(Cond (atom x) x)

('T (FirstAtom (car x))))))))))))

(Y ((A b) (C D))))))))))))))

Finally returned A.

Finally, the expression is obtained as ((Lambda (... E) ...), first adjusting EVLIS. To obtain the value (...) corresponding to the variable (...), ) ... () Add to the environment, then evaluate the E.

(EVAL. '(Lambda (X Y) (CONS X (CDR Y)))

'a

'(B C D)))

'())

Become

(EVAL. '(CONS X (CDR Y))

((x a) (Y (b C D))))))))

Finally returned (a c d).

as a result of

Since understanding how Eval works, let's take a look at this means. We have got a very beautiful computational model here. Only quote, Atom, EQ, Car, CDR, CONS, and COND, we Define the function EVAL., It actually implements our language, use it to define any additional functions we want.

Of course, there have been various computational models - the most famous of the map foreground. But the map spirit is difficult to read. If you want a language to describe the algorithm, you may need more abstract, and this is John McCarti definition Lisp One of the goals.

John McCarti is still a lot of things in 1960. It does not have side effects, no continuous implementation (it is useful to use it together), there is no actual number, 4 no dynamic visual field. But these restrictions can make People are surprised to remedy with very little extra code. Steele and Sussman describe how to do this in a famous papers called `` interpreter's art '' .5

If you understand the EVAL of John McChak, you are not only to understand a stage in the history language history. These ideas are still the Semantic core of Lisp. So from a sense, learn John McChaki's original to show us What is LISP. With it, Lisp is the design of McCarti, it is better to say is his discovery. It is not born is a language used for artificial intelligence, fast prototype development or equivalent level task. It is what you try to process Results (one).

Over time, the intermediate language, that is, the language used by the intermediate layer programmer is in line with the LISP. Therefore, by understanding Eval, you are understanding what the future mainstream calculation mode is like. Note to translate John McCarti I will change as little as possible in the process of code. I have a thought of making code easier to read, but I still want to keep the original taste.

In John McCarti's paper, if f is represented, not empty form. I use empty list to make an example to run in Common Lisp. (FixMe)

I have skilled the Dotted Pairs, because you don't need it to understand evAl. I didn't mention Apply, although APPLY (its early form, the main role is to reference the variable), by John McCorty in 1960 called a universal function in 1960 Eval is just a subroutine called by Apply to complete all work.

I defined List and CXR, etc., because McCarti did this. In fact, CXR can be defined as a normal function. List can also be like this, if we modify EVAL, this is easy to accept, let function can accept Arbitrary number of arguments.

There are only five original operators in McCartin. He used Cond and Quote, but they might use them as part of his meta language. Didn't define logical operators and NOT, this is not a problem, because they can Defined as a suitable function.

In the definition of EVAL. We call other functions such as Pair. And Assoc., But any function called with the original operator can be replaced by EVAL. That is

(assoc. (car e) a)

Can write

(Eval. '((Label Assoc.

(lambda (x y)

(Cond ((CAAR Y) (Cadar Y))

('T (Assoc. x (cdr y)))))))))))))))))))))))))

(Car E)

a)

(CONS (List 'E E) (CONS (List' A) A))))

The EVAL of McCartin has an error. The 16th line is (equivalent) (EVLIS. (CDR E) a) instead (CDR E), which makes the argument to be evaluated twice in the call of a famous function. This shows When the paper is published, this description of EVAL has not been implemented in IBM 704 machine language. It also proves how difficult it is to ensure that the correctness of the program is not to run.

I also encountered a problem in McCarthy. After defining evAl, he continued to give some more advanced functions - accepted other functions as a function of the argument. He defined Maplist:

(Label Maplist

(lambda (x f)

(Cond ((NULL X) '())

('T (CONS (CDR X) F)))))))))))

Then use it to write a simple function Diff. But Diff is transmitted to Maplist.

X Do the function of parameters, which is captured by the reference to the parameter X in the maplist.

6

This is the eligibility of dynamic visual domain danger, even the earliest and more advanced functions are also wrong because it is wrong. Maybe McCartin has not fully realized the meaning of dynamic visual fields in 1960. Dynamic visualty People have existed a considerable time in the LISP implementation - until SUSSMAN and Stelec have developed Scheme in 1975. The visual field did not make Eval definition complicated, but the compiler is more difficult to write.

About this document ...

The root of Lisp

THIS Document Was Generated Using The Latex2html Translator Version 2K.1beta (1.48)

Copyright © 1993, 1994, 1995, 1996, Nikos Drakos, Computer Based Learning Unit, University of Leeds. Copyright © 1997, 1998, 1999, Ross Moore, Mathematics Department, Macquarie University, Sydney.

THE Command Line Arguments WERE: LATEX2HTML -SPLIT = 0 Roots_Of_Lisp.Texthe Translation Was Initiated by Dai Yuwen On 2003-10-24

FootNotes

... Contribution to the geometric contribution to the geometric contribution.

1

`` Recursive Functions of Symbolic Expressions and their computation by machine, part1. ''

Communication of the ACM 3: 4, April 1960, PP. 184-195.

... When the expression is starting with five beginning in seven original operators, its own variables are always required.

2

The expression of the other two operators quote and the COND is evaluated in different ways. When the quote expression is evaluated, its auto-variable is not evaluated, but is returned as the value of the entire expression. In one correct In the COND expression, only sub-expression plants on the L-shaped path will be evaluated.

Number.

3

Logically we don't need to define a new marker for this. In an existing mark, we can define a recursive function in an existing mark, we can define a recursive function. Maybe McCarthy does not know when writing this paper. Combiners; in any case, Label is readily readable.

... There is no actual number,

4

In the 1960 LISP of McCarti, it is possible to do an arithmetic, such as a number N atoms with N atoms.

... The art '' '' of the famous papers describing how to do this.

5

Guy Lewis Steele, Jr. And Gerald Jay Susseman, `` The Art of The Interpreter, or The Modular Complex (Parts Zero, ONE, AND TWO), 'Mit Al Lab Memo 453, May 1978.

... The reference to it is captured by the parameter X in the mapList.

6

The contemporary Lisp program will use MapCar here with MapCar. This example unlocked a mystery: MapList will be in Common Lisp. It is the earliest mapping function, Mapcar is later increased.

Dai Yuwen 2003-10-24

转载请注明原文地址:https://www.9cbs.com/read-37171.html

New Post(0)