Sei sulla pagina 1di 90

List Processing LISP

MacLennan- Chap. 9

History and Motivation

The Fifth Generation Comprises Three Overlapping Paradigms


functional programming object-oriented programming logic programming Lisp is for functional programming.
3

The Desire for an Algebraic ListProcessing Language


Lisp is developed in the 1950s for artificial intelligence programming. In these applications complex interrelationships among data must be represented. Natural data structures are:
Pointers Linked lists
4

In the 1950s Newell, Shaw, and Simon (at Carnegie institute of technology and the Rand Corporation) developed many of the ideas of list processing in the IPL family of programming languages. these ideas included the linked representation of list structures and the use of a stack (specifically, a push-down list) to implement recursion.

In the summer of 1956, the first major workshop on artificial intelligence was held at Dartmouth. At this workshop john McCarthy, then at MIT, heard a description of the ipl2 programming language. which had a low-level pseudo-code, or assembly-language-like syntax. McCarthy realized that an algebraic listprocessing language, on the style of the recently announced FORTRAN I system, would be very useful.
6

FLPL Was Based on Fortran


That summer Gerlernter and Gerberich of IBM were working, with the advice of McCarthy, on a geometry program. As a tool they developed FLPL, the Fortran list-processing language, by writing a set of list-processing subprograms for use with Fortran programs. One result of this work was the development of the basic list-processing primitives that were later incorporated into lisp.

McCarthy Developed the Central Ideas of LISP


FORTRAN I had only one conditional construct the arithmetic IF-statement. This construct was very inconvenient for list processing. which led McCarthy, in 1957, to write an IF function with three arguments: X = IF (N .EQ. 0, ICAR(Y) , ICDR(Y)) If N were zero, then X = ICAR(Y) else X = ICDR(Y)
8

An important consequence of this invention was that it made it feasible to compose IF function and the listprocessing functions to achieve more complicated actions.
Since FORTRAN does not permit recursive definitions, it became apparent that a new language was needed. In 1958 McCarthy began using recursion in conjunction with conditional expression in his definition of list-processing functions.
9

The Lisp List-Handling Routines Were Developed First


in the fall of 1958, implementation of a LISP system began. One important component of this was a set of primitive list-handling subroutines for the lisp run-time environment. These were the first parts of the system that were implemented. The original intention was to develop a compiler like FORTRAN. Therefore, to gain experience in code generation, a number of LISP programs were hand compiled into assembly language.
10

A LISP Universal Function Resulted in an Interpreter


McCarthy became convinced that recursive list-processing functions with conditional expressions formed an easierto-understand basis for the theory of computation than other formalisms such as Turing machines. Recursive Functions of Symbolic Expressions and Their Computation by Machine.
11

He defined a universal LISP function that could interpret any other lisp function. he wrote a LISP interpreter in LISP. Since manipulates only lists, writing a universal function required developing a way of representing LISP program as list structures.

12

For example the function call f [x+y; u*z] Would be represented by a list whose first element is f and whose second and third element are the lists representing x+y and u*z. in LISP this list is written as (f (plus x y) (times u z) )
13

The algol-like notation (e,g., f[x+y; u*z]) is called M-expressions (M for meta-language). The list notation is called Sexpressions (S for symbolic language)

14

LISP Became Widely Used in Artificial Intelligence


The first implementation of LISP was on IBM 704 LISP systems rapidly spread to other computers, and they now exist on virtually all machines, including microcomputers. LISP has become the most widely used programming language for artificial intelligence and other symbolic applications. LISP was standardized after a period of divergent evolution

15

DESIGN: STRUCTURAL ORGANIZATION

An Example LISP Program (in the Sexpression) Page 312

16

Function Application Is the Central Idea


programming language are often divided into two classes: Imperative language Depend heavily on an assignment statement and a changeable memory for accomplishing a programming task. Applicative language The central idea is function application, that is, applying a function to its argument .
17

In the LISP almost everything is a function application (f a1 a2an) where f is the function and a1, a2, , an are the arguments. This notation is called Combridge Polish (prefix notation). Example: (plus 2 3) (plus 10 5 8 64) LISP is fully parenthesized
18

