CSCI 2210: Programming in Lisp - PowerPoint PPT Presentation

About This Presentation
Title:

CSCI 2210: Programming in Lisp

Description:

DOTIMES is Lisp's way of doing iteration. C/C . for (i=0; i n; i ) { body Lisp ... (member 'mother '((father son) (mother daughter))) NIL ... – PowerPoint PPT presentation

Number of Views:47
Avg rating:3.0/5.0
Slides: 42
Provided by: AlokM8
Learn more at: http://www.cs.rpi.edu
Category:

less

Transcript and Presenter's Notes

Title: CSCI 2210: Programming in Lisp


1
CSCI 2210 Programming in Lisp
  • Procedures

2
Example Our-third
  • Function to get the third element of a list
  • gt (third '(a b c d e))
  • c
  • How can we do this without using THIRD?
  • Want to create our own function, OUR-THIRD that
    mimics THIRD
  • gt (our-third '(a b c d e))
  • c
  • Definition of OUR-THIRD
  • gt (defun our-third (x)
  • (first (rest (rest x))))
  • OUR-THIRD
  • Many Lisp built-in functions can be written using
    other Lisp built-in functions
  • See Appendix B, Lisp in Lisp.

3
Example Both-ends
  • Define a procedure that gives both ends of a list
  • gt (setf itinerary (Albany NYC Chicago Seattle
    Anchorage))
  • gt (both-ends itinerary)
  • (ALBANY ANCHORAGE)
  • Three steps
  • Get first element
  • gt (first itinerary)
  • ALBANY
  • Get last element
  • gt (first (last itinerary))
  • ANCHORAGE
  • Combine the two
  • gt (list (first itinerary) (first (last
    itinerary)))
  • Define procedure
  • gt (defun both-ends (l) (list (first l) (first
    (last l))))

4
Example Distance
  • Write a function to find the distance between 2
    points.
  • gt (defun sqr (x) ( x x))
  • SQR
  • gt (defun distance (x1 y1 x2 y2)
  • (sqrt ( (sqr (- x2 x1)) (sqr (- y2 y1)))))
  • DISTANCE
  • gt (setf originx 0 originy 0)
  • 0
  • gt (distance originx originy 2 2)
  • 1.414
  • Must have correct number of arguments
  • The value of each argument is copied to the
    corresponding parameter
  • originx copied to x1
  • originy copied to y1
  • 2 copied to x2
  • 2 copied to y2

5
Scope
  • Consider
  • gt (setf a ORIG-A b ORIG-B c ORIG-C)
  • ORIG-C
  • gt (list a b c)
  • (ORIG-A ORIG-B ORIG-C)
  • gt (defun myfun (a) (setf a myfun-a)
  • (setf b myfun-b) (list a b))
  • gt (myfun c)
  • (MYFUN-A MYFUN-B)
  • gt (list a b c)
  • (ORIG-A MYFUN-B ORIG-C)
  • Value of C is copied to A
  • Parameter passing Pass by Value (Like C/C
    default)
  • Global variables are still accessible!
  • Like C/C Global variables
  • Lexical variable variable declared as a
    parameter
  • Special variable variable not declared as a
    parameter

A,B,C
A
6
Let
  • Let Lisps way of defining local variables
  • (let ( (ltvar1gt ltvalue1gt)
  • (ltvar2gt ltvalue2gt) )
  • ltexpr1gt
  • ltexpr2gt
  • )
  • Example
  • (defun distance (x1 y1 x2 y2)
  • (let ( (dx (- x2 x1))
  • (dy (- y2 y1)) )
  • (sqrt ( (sqr dx) (sqr dy))) ))
  • Let evaluates in parallel (not sequentially)
  • Uses original values of variables in all (ltvargt
    ltvaluegt) pairs
  • (let ( (dx (- x2 x1)) (dy (- y2 y1))
  • (dx_sqr (sqr dx)) (dy_sqr (sqr dy)) )
    Wont work!
  • (sqrt ( dx_sqr dy_sqr)) )

7
Let vs. Let
  • Let - Parallel evaluation
  • gt (setf x outside)
  • OUTSIDE
  • gt (let ((x inside) (y x)) (list x y))
  • (INSIDE OUTSIDE)
  • Let - Sequential evaluation
  • gt (setf x outside)
  • OUTSIDE
  • gt (let ((x inside) (y x)) (list x y))
  • (INSIDE INSIDE)
  • Let Implementation of distance
  • (let ( (dx (- x2 x1)) (dy (- y2 y1))
  • (dx_sqr (sqr dx)) (dy_sqr (sqr dy)) )
    OK!
  • (sqrt ( dx_sqr dy_sqr)) )

8
Exercise
  • 1. Rewrite the distance function to use setf
    instead of let. Explain the difference.
  • 2. Write the function solve-quadratic such that,
    given a,b,c, the function finds all values of x
    for which ax2 bx c 0.
  • x1 (-b sqrt (b2 - 4ac)) / 2a
  • x2 (-b - sqrt (b2 - 4ac)) / 2a
  • The function should return both values of x as a
    list of two elements. For example,
  • gt (solve-quadratic 1 -2 1)
  • (1.0 1.0)

9
Example Solve-quadratic
  • Solution to solve-quadratic
  • (defun solve-quadratic (a b c)
  • (let ((sqrt_clause (- ( b b) ( 4 a c)))
  • (neg_b (- b))
  • (two_a ( 2 a)) )
  • (list (/ ( neg_b (sqrt sqrt_clause))
    two_a)
  • (/ (- neg_b (sqrt sqrt_clause))
    two_a))))
  • Notes - No error checking is done
  • (- ( b b) ( 4 a c)) might result in a negative
    number
  • What happens when you try to take sqrt of a
    negative number?
  • What happens when the value of A is zero?
  • Need
  • Predicates - to determine when error conditions
    occur (e.g. )
  • Conditionals - to do something else when error
    occurs

10
EQUAL does not EQL
  • Several predicates check equality
  • Slightly different semantics
  • Can be confusing
  • Equality predicates
  • Equal - Are two argument values the same
    expression?
  • Eql - Are two argument values the same symbol or
    number?
  • Eq - Are two argument values the same symbol?
  • - Are two argument values the same number?
  • General Rule of Thumb
  • Use when you want to compare numbers
  • Use EQUAL otherwise

11
Relationships Bet Equality Preds
EQUAL
F

EQL
EQ
A
D
E
B
C
  • EQ vs.
  • returns T if two numbers are the same,
    regardless of their type
  • EQ returns T if two arguments are the same symbol
  • Same chunk of memory
  • Identical primitives sometimes are EQ
  • Examples
  • gt (eq 4 4) EQT T (C)
  • gt (eq (/ 1 4) 0.25) EQNIL T (A)
  • gt (eq A A) EQT Error (D)
  • gt (eq 4.0 4.0) EQNIL T (A)

12
EQL vs.
  • EQL
  • Arguments are EQL if they are either EQ or they
    are equivalent numbers of the same type
  • Examples
  • gt (eq 4.0 4.0) EQNIL EQLT T (B)
  • gt (eq 4 4.0) EQNIL EQLNIL T (A)
  • EQUAL
  • Arguments are EQUAL if they are either EQL or
    they are Lists whose elements are EQUAL
  • Performs an element by element comparison of lists

13
EQUAL vs. EQL vs.
C
  • EQUAL vs. EQL
  • gt (setf X (A (B (C))))
  • gt (setf Y X)
  • gt (setf Z (A (B (C))))
  • X and Y are EQUAL and EQL
  • X and Z are EQUAL but not EQL
  • They dont point to the SAME memory
  • But, if you do an element by element comparison
    of the lists, they are equal
  • EQUAL vs.
  • gt (EQUAL 4 4.0)
  • NIL
  • gt ( 4 4.0)
  • T

B
A
X
C
Y
B
A
Z
14
Data Type Predicates
  • Data Type Predicates
  • Compare objects to determine their type
  • atom - Is argument an atom?
  • numberp - Is argument a number?
  • symbolp - Is argument a symbol (a non-numeric
    atom)?
  • listp - Is argument a list?
  • Examples
  • gt (list pi ABC)
  • (3.14159 ABC)
  • gt (list (atom pi) (atom ABC))
  • (T T)
  • gt (list (numberp pi) (numberp ABC))
  • (T NIL)
  • gt (list (symbolp pi) (symbolp ABC))
  • (NIL T)
  • gt (list (listp pi) (listp ABC) (listp (A B))
  • (NIL NIL T)

15
Number Predicates
  • Number predicates
  • numberp - Is it a number?
  • zerop - Is it zero? Argument must be a number
  • plusp - Is it positive? Argument must be a number
  • minusp - Is it negative? Argument must be a
    number
  • evenp - Is it even?
  • oddp - Is it odd?
  • gt - Is the list of arguments in descending order?
    (e.g. (gt 5 4))
  • lt - Is the list of arguments in ascending order?

16
If, When, Unless
  • If
  • (if lttestgt ltthen-formgt ltelse-formgt)
  • if lttestgt is true
  • ltthen-formgt is evaluated,
  • otherwise ltelse-formgt is evaluated.
  • When
  • (when lttestgt ltthen-form1gt ltthen-form2gt )
  • If lttestgt is true, then other arguments are
    evaluated.
  • Unless
  • (unless lttestgt ltelse-form1gt ltelse-form2gt )
  • If lttestgt is false, then other arguments are
    evaluated.

17
Cond
  • Cond format
  • (COND (lttest1gt ltthen-1-1gt ltthen-1-2gt )
  • (lttest2gt ltthen-2-1gt ltthen-2-2gt )
  • (lttest3gt ltthen-3-1gt ltthen-3-2gt )
  • (lttestigt ltthen-i-1gt ltthen-i-2gt )
  • (lttestmgt ltthen-m-1gt ltthen-m-2gt )
  • Semantics
  • 1. Evaluate lttest1gt, lttest2gt, until you get to
    a lttestigt such that lttestigt evaluates to a nonNIL
    value
  • 2. Evaluate ltthen-i-1gt ltthen-i-2gt
  • 3. Return value of the last ltthen-i-ngt clause
    executed
  • If all tests evaluate to NIL, result of COND is
    NIL

18
Example
  • Define a function to find area
  • (defun area (type r)
  • (cond ((equal type circle) ( PI R R))
  • ((equal type sphere) ( 4 PI R R))
  • ((equal type square) ( R R)
  • ((equal type cube) ( 6 R R))
  • ( t (print Error) ))
  • Define a function, compute-grade, to determine
    the letter grade.
  • (compute-grade 81.5)
  • B

19
Case
  • Similar to COND, but is more elegant when
    checking for equality
  • (defun area (type r)
  • (case type
  • (circle ( PI R R))
  • (sphere ( 4 PI R R))
  • (square ( R R)
  • (cube ( 6 R R))
  • (otherwise (print Error) ))
  • Format
  • (case ltkey-formgt
  • (ltkey 1gt ltthen-1-1gt ltthen-1-2gt )
  • (ltkey 2gt ltthen-2-1gt ltthen-2-2gt )
  • (ltkey mgt ltthen-m-1gt ltthen-m-2gt )
  • (otherwise ltthen-o-1gt ltthen-o-2gt )

20
Case (2)
  • Notes
  • ltkey-formgt is evaluated
  • But, ltkey 1gt ltkey 2gt, are NOT evaluated
  • OTHERWISE or T always evaluate to nonNIL
  • If no matches are found, the CASE statement
    returns NIL
  • A ltkeygt form may contain a list. In this case,
    the ltkey-formgt can match ANY element of the list
  • (defun circularp (type)
  • (case type
  • ((circle sphere) T)
  • (otherwise NIL)))
  • (circularp cube)
  • Technical note the MEMBER function is used to do
    the comparison.

21
Both-ends Revisited
  • Both-ends with error handling
  • (defun both-ends (l)
  • (if (listp l)
  • (case (length l)
  • (0 NIL)
  • (1 (list (first l) (first l)))
  • (t (list (first l) (first (last l)))))
  • NIL))

22
Solve-quadratic revisited
  • Solve-quadratic with error checking
  • Checks for errors returns NIL instead
  • (defun solve-quadratic (a b c)
  • (if (not (and (numberp a) (numberp b) (numberp
    c)))
  • NIL at least one argument is not a number
  • (let ((sqrt_clause (- ( b b) ( 4 a c)))
  • (neg_b (- b))
  • (two_a ( 2 a)) )
  • (cond
  • ((minusp sqrt_clause) NIL)
  • (( 0 a) NIL) Could have used zerop
  • (t
  • (list (/ ( neg_b (sqrt sqrt_clause))
    two_a)
  • (/ (- neg_b (sqrt sqrt_clause))
    two_a)))))))
  • What happens if we don't include the clause
  • (minusp sqrt_clause)
  • By default, Lisp arithmetic operations handle
    complex numbers

23
Factorial
  • Definition of Factorial
  • C Implementation
  • int factorial (int x)
  • int i,f
  • f 1
  • for (i1 iltx i) f f i
  • return f
  • Lisp Implementation
  • (defun factorial (n)
  • (let ((f 1))
  • (dotimes (i n f)
  • (setf f ( f ( i 1))))))
  • Note To more easily compare, C loop could have
    been written as
  • for (i0 iltx i) f f (i 1)
  • Tip Compute factorial(100) using C/C and Lisp

24
DoTimes
  • DOTIMES is Lisps way of doing iteration
  • C/C
  • for (i0 iltn i)
  • ltbodygt
  • Lisp
  • (dotimes (i n) ltbodygt)
  • First parameter is a list with three elements
  • counter variable (e.g. i)
  • number of times to iterate (e.g. n)
  • Counter variable (i) ranges from 0 to n-1
  • Optional return value can be specified (default
    is NIL)
  • (dotimes (i n return_value) ltbodygt)

25
Recursively Calculating Factorial
  • Mathematical Definition of Factorial
  • C/C Implementation
  • long Factorial (long X)
  • if (X lt 1)
  • return 1
  • else
  • return X Factorial(X-1)
  • Lisp Implementation
  • (defun recursive-factorial (x)
  • (if (lt x 1)
  • 1
  • ( x (recursive-factorial (- x 1)))))

26
Recursive calls
  • Show recursion when calling (recursive-factorial
    4)
  • Begin (recursive-factorial 4)
  • Since 4gt1, evaluate 4 (recursive-factorial
    3)
  • Begin (recursive-factorial 3)
  • Since 3gt1, evaluate 3
    (recursive-factorial 2)
  • Begin (recursive-factorial 2)
  • Since 2gt1, evaluate
    2(recursive-factorial 1)
  • Begin (recursive-factorial 1)
  • Since 1lt1, return 1
  • End (recursive-factorial 1),
    returns 1
  • 2 (recursive-factorial 1) 2 1
    2
  • End (recursive-factorial 2), returns 2
  • 3 (recursive-factorial 2) 3 2 6
  • End (recursive-factorial 3), returns 6
  • 4 (recursive-factorial 3) 4 6 24
  • End (recursive-factorial 4), returns 24

27
MEMBER
  • MEMBER
  • Checks if first argument is an element of second
    argument
  • Returns what is left of the list when symbol is
    found
  • gt (setf sentence (tell me more about your mother
    please))
  • (TELL ME MORE ABOUT YOUR MOTHER PLEASE)
  • gt (member mother sentence)
  • (MOTHER PLEASE)
  • Only checks the top level for a match (using EQL)
  • gt (member mother ((father son) (mother
    daughter)))
  • NIL

28
Example Our-member
  • Our-Member
  • (defun our-member (obj aList)
  • (if (null aList)
  • nil
  • (if (eql (first aList) obj)
  • aList
  • (our-member obj (rest aList)))))
  • This "design pattern" is used frequently in Lisp
    for recursive methods that operate on Lists
  • (defun ltrecursive-function (aList)
  • (if ltbase conditiongt
  • ltterminate with return valuegt
  • ltprocess first elementgt
  • ltrecursively process everything
  • except the first elementgt))

29
MEMBER Keyword Modifiers
  • MEMBER tests for membership using EQL
  • gt (setf pairs ((maple shade) (apple fruit)))
  • gt (first pairs)
  • (MAPLE SHADE)
  • gt (member (first pairs) pairs)
  • ((MAPLE SHADE) (APPLE FRUIT))
  • gt (member (maple shade) pairs)
  • NIL
  • Use keyword modifier to override
  • gt (member (maple shade) pairs test equal)
  • ((MAPLE SHADE) (APPLE FRUIT))
  • test is a keyword it expects an argument of
    type procedure
  • equal is a keyword argument
  • is a macro
  • equal expands to (function equal)
  • Returns the procedure object named equal

30
Keywords Procedure Macro
  • Why use keywords?
  • Why not just an optional parameter?
  • gt (member (maple shade) pairs equal)
  • Keywords allow more than one type of behavior
    modification
  • test-not is another keyword for MEMBER
  • Why use procedure objects?
  • Why not just allow procedure name to be passed?
  • gt (member (maple shade) pairs test equal)
  • Procedure objects can be bound to variable names
  • gt (setf predicate equal)
  • gt (member (maple shade) pairs test predicate)
  • Can pass them as parameters to functions, etc.

31
Recursive Definition of Length
  • Length
  • (defun mylength (l)
  • (if (endp l)
  • 0
  • ( 1 (mylength (rest l)))))
  • Alternate definition
  • (defun mylength2 (l)
  • (mylength2-aux l 0))
  • (defun mylength2-aux (l count)
  • (if (endp l)
  • count
  • (mylength2-aux l ( count 1))))
  • Note
  • All recursive calls simply return the final value
    evaluated.
  • No additional computations

32
Tail Recursion
  • Tail Recursion
  • The final expression of a function is a recursive
    call
  • No additional computations are done to that
    expression
  • That is, return value is JUST the result of the
    recursive call
  • Lisp handles tail recursion efficiently
  • Mylength is not tail recursive
  • Mylength2 is tail recursive
  • Example
  • Write a function to produce N atoms with value
    A.
  • gt (produce-list-of-a 5) Example call
  • (A A A A A)

33
Produce-list-of-a
  • Using dotimes
  • (defun produce-list-of-a (n)
  • (let ((la NIL))
  • (dotimes (i n la) (push 'A la))))
  • Recursion, not tail recursive
  • (defun produce-list-of-a (n)
  • (if ( n 0)
  • nil
  • (cons 'A (produce-list-of-a (- n 1)))))
  • Recursion, with tail recursion
  • (defun produce-list-of-a (n)
  • (produce-list-of-a-aux n NIL))
  • (defun produce-list-of-a-aux (n list-so-far)
  • (if ( n 0)
  • list-so-far
  • (produce-list-of-a-aux
  • (- n 1)
  • (cons 'A list-so-far))))

34
Tower of Hanoi
  • Three pegs, S(start), T(temp), E(end)
  • N disks
  • Goal Move disks from peg S to peg E
  • Restriction Larger disk cant be placed on top
    of smaller disk
  • S T E

35
Tower of Hanoi
  • Solution to Tower of Hanoi
  • (defun hanoi-aux (n start end temp)
  • (if (gt n 1) (hanoi-aux (- n 1) start temp
    end))
  • (print (list start end))
  • (if (gt n 1) (hanoi-aux (- n 1) temp end
    start)))
  • (defun hanoi (n) (hanoi-aux n 'S 'E 'T))
  • Example Runs
  • gt (hanoi 2)
  • (S T)
  • (S E)
  • (T E)
  • NIL

gt (hanoi 3) (S E) (S T) (E T) (S E) (T S) (T
E) (S E) NIL
36
Optional
  • Produce-list-of-a function(s)
  • (defun produce-list-of-a (n)
  • (produce-list-of-a-aux n NIL))
  • (defun produce-list-of-a-aux (n list-so-far)
  • (if ( n 0)
  • list-so-far
  • (produce-list-of-a-aux
  • (- n 1)
  • (cons 'A list-so-far))))
  • Redefined with optional parameters
  • (defun produce-list-of-a (n optional
    list-so-far)
  • (if ( n 0)
  • list-so-far
  • (produce-list-of-a
  • (- n 1)
  • (cons 'A list-so-far))))
  • Note optional values are bound to NIL, by default

37
Optional Parameters (cont)
  • Solution to Hanoi
  • (defun hanoi-aux (n start end temp)
  • (if (gt n 1) (hanoi-aux (- n 1) start temp
    end))
  • (print (list start end))
  • (if (gt n 1) (hanoi-aux (- n 1) temp end
    start)))
  • (defun hanoi (n) (hanoi-aux n 'S 'E 'T))
  • Revised with optional parameters
  • (defun hanoi (n optional (start 'S) (end 'E)
    (temp 'T))
  • (if (gt n 1) (hanoi (- n 1) start temp end))
  • (print (list start end))
  • (if (gt n 1) (hanoi (- n 1) temp end start)))
  • Note notice the syntax for initializing optional
    parameters

38
Rest
  • Rest - Specifies a variable number of arguments
  • Example Assume only accepts 2 arguments.
    Define Plus, a function that adds an arbitrary
    number of arguments)
  • gt (plus 2 3)
  • gt (plus 2 3 4 5 8)
  • Solution
  • (defun plus (arg1 rest other_args)
  • (plus-aux arg1 other_args))
  • (defun plus-aux (arg1 other_args)
  • (if (null other_args)
  • arg1
  • (plus-aux ( arg1 (first other_args))
  • (rest other_args))))

39
Key Parameters
  • KEYword parameter
  • Useful when function has MANY parameters
  • Most are tied to default values
  • Examples
  • gt (rotate-list '(a b c d e)) rotate one
    element right
  • (E A B C D)
  • gt (rotate-list '(a b c d e) direction 'left)
  • (B C D E A)
  • gt (rotate-list '(a b c d e) distance 2)
  • (D E A B C)
  • gt (rotate-list '(a b c d e) direction 'left
    distance 2)
  • (C D E A B)

40
Key
  • Use key to define Key parameters
  • (defun rotate-list (l key (direction 'right)
    (distance 1))
  • (if (eq direction 'left)
  • (rotate-list-left l distance)
  • (rotate-list-right l distance)))
  • (defun rotate-list-right (l n)
  • (if (zerop n)
  • l
  • (rotate-list-right (append (last l)
    (butlast l))
  • (- n 1))))
  • (defun rotate-list-left (l n)
  • (if (zerop n)
  • l
  • (rotate-list-right (append (rest l) (list
    (first l)))
  • (- n 1))))

41
Aux
  • Aux keyword is used as a shorthand for Let
  • Produce-list-of-a using Let
  • (defun produce-list-of-a (n)
  • (let ((la NIL))
  • (dotimes (i n la) (push 'A la))))
  • Using Aux
  • (defun produce-list-of-a (n aux (la NIL))
  • (dotimes (i n la) (push 'A la)))
Write a Comment
User Comments (0)
About PowerShow.com