An Introduction to LISP - PowerPoint PPT Presentation

1 / 32
About This Presentation
Title:

An Introduction to LISP

Description:

LISP is a functional language that was invented by John McCarthy, an ... Formal Definition of S-Expression (from Luger) An s-expression is defined recursively: ... – PowerPoint PPT presentation

Number of Views:186
Avg rating:3.0/5.0
Slides: 33
Provided by: hpcus648
Category:

less

Transcript and Presenter's Notes

Title: An Introduction to LISP


1
An Introduction to LISP
  • LISP is a functional language that was invented
    by John McCarthy, an AI pioneer, in 1959
  • LISP stands for LISt Processing
  • Lists are the primary data structure in LISP
  • The variant of LISP used most today is called
    Common LISP
  • Scheme is directly descended from LISP
  • LISP is a functional programming language
  • Recall that Prolog is a logic programming
    language
  • C is both imperative and object oriented
  • Imperative features have been added to LISP and
    Prolog for practical purposes
  • It would take a whole quarter to thoroughly learn
    LISP
  • Our goal is to learn enough to see how LISP
    facilitates building AI systems

2
Symbolic Expressions
  • Everything you write in LISP is a symbolic
    expression (S-expression)

  • S-expression
  • Atom
    List
  • Number Symbol
  • Five example atoms are 32, , john, r2d2, 5.125
  • Two example lists are (32 john r2d2
    5.125)

  • (happy students love CS480/580)

3
Lists and S-Expressions
  • Lists represent both data and programs
  • Lists can be nested to any depth
  • Example lists can represent predicate calculus
    statements
  • (likes joe chocolate)
  • (not (likes fred broccoli))
  • Example lists can represent arithmetic
    expressions
  • ( 2 3)
  • ( ( 2 3) ( 1 2))
  • A LISP interpreter will try to evaluate any
    S-expression entered
  • An S-expression which can be evaluated is called
    a form
  • Example gt ( 2 3)
  • 5
  • gt ( ( 2 3) ( 1 2))
  • 15

4
Formal Definition of S-Expression (from Luger)
  • An s-expression is defined recursively
  • An atom is an s-expression.
  • If s1, s2, , sn are s-expressions, then so is
    the list (s1 s2 sn).
  • A list is a nonatomic s-expression.
  • A form is an s-expression that is intended to be
    evaluated. If it is a list, the
  • first element is treated as the function name and
    the remaining elements are
  • evaluated to find the function arguments.
  • To evaluate 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 the symbol is
    not bound, 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
    results.

5
Working with Lists
  • There is one special value, nil, which is both an
    atom and a list
  • nil is the empty list, ()
  • nil is also used to represent the boolean value
    false in LISP
  • LISP uses the atom t (or anything other than nil)
    to represent true
  • There are several handy built-in functions for
    working with lists
  • list creates a list
  • gt (list 1 2 3)
  • (1 2 3)
  • length tells how many elements are in a list
  • gt (length (1 2 3))
  • 3
  • null tells whether or not a list is empty
  • gt (null (1 2 3))
  • NIL

6
Notes on Working with Lists
  • Note that when you enter something like (null (1
    2 3)) into an interpreter, you can see that the
    list is not null
  • A program operates by manipulating lists, so you
    would not normally know the results of a test
    before you make it
  • Otherwise, you would be wasting your time
  • Also note that our LISP interpreter (Gnu Common
    LISP) always responds in all capital letters
  • LISP is not case sensitive, ie., xyz is
    equivalent to XYZ
  • You may program using upper case or lower case
    letters, but the interpreter will convert what
    you write to all upper case

7
More Built-in List Operations
  • nth n, where n is an integer, will return the nth
    element of a list
  • Note that the first element has n 0 and that
    elements may be lists
  • gt (nth 2 (1 2 3))
  • 3
  • gt (nth 2 ((1 2) (3 4) (5 6) (7 8)))
  • (5 6)
  • member tests to see if its first argument is an
    element of its second
  • gt (member a (x y z))
  • NIL
  • gt (member y (x y z))
  • (Y Z)
  • Note that member returns the rest of the list
    beginning with the first argument, rather than a
    simple t
  • This is useful if you want to continue processing
    the list
  • Anything other than NIL is still treated as true

