Title: LISP
1LISP
- John McCarthy and Marvin Minsky formed MITs AI
Project in 1958.
McCarthy developed LISP in 1958 1959.
Suggested reading John McCarthys home page
http//www-formal.stanford.edu/jmc/
2Functional Programming
- Imperative languages are based on Von Newman
Architecture.Functional programming paradigm is
based on mathematical functions.
- Mathematical function is mapping of members of
one set, called the domain set, to another set
called the range set.
F(x) 2x 5
3Functional Programming
- Evaluation is controlled by recursion and
conditional expressions rather than by sequencing
and iterative repetition that are common to
imperative languages.
- Imperative languages refer to values stored in
memory locations, so side effects are generated.
- In mathematical functions there are no variables
in the sense of imperative languages, so there
can be no side effect.
4Functional Programming
- Naming a function can be separated from defining
a function. Lambda notation is devised to define
a nameless function.
(?(x) xxx) (2)
5Functional Forms
- A high order function, is one that either takes
functions as parameters or yields a function as
its results, or both.
Function composition h ? f ? g
If f(x) ? x 2 g(x) ? x 3 Then, h(x) ?
f(g(x)), or h(x) ? (3 x) 2
6Functional Forms
- Construction
- Is a functional form that takes a list of
functions as parameters and collects the results
in a list.
Let f(x) ? x x g(x) ? x 3 h(x) ? x /
2 then, f, g, h(4) yields (16, 12, 2)
7Functional Forms
- Apply-to-all
- Is a functional form that takes a single
functions as a parameter and and applies it to a
list of arguments.
Let h(x) ? x x then, ?(h, (2, 3, 4)) yields
(4, 9, 16)
8Fundamentals of Functional Programming
- In imperative programming an expression is
evaluated and the result is stored in memory
location which is represented as a variable in
the program.
A purely functional programming language does not
use variables and assignment statements. Without
variables iterative constructs are not possible.
Repetition must be done by recursion.
The execution of a function always produces the
same result when given the same parameters. This
is called referential transparency.
9Fundamentals of Functional Programming
- Although functional languages are often
implemented with interpreters, they can also be
complied.
Functions in imperative languages have
restrictions on the types of values that can be
returned. In many languages only scalar types are
allowed. More importantly, they can not return a
function.
Imperative languages may have functional side
effects.
10LISP
- LISP was the first functional program.
- With the exception of the first version all LISP
dialects include imperative language features
such as, imperative style variables, assignment
statements, and iteration.
11Symbolic Expressions, the Syntactic Basis of LISP
- The syntactic elements of the LISP programming
language are symbolic expressions. - Both programs and data are represented as
s-expressions. An s-expression may be either an
atom or a list. - Symbolic atoms are composed of letters numbers
and certain non-alphanumeric characters ( -
_ gt lt ) - A list is a sequence of either atoms or other
lists separated by blanks and enclosed in
parentheses.
12Examples
- (A B C D)
- (A (B C) D (E (F G)))
13Concepts behind LISP
- McCarthy thought that the processing of symbolic
links is more natural than Turing machines. - One of the common requirements of the study of
computation is that one must be able to prove
certain computability characteristics of the
whole class of whatever model of computation is
being used. - In the case of Turing machine model one can
construct a universal Turing machine that can
mimic the operations of any Turing Machine.
14Concepts behind LISP
- From this emerged a universal LISP function that
could evaluate any other function in LISP. - The first requirement for the universal LISP
function was a notation that allowed functions to
be expressed in the same way data was expressed. - Function calls were specified in a prefix list
form called Cambridge Polish.
15Concepts behind LISP
- (function_name arg_1 arg_n)
Example ( 5 7 ) evaluates to 12.
16Examples
- (- ( 3 4) 7)
-
- (( 2 3) 5)
-
- (list 1 2 3 4)
- (nth 0(list a b c d)
0
t
(1 2 3 4)
a
17- In evaluating a function LISP first evaluates its
arguments and then applies the function indicated
by the first element of the expression to the
results of these evaluations. For example in
evaluating the expression -
- ( ( 2 3) ( 3 5))
- LISP first evaluates the arguments ( 2 3) and (
3 5). These results are then passed to the top
level addition which is evaluated, returning 24.
18Definition
- S-Expression
-
- An s-expression is defined recursively
- 1. An atom is an s-expression.
- 2. If s1, s2,...,sn are s-expressions,
- then so is the list (s1, s2,...,sn).
19- A list is a non-atomic expression.
- In evaluating an s-expression
- If the s-expression is a number, return the value
of the number. - If the s-expression is an atomic symbol, return
the value bound to that symbol if it is not
bound then it is an error. - If the s-expression is a list, evaluate the
second through the last arguments and apply the
function indicated by the first argument to the
result.
20Control of LISP Evaluation quote and eval
- The purpose of the quote is to prevent evaluation
of s-expression that should be treated as data
rather than an evaluable form.
- (quote(a b c ))
- (quote(1 3))
- (list(1 2) ( 3 4)
- (list ( 1 2) ( 3 4)
- (gt( 5 6) ( 4 5))
21Control of LISP Evaluation quote and eval
- eval is a complement to quote.
(quote( 2 3)) ( 2 3)
(eval(quote( 2 3))) 5
22Programming in LISP Creating New Functions
- LISP supports a large number of built in
functions -
- Arithmetic functions supporting both integers and
real numbers. - Program control functions
- List manipulation and other data structuring
functions. - Input/Output functions
- Forms for the control of function evaluation
- Functions for the control of the environment and
operating system.
23(defun square(x) ( x x))
gt(square 5) causes 5 to be bound to x 25
24(defun ltfunction namegt (ltformal parametersgt)
ltfunction body
(defun hypotenuse(x y) (sqrt( (square(x))
(square(y))))
25Program Control in LISP Conditionals and
Predicates
- cond takes as arguments a number of condition -
action pairs.
cond (ltcondition1gt ltaction1gt) (ltcondition2gt
ltaction2gt) ................ (ltconditionngt
ltactionngt)
26 (defun absolute-value(x) (cond ((lt x 0)
(-x)) ((gt x 0) (x))))
(defun absolute-value(x) (cond ((lt
x 0) (-x)) (t x)))
27(defun absolute-value(x) (if (lt x 0 ) (-x) x
))
28Predicates
- A predicate is a LISP function that returns nil
to indicate false and anything other than nil
to indicate true. - gt ( 9 ( 4 5))
- t
-
- gt(oddp 4)
- nil
- Examples to arithmetic predicates are lt, gt, ,
oddp, evenp, zerop, plusp, minusp.
29- gt(member 3 (1 2 3 4 5))
- (3 4 5)
All Boolean functions are short circuit in Common
LISP. They return a value as soon as the result
is determined. gt(and(t t nil t)) nil gt(or( t
nil t t) t
30Functions, lists, and Symbolic Computing
- Using nth it is possible to define access
functions for the various fields of a data
record. - Example
- Suppose a record consists of the fields name,
salary, employee number. - gt(defun name-field(record)
- (nth 0 record))
- gt(name-field ((Ada Lovelance) 45000.00 38519))
- (Ada Lovelance)
- gt(defun first-name(name)
- (nth 0(name))
- gt(first-name(name-field ((Ada Lovelance)
45000.00 38519))) - Ada
31list is a built in LISP function. gt(list 1 2 3
4) (1 2 3 4)
gt(defun build-record(name salary
emp-number) (list name salary emp-number))
gt(build-record ((Ada Lovelance) 45000.00
38519)) (Ada Lovelance) 45000.00 38519)
32Using build record and the access functions we
may construct functions that return a modified
copy of a record .
(defun replace-salary-field(record
new-salary)) (build-record (name-field
record) new salary (number-field record)))
gt(replace-salary-field (((Ada Lovelance)
45000.00 38519) 50000.00)) ((Ada
Lovelance) 50000.00 38519)
33Lists as Recursive Structures
- The basic functions for accessing the components
of a list are car and cdr. -
- car (first) - Takes a list as its argument and
returns the first element of the list. - cdr (rest) - Takes a list as its argument and
returns the list with the first argument
removed.
34gt(car (a b c )) a
gt(cdr (a b c)) (b c)
gt(car(cdr (a b c d))) b
35- A recursive approach to manipulate list
structures to perform an operation on each of the
elements of a list - If the list is empty quit
- Perform the operation on the first element of the
list and recur on the remainder of the list.
Common LISP predicates for list processing are
member Determines whether an s-expression
is a member of a list. length Determines
the length of a list.
36Example Define my-member which takes an atom
and a list as arguments and returns nil if the
atom is not present in the list, otherwise
returns the portion of the list containing the
atom as the first element.
(defun my-member(element list) (cond((null list)
nil) ((equal element(car list)) list) (t
(my-member element (cdr list))))
37gt(my-member 4 (1 2 3 4 5 6)) (4 5 6)
(defun my-length(list) (cond((null list) 0) (t
( (my-length (cdr list) 1)))))
38cons is a basic list constructor (cons A (L
I S)) (A L I S) (cons A B) (A.B) (cons (A)
(L I S)) ((A) L I S)
39(defun filter-negatives (number-list) (cond((null
number-list) nil) ((plusp(car number-list))
(cons (car number-list) (filter-negatives (cdr
number-list)))) (t (filter-negatives(cdr
number-list)))))
gtfilter-negatives (1 -1 2 3 -4 -5 6) (1 2 3 6)
40car and cdr tear lists apart and drive the
recursion cons selectively constructs the
result as the recursion unwinds.
Recursion is used to scan the list element by
element, as the recursion unwinds the cons
function reassembles the solution.
41If cons is called with two lists as arguments it
makes the first of these a new first element of
the second list, whereas append returns a list
whose elements are the elements of the two
arguments gt(cons (1 2) (4 5 6)) ((1 2) 4 5 6)
gt(append (1 2) (4 5 6)) (1 2 4 5 6)
42Lists are powerful representations for tree
structures especially for search and parse trees.
In addition nested lists provide a way of
hierarchically structuring complex data. (1 2 3
4) ((1 2) 3 4)
43car-cdr recursion adds one more dimension to
simple cdr recursion. (defun count-atoms
(list) (cond ((null list) 0) ((atom list)
1) (t ((count-atoms(car list))
(count-atoms(cdr-list))))))
gt(count-atoms ((1 2 ) 3 (((4 5 (6))))) 6
44Functional Programming (set inc 0) (defun
f(x) (set inc ( inc 1)) ( x inc))
gt(f 4) 5 gt(f 4) 6
45In this example x is a bound variable where inc
is a free variable.
All the variables that appear as the formal
parameter of a function are bound variables, and
all the other variables that appear in the body
of the function are free variables.
When a function is called any bindings that a
bound variable may have in the global environment
are saved and the variable is rebound to the
calling parameter.
After the function has completed execution, the
original bindings are restored. Thus setting the
value of a bound variable inside a function body
has no effect on the global bindings of that
variable
46As it is seen from the example free variables in
a function definition are the primary source of
side effects in functions.
(defun fo(x) (setq x ( x 1)) (x))
47The Assignment of Value
SETQ The variable is assigned the value of the
form.
SET symbol is assigned the value given
SETF refers to memory location
(SETQ X 23) x assigned 23 (SET A 999)
arguments are evaluated
48The Assignment of Value
setf regards the first argument as naming a
memory location. gt(setf x (a b c)) (a b c)
gtx (a b c)
gt(setf(cdr x) (2 3)) (2 3)
gt(setf(car x) 1) 1
gtx (1 2 3)
gtx (1 b c)
49Data types in Common LISP Built in types are
integers, floating numbers, strings and
characters. LISP also includes structured types
as arrays, hash tables, sets, and structures .
Unlike other strongly typed languages as Pascal,
in Lisp it is the data objects that are typed
rather than variables. Any LISP symbol may bind
to any object the object itself is typed.
Consequently LISP implements run time type
checking.
50High-Order Functions and Procedural
Abstraction Functions that take other functions
as parameters or return them as results are
called higher-order functions and constitute an
important tool for procedural abstraction.
(defun filter-evens(number-list) (cond(null
number-list) nil) ((oddp(car number-list)) (co
ns(car(number-list) (filter-evens(cdr
number-list))) (t filter-evens(cdr
number-list))))
51funcall takes as arguments a function and a
series of arguments and applies that function to
those arguments
gt(funcall ?plus 2 3) 5
(defun filter (list-of-elements test
) (cond(null list-of-elements) nil) ((funcall
test(car number-list)) (cons(car(number-list)
(filter (cdr list-of-elements) test)) (t
(filter (cdr list-of-elements) test))))
52The function, filter applies the test to the
first element of the list. If the test returns
non-nil it conses the element onto the result of
filtering the cdr of the list oterwise it just
returns the filtered cdr.
gt(filter (1 a b c 5 7) ?numberp) (1 5 7)
gt(filter (1 3 -9 5 -2 -7 6) ?plusp) (1 3 5 6)
Another important class of higher-order functions
consists of mapping functions. gt(mapcar (1 2
3) (2 4 6) (3 6 9)
53Functional Arguments and Lambda
Expressions Lambda expressions allows the
programmer to separate a function definition from
the function name. Without lambda expressions the
programmer must define every functiom in the
global environment using a defun even though the
function may be used only once.
(LAMBDA (X Y) ( X Y)) 30 40
1200
NIL
(LAMBDA (X Y) ( X Y) ()) 30 40
54Lambda Expressions
((LAMBDA (OPTIONAL X Y) (LIST X Y)) 30 40
(NIL NIL
((LAMBDA OPTIONAL X Y) (LIST X Y)) 10 20)
(10 20)
((LAMBDA OPTIONAL (X 0) (Y 0)) (LIST X Y)) 10
20)
(10 20)
55Functional Arguments and Lambda
Expressions Lambda expressions allows the
programmer to separate a function definition from
the function name. Without lambda expressions the
programmer must define every functiom in the
global environment using a defun even though the
function may be used only once.
gt(funcall ?(lambda( x y) ( (x x) y)) ( 2 3)) 7
gt(mapcar ?(lambda(x) ( x x)) (1 2 3 4 5)) (1 2
9 16 25)
56Pattern Matching in Lisp match takes two
arguments and returns t if the expressions match.
Matching requires that both expressions have the
same structure as well as having identical atoms
in corresponding positions.
gt(match (likes bill wine) (likes bill
wine)) t gt(match (likes bill ?) (likes bill
wine)) t gt(match (likes bill ?) (likes ?
wine)) t
57Homework
Define LISP function that reverses a given list