Example
(set Freq (make-table text nil)) is a nested function application : set is applied to two arguments: Freq the result of applying make-table to the arguments text and nil. In an Algol-like language this would be written set (Freq, make-table (text, nil))
19

Example
(cond ((null x) 0) ((eq x y) (f x)) (t (g y)) ) In an Algol-like language this would be written If null(x) then 0 elseif x = y then f(x) else g(y) endif
20

function definition is accomplished by calling a function, defun, with three arguments: the name of the function, its formal parameter list, and its body.

21

Why is everything a function application in LISP?


Simplicity Principle
If there is only one basic mechanism in a language, the language is easier to learn, understand, and implement.

22

The List is the Primary Data Structure Constructor


We said that one of LISPs goals was to allow computation with Symbolic data. This is accomplished by allowing the programmer to manipulate lists of data. Example: (set text (to be or not to be)) the second argument to set is the list (to be or not to be) This list above is composed of four distinct atoms: to be or not
23

LISP manipulates list just like other languages manipulate number; they can be compared, passed to functions, put together, and taken apart.

24

Programs Are Represented as Lists


Function application and lists look the same. (make-table text nil) could either be a three-element list whose elements are the make-table, text, nil; or it could be an application of the function make-table to the arguments named text and nil. Because a LISP program is itself a list. If the list is quoted, then it is treated as data; that is, it is unevaluated.
25

If the list is quoted, then it is treated as data; that is, it is unevaluated. Example: (set text (to be or not to be)) (set text (to be or not to be)) What happens?
26

the fact that LISP represents both programs and data in the same way is of the utmost importance: it makes it very easy to write a LISP interpreter in LISP. it makes it convenient to have one LISP program generate and call for the execution of another LISP program. It also simplifies writing LISP programs that transform and manipulate other LISP programs.
27

These capabilities are important in artificial intelligence and other advanced programdevelopment environments. These amplification come with a reduction of readability.

28

LISP is often Interpreted


Most LISP systems provide interactive interpreters. We interact with the LISP interpreter by typing in function applications. The LISP system then interprets them and point out the result. Example: (plus 2 3) the system will respond 5 Similarly if we type (eq (plus 2 3) (difference 9 4)) the system will respond t
29

Pure Function
functions like eq and plus are pure functions (or simply functions) because they have no effect other than the computation of a value. Pure functions obey the Manifest Interface Principle because their interfaces are apparent (manifest).

30

The Manifest Interface Principle


All interfaces should be apparent (manifest) in the syntax.

31

Procedures
Some function in LISP are pseudo-function (or procedure). These are functions that have a side effect on the state of computer in addition to computing a result. Example: (set text (to be or not to be)) binds the name (atom) text to the (to be or not to be) that it is a list and return this list. The atom n can now be used as a name for this list in any expression, for example (set Freq (make-table text nil))
32

Function
another important pseudo-function is defun, which define a function. Example: (defun f (x1,x2, , xn) b) defines a function with the name f, formal parameters x1, x2, , xn; and body b The function application used to define functions is different in many dialects.
in LISP the binding process is dynamic, that is, it takes place at run-time.
33

DESIGN: DATA STRUCTURE

34

The Primitives Include Numeric Atoms


We classify LISP data structure (like other languages) into primitive and constructors. The principal constructor is the list: it permits more complicated structures to be built from simpler structures. The primitive data structures are the starting points to building process. Thus, the primitives are those data structure that are not build from any other: they have no parts. It is for this reason that they are called atoms.
35

There are at least two types of atoms in all LISP systems: Numeric Nonnumeric

36

LISP provides a very large set of primitive functions for manipulating numeric atoms: Arithmetic operations (plus, difference, etc.) Predecessor and successor function (sub1, add1) Maximum and minimum functions Relation tests (equal, lessp, greaterp) Predicates (i.e., tests, such as zerop, onep, minusp)

37

All of these functions take both integer and floating-point (and in some systems, multiple-precision) arguments and return results of the appropriate type.

38