8
Controlling Evaluation with Quote and Eval
  • The interpreters default is to try to evaluate
    everything
  • Ex (nth 2 (a b c d)) looks like it might
    evaluate to c, but it wont
  • In evaluating (a b c d), LISP tries to apply the
    operator a to the arguments b, c and d
  • Since a is not a defined operator, this is an
    error
  • To get the desired behavior, use (nth 2 (quote
    (a b c d))) or simply, (nth 2 (a b c d))
  • eval undoes the effect of quote
  • gt (quote ( 3 4))
  • ( 3 4)
  • gt (eval (quote ( 3 4)))
  • 7
  • The real advantage of eval is that it allows the
    programmer to evaluate any constructed
    S-expression that is, you can have your program
    write and execute another program on the fly

9
You Try It - What Will the Interpreter Respond?
  • 1. (- 10 3)
  • 2. (/ ( ( 4 5) 1) 2)
  • 3. (nth 0 (list a b c))
  • 4. (length (a b c))
  • 5. (null ())
  • 6. (member 1 (1 2 3))
  • 7. (null (member z (x y z)))
  • 8. (nth 3 ((a (b c)) d (e f g) (h) j k (l
    (m n (o p)))))
  • 9. (list (- 5 2) ( 1 1))
  • 10. (list (- 5 2) ( 1 1))
  • 11. (eval (list 10 10))
  • 12. ( (eval (list 10 10)) 20)

10
Defining New Functions in LISP
  • LISP has many built-in functions
  • Programmer defined functions are created using
    defun
  • Syntax (defun ltfunction namegt (ltparam namesgt)
    ltfunction bodygt)
  • Example Convert Fahrenheit temperatures to
    Celsius
  • (defun f-to-c (temp)
  • (/ (- temp 32) 1.8)
  • )
  • Once this is defined, it can be used like any
    other function
  • gt (f-to-c 32)
  • 0.0
  • gt (f-to-c 212)
  • 100.0

11
Conditional Expressions in LISP
  • In any computer language, it is useful to be able
    to branch based on different conditions
  • In C, we have if statements and switch
    statements for this
  • In LISP, we have if statements and cond
    statements
  • cond is most general, and therefore, used most
    often
  • if is a nice shortcut, when you have only two
    ways to branch
  • The basic structure of a cond is
  • (cond (ltcondition1gt ltaction1gt)
  • (ltcondition2gt ltaction2gt)
  • (ltconditionngt ltactionngt)
  • )

12
Evaluating a Cond
  • Conditions and actions (like everything else in
    LISP) are S-expressions
  • Conditions are evaluated in order
  • If no condition is true, the whole cond evaluates
    to nil
  • As soon as a true condition is encountered, its
    associated action is evaluated
  • All conditions following the first true one are
    ignored
  • The value obtained for the action becomes the
    value of the cond
  • A condition is true if it does not evaluate to
    the empty list or nil
  • There are several handy predicates built in for
    boolean tests
  • For numbers, we have relational operators lt, gt,
    lt, gt, , and /
  • For numbers, we also have oddp, minusp, zerop
    and plusp
  • To find out if we have a number or something
    else, we can use numberp, listp, atom, null

13
Example
  • (defun minimum (x y)
    return the minimum of two numbers
  • (cond ((lt x y) x)
    if x lt y, return x
  • (( x y) x)
    if x y, return x
  • ((gt x y) y)
    if x gt y, return y
  • )
    comments start with semi-colons!
  • )
    lining up parens may aid clarity, at
    first
  • This illustrates the use of cond, but the minimum
    function can be improved
  • (defun minimum (x y)
  • (cond ((lt x y) x)
  • (t y)
    t means otherwise, or by default
  • )
    use t only in the last line of a cond
  • )

14
The if statement
  • The if statement takes the form
  • (if ltconditiongt lttrue-actiongt
    ltfalse-actiongt)
  • When you only have a two-way test, you may prefer
    if to cond
  • Example
  • (defun minimum (x y)
  • (if (lt x y) x y)
  • )

15
Boolean Operators
  • The Boolean operators and, or and not are
    available
  • Evaluation is short circuit
  • For non-functional side effects, interpreters may
    differ in evaluation
  • Examples
  • gt (not nil)
    nil is false, so not nil is true
  • T
  • gt (not 3) 3
    is not false, so not 3 is false
  • NIL
  • gt (and (oddp 2) (print 2)) 2 is not
    odd, so the second statement is
  • NIL
    not evaluated (short circuit)
  • gt (or (oddp 2) (print 2)) here, a
    side effect (printing) occurs, and
  • 2
    the expression evaluates to what was
  • 2
    printed (other interpreters might evaluate

  • printing to nil)

16
More on Output
  • It is useful to be able to print output, even
    though printing is a side effect, not a function,
    and LISP is a functional language
  • Recall that printing output did not fit neatly
    into Prolog, either
  • Programmers need to understand how it works,
    anyway
  • More examples
  • gt ( (print 2) (print 3))
  • 2
  • 3
  • 5
  • gt (print hello)
  • HELLO
  • HELLO
  • gt (print Hello, world!)
  • Hello, world!
  • Hello, world!

17
You Try It
  • 1. Write a LISP function triple, that returns 3
    times its input value
  • 2. Write a LISP function income-status, that
    takes income and number of dependents as
    arguments, and returns adequate if there is at
    least 10,000 of income per dependent and
    inadequate otherwise
  • (a) Use a cond statement
  • (b) Use an if statement

18
Database Example
  • This example shows how to build and use a simple
    database with fields for name, salary and
    employee number
  • First, define a function to set up records
  • (defun build-record (name salary emp-number)
  • (list name salary emp-number)
  • )
  • Then, input records
  • gt (build-record (Prof. Marling) 1000000
    1)
  • ((Prof. Marling) 1000000 1)
  • Next, define functions to access parts of records
  • (defun name-field (record)
  • (nth 0 record)
  • )

19
Database Example, continued
  • (defun salary-field (record)
  • (nth 1 record)
  • )
  • (defun emp-number-field (record)
  • (nth 2 record)
  • )
  • (defun first-name (name)
  • (nth 0 name)
  • )
  • Access fields of data in records
  • gt (name-field ((Prof. Marling) 1000000 1))
  • (Prof. Marling)
  • gt (first-name (name-field ((Prof. Marling)
    1000000 1)))
  • Prof.