Example
LISPs use of Combridge Polish limits its numerical applications. Example: (-b + (b - 4ac) ) /2a must be written (quotient (plus (minus b) (sqrt (difference (expt b 2) (times 4 a c)))) (times 2 a)
39

Nonnumeric Atoms Are Also Provided

These atoms are strings of characters that were originally intended to represent words or symbols.

40

Example
With few exceptions, the only operations that can be performed on nonnumeric atoms are comparisions for equality and inequality. This is done with function eq: Example: (eq x y) t if x and y are the same atom, nil if x and y are not the same atom,
41

the atom nil has many uses in LISP. This operation is often used as a base for recursive definitions. (eq x nil) (null x) nil is the noun and null is the corresponding adjective.

42

Some LISP systems provide additional types of atoms, such as strings. In these cases special operations for manipulating these values are also provided

43

Abstract Data Type

An abstract data type is a set of data values together with a set of operations on those values.

44

The Principal Constructor is the List


The characteristic method of data structuring provided by LISP is called the list. Lists are written in the S-expression notation by surrounding with parentheses the lists elements, which are separated by blanks. Lists can have none, one, or more elements, so they satisfy the Zero-One-Infinity Principle. The elements of lists can themselves be lists, so the Zero-One-Infinity Principle is also satisfied by the nesting level of lists.
45

The empty list, ( ) is considered equivalent to the atom nil: (eq ( ) nil) or (null ( ) ) Except the null list all lists are nonatomic, they are sometimes called composite data values.
46

We can find out whether or not something is an atom by using the atom predicate. Example: (atom to) t (atom (plus 2 3)) t (atom nil) t (atom (to be) ) nil (atom ( ( ) ) ) nil Notice neither ( ( ) ) nor (nil) is the null list
47

Constructor and Selector


Operations that build a structure are called constructors. Operation that extract their parts are called selectors.

48

Car and Cdr Access the Parts of Lists


Car : return the first element of the list. Cdr : returns all of a list except its first element. Example: (car (to be or not to be) ) returns the atom to (cdr (to be or not to be) ) returns the list (be or not to be)
49

Notice that the argument to car and cdr is always a nonnull list. Unlike car, cdr always returns a list. Car and Cdr are pure functions. The easiest way to think of the way they work is that they make a new copy of the list.

50

Car and Cdr can be used in combination to access the components of a list
Example: (set DS (Don Smith) 45 (august 25 1980) ) ) (car (cdr (cdr (cdr DS)))) returns the list (august 25 1980)
51

30000

In general, the nth element of a list can be access by n-1 cdrs followed by a car. The composition of cars and cdrs is represented by the sequence of as and ds between the initial c and the final r. This can be seen more clearly if the list is written as a linked data structure; then a d moves to the right and an a moves down.
52

Figure 9.2

53

Clearly, these sequence of as and ds can become quite complicated to read. Writing them is also error-prone. One solution to this is to write a set of special-purpose functions for accessing the part of a record. For example a function for accessing the hire date could be defined as (defun hire-date (r) (cadddr)) Then (hire-date DS) returns Don Smith hire date
54

Information Can Be Represented by Property Lists


A personnel record would not probably be represented in LISP in the way we have just described: it is too inflexible. A better arrangement is to precede each information with an indicator identifying the property. Example: (name (Don Smith) age 45 salary 30000 hire-date (august 25 1980) ) this method of representing information is called a property list or p-list. (P1 v1 P2 v2 Pn vn) each Pi is the indicator for a property and each vi is the corresponding property value
55

How can the properties of a p-list be accessed?


(defun getprop (p x) (if (eq (car x) p) (cadr x) (getprop p (cddr x)) )) Example: (getprop name DS) Return (Don Smith)

56

What will this function do if we ask for a property that is not in the property list? (getprop weight DS) Error: car of nil

57

One way to do this is to have getprop return a distinguished value if the property does not exist. An obvious choice is nil,
but this would not be a good choice since it would then be impossible to distinguish an undefined property from one that is defined but whose value is nil.
58

A better decision is to pick some atom, such as undefined-property, which is unlikely to be used for any other purpose. (getprop weight DS) undefined-property

59

Information Can Be Represented in Association List