20
Database Example, continued
  • Manipulate data
  • (defun double-salary (record)
  • (build-record
  • (name-field record) ( 2 (salary-field
    record)) (emp-number-field record)
  • )
  • )
    Actually, I added this function to the
    example
  • gt (double-salary ((Prof. Marling) 1000000 1))
  • ((Prof. Marling) 2000000 1) I really
    like this function (-
  • Note that the functional programming style does
    not actually change the original record. Rather,
    it creates a new record with the desired changes.
    This is not like C, but it is like ordinary
    mathematical functions, e.g., the square root.
    The square root of 9 is 3, but the original 9
    maintains its value.

21
Lists as Recursive Structures
  • Manipulating lists is central to LISP
  • Recursion is a natural control structure for
    moving about in lists
  • There are three basic list processing functions,
    car, cdr and cons
  • Some versions of LISP rename these functions, but
    the idea behind list processing remains the same
  • car takes one argument, which must be a list, and
    returns the first element of the list
  • car stands for Contents of the Address Register,
    which was a sensible name for an important
    function in 1959
  • Examples
  • gt (car (I love LISP))
  • I
  • gt (car ( (Absolutely everybody) (loves
    LISP)))
  • (ABSOLUTELY EVERYBODY)

22
cdr
  • cdr takes one argument, which must be a list, and
    returns the rest of the list except for the car
  • It always returns a list, even if theres nothing
    or only one thing left in the list
  • cdr stands for Contents of the Decrement
    Register, another name that was more mnemonic in
    1959
  • Examples
  • gt (cdr (I really love LISP))
  • (REALLY LOVE LISP)
  • gt (cdr (Hello world))
  • (WORLD)
  • gt (cdr ())
  • NIL

23
More on List Processing Functions
  • car and cdr are used together to get to any part
    of a list
  • gt (car (cdr (computer TV camera)))
  • TV
  • gt (car (cdr (car (cdr ((a b)(c d)(e
    f))))))
  • D
  • Note that evaluation proceeds from the inside
    out, as it would for any mathematical function
  • cons takes two arguments, a new list element and
    a list to add it to
  • cons stands for list constructor
  • gt (cons a (b c))
  • (A B C)
  • gt (cons (a b) (c d))
  • ((A B) C D)

24
Using List Processing Functions
  • The three basic functions are used to build
    additional functions
  • For example, if nth were not already built-in, we
    could write it
  • (defun nth (n a-list)
  • (cond ((zerop n) (car a-list))
  • (t (nth (- n 1) (cdr
    a-list)))
  • )
  • )
  • Here, we assume that n is a positive number and
    that a-list actually is a list we could add
    error checking, if desired
  • Note the natural use of recursion!
  • Many LISP functions work by processing the first
    element in a list and then processing the rest of
    the list
  • This is called tail recursion

25
Another Example of Tail Recursion
  • filter-negatives uses tail recursion to process a
    list of numbers and return a list containing only
    the positive numbers
  • Example
  • gt (filter-negatives (-1 0 1 2 -2 3))
    it also filters out zeroes
  • (1 2 3)
  • (defun filter-negatives (number-list)
  • (cond ((null number-list) nil)
    termination condition
  • ((plusp (car number-list)) (cons
    (car number-list)

  • (filter-negatives (cdr
    number-list))))
  • (t (filter-negatives (cdr
    number-list)))
  • )
  • )

26
You Try It
  • Write function double-list which doubles every
    number in a given list
  • Assume that the argument will be a valid list of
    numbers

27
Double Recursion
  • Because lists may be nested, tail recursion cant
    fully process all lists
  • Double recursion is another standard technique
  • Example If we want to know how many elements are
    in a nested list, we can use length. If we want
    to know how many atoms are in a nested list, we
    need a new function, that uses double recursion
  • (defun count-atoms (my-list)
  • (cond ((null my-list) 0)
  • ((atom my-list) 1)
  • (t ( (count-atoms (car my-list))
  • (count-atoms (cdr
    my-list))))))
  • (count-atoms ((1 2) 3 (((4 5 (6))))))
  • 6

28
Finding the Length of a List Using Tail Recursion
29
Counting Atoms in a List With Double Recursion
30
Binding Variables Using set
  • While purely functional languages do not have
    assignment statements, set, setq and setf are
    ways of creating creating global variables and
    assigning values to them
  • set and setq serve the same purpose
  • setq is the more commonly used function
  • Example gt (setq x 0)
  • 0
  • If no global variable named x exists, this will
    create one and set its value to 0
  • If there is already a global variable x, this
    will change its value to 0
  • Note that the first argument to setq must be a
    symbol
  • The second can be any S-expression
  • setq may also be used to assign a value to a
    functions argument within a function body or to
    a local variable
  • In this case, no new global variable is created

31
Example of setf
  • To assign a value to any arbitrary memory
    location, setf can be used instead of setq
  • Its use is usually discouraged, as it detracts
    from functional programming and makes it harder
    to debug programs
  • However, it does provide flexibility
  • gt (setf x (a b c))
  • (A B C)
  • gt x
  • (A B C)
  • gt (setf (car x) 1)
  • 1
  • gt x
  • (1 B C)
  • gt(setf (cdr x) (2 3))
  • (2 3)
  • gt x
  • (1 2 3)

32
Defining Local Variables with let
  • A let block establishes an environment for local
    variables
  • If there are global variables with the same
    names, their values are used outside of the let
    block
  • A let block takes the form
  • (let (ltlocal-variablesgt) ltexpressionsgt)
  • A local variable may be a symbol or a list
    containing a symbol and a value
  • Symbols without values are set to NIL by default
  • Examples
  • gt (let ( (a 1) (b 2) )
    gt (let (a b)
  • ( a b)
    (setq a 1)
  • )
    (setq b 2)
  • 3
    ( a b)

  • )

  • 3
Write a Comment
User Comments (0)
About PowerShow.com