The property list data structure works best when exactly one value is to be associated with each property. Some properties are flags that have no associated value for example retired flag in our personnel record. if a property has several associated values, for example the manages property, might be associated with the names of everyone managed by Don Smith.
60

These problems are solved by another common LISP data structure, the association list, or a-list. An a-list is a list of pairs. The general form of an a-list is a list of attributevalue pairs: ((a1 v1) (a2 v2)(an vn))
( (name (Don Smith) (age 45) (salary 30000) (hire-date (August 25 1980)) )
61

Assoc
The function that does the forward association. For example (assoc hire-date DS ) Return (August 25 1980)

62

Cons Constructs Lists


If the constructors undo what the selectors do and vice versa, we will have more regular data types. cons adds a new element to the beginning of a list. cons is the inverse of car and cdr

63

Example: (cons to (be or not to be)) return the list (to be or not to be) (car (to be or not to be)) = (cdr (to be or not to be)) = be)) (cons to (be or not to be)) = be)

to (be or not to (to be or not to


64

Quiz: (cons (a b) (c d))

65

Notice that the second argument of cons must be a list. Cons is a pure function.

66

Lists Are Usually Constructed Recursively

67

Append
(append M L) will return the concatenation of the lists L and M. (append ( ) L) = L (append L ( )) = L (append (b c) (d e f)) = (b c d e f)

68

Atoms Have Properties

LISP was originally developed for artificial intelligence application. AI applications often must deal with
the properties of objects and the relationship among objects.

69

In LISP,
objects are represented by atoms, each atom has an associated p-list
represents the properties of the atom and the relationship in which it participates.

70

(set Europe (England France Spain Germany )) >> (England France Spain Germany ) (car Europe) >> England (eq England (car Europe)) >> t (eq France (car Europe)) >> nil
71

How are other properties attached to an atom?


Example: (putprop France Paris capital)

Return Paris We can find out the value of a property with the get function: (get France capital) Return Paris Figure 9.7
72

Figure 9.7

73

Each object comes complete with a property, its print name, which is a character string tagged by pname.

74

Atoms are pointers to their property lists


In implementation atoms are equivalent to memory locations

75

Figure 9.13

76

Binding atoms to lists: (Set Europe (England France ) (get Europe apval) (England France Spain )

77

Binding of atoms to functions is represented by the expr property (Get getprop expr) {function expr) Defun equivalent to putprop

78

Lists Have a Simple Representation


LISP lists are usually implemented as linked structure. For instance, the list (to be or not to be) is represented as
a sequence of six cells in memory, each containing a pointer to the next. Each cell also contains a pointer to the element of the list it represents.
79

Figure 9.8

80

List containing other lists are represented in the same way. For example, the list ( (to 2) (be 2) (or 1) (not 1) ) would be represented in storage as shown in below.

81

Figure 9.9

82

The List Primitive Are Simple and Efficient


Car A := L . left; Cdr D := L . right

83

Figure 9.10

84

Cons new(L); L . left : = A; L . right := D;

85

Shared sub-lists (Quiz)


(set L (or not to be)) >> (or not to be) (set M (to be)) >> (to be) (cadr M) >> be (set N (cons(cadr M) L)) >> (car M) > (set O(cons(car M) N)) > (cons (car M) (cons (cadr M)L)) >
86

Sublists can be shared


A lot of the substructures can be shared. Memory efficiency Danger of Aliasing (and sharing of data structures) only when
There is the ability to change the content of memory

Because car,cdr,cons are pure functions, they have no side effect on memory, so they are danger free
87

Lists can be modified


Pseudo-function
rplaca : replace address part rplacd : replace decrement part (rplaca L A)
L ^ .left := A;

(rplacd L D)
L^ .right := D;

88

Figure 9.12
(set text (to be or not to be)) >> (to be or not to be) ((rplacd (cdr text) (is all))

89

List Structures Can Be Modified


rplaca (replace address part) rplacd (replace decrement part) (set 'text '(to be or not to be)) (to be or not to be) ( set 'x (cdr text)) (be or not to be) (rplacd x '(is all)) (be is all) text (to be is all) Danger of unwanted memory change
90

Potrebbero piacerti anche