The Case primitive: matches the evaluated key form against the unevaluated keys by using eql - PowerPoint PPT Presentation

About This Presentation
Title:

The Case primitive: matches the evaluated key form against the unevaluated keys by using eql

Description:

The Case primitive: matches the evaluated key form against the unevaluated keys by using eql – PowerPoint PPT presentation

Number of Views:28
Avg rating:3.0/5.0
Slides: 28
Provided by: csC5
Learn more at: https://cs.ccsu.edu
Category:

less

Transcript and Presenter's Notes

Title: The Case primitive: matches the evaluated key form against the unevaluated keys by using eql


1
The Case primitive matches the evaluated key
form against the unevaluated keys by using eql
  • The general format of case is the following
  • (case ltkey formgt
  • (ltkey 1gt ltconsequent 1-1gt ...
    ltconsequent 1-ngt)
  • (ltkey 2gt ltconsequent 2-1gt ...
    ltconsequent 2-ngt)
  • .....
  • (ltkey mgt ltconsequent m-1gt ...
    ltconsequent m-ngt))
  • Example
  • gt (setf object 'sphere r 2)
  • 2
  • gt (case object
  • (circle ( pi r r))
  • (sphere ( 4 pi r r)))
  • 50.2654824574367

2
The key may be an atom or a list in the latter
case the list is searched for the key by means of
the member predicate
  • Example
  • gt (case object
  • ((circle wheel) ( pi r r))
  • ((ball sphere) ( 4 pi r r))
  • (otherwise 0)) if none of
    the clauses is triggered, case
  • 50.2654824574367 returns NIL, the
    otherwise clause (or t)
  • can
    be used to set the returned value.

3
The problem reduction technique
  • The idea divide the problem into sub-problems
    each of which can
  • be handled separately.
  • Example the both-ends procedure
  • (defun both-ends (whole-list)
  • (case (length whole-list)
  • (0 ....) gt
    (0 nil)
  • (1 ....) gt
    (1 (cons (first whole-list) whole-list))
  • (2 ....) gt
    (2 whole-list)
  • (t ....))) gt
    (t (cons (first whole-list)

  • (last whole-list)))))

4
The procedure abstraction technique
  • The idea arrange procedures into abstraction
    layers.
  • Example the both-ends procedure
  • gt (defun both-ends (whole-list)
  • (make-list
  • (get-first-el whole-list)
  • (get-last-el whole-list)))
  • BOTH-ENDS
  • gt (defun make-list (el-1 el-2)
  • (list el-1 el-2))
  • MAKE-LIST
  • gt (defun get-first-el (list-1)
  • (first list-1))
  • GET-FIRST-EL
  • gt (defun get-last-el (list-1)
  • (first (last list-1)))
  • GET-LAST-EL

5
Defvar and defparameter define global variables
  • (defvar global) declares global as a global
    variable.
  • (defvar global expression) assigns a value to
    global
  • (defparameter global expression) declares
    global as a global variable, and assings a
    value to it.
  • Examples
  • gt (defvar var-1)
    gt (defparameter par-1)
  • VAR-1
    ERROR
  • gt (defvar var-1 222)
    gt (defparameter par-1 77)
  • VAR-1
    77
  • gt var-1
    gt par-1
  • 222
    77
  • gt (defvar var-1 333)
    gt (defparameter par-1 88)
  • VAR-1
    PAR-1
  • gt var-1
    gt par-1
  • 222
    88

6
Singly recursive procedures each recursive call
originates only one new call
  • Example compute the n power of m.
  • gt (defun exponent (m n)
  • (if (zerop n)
  • 1
  • ( m (exponent m (- n 1)))))
  • EXPONENT
  • gt (exponent 2 3)
  • 8
  • The behavior of recursive procedures can be
    observed by means of the
  • trace primitive. Untrace will undo the effect of
    trace. These have the
  • following syntax
  • (trace ltprocedure namegt)
  • (untrace ltprocedure namegt)

7
  • gt (trace exponent)
  • (EXPONENT)
  • gt (exponent 2 3)
  • 1gt EXPONENT called with args
  • 2
  • 3
  • 2gt EXPONENT called with args
  • 2
  • 2
  • 3gt EXPONENT called with args
  • 2
  • 1
  • 4gt EXPONENT called with args
  • 2
  • 0
  • 4lt EXPONENT returns value
  • 1
  • 3lt EXPONENT returns value
  • 2

8
Doubly recursive procedures each call originates
two recursive calls
  • Example compute Fibonacci numbers
  • (defun fibonacci (n)
  • (if (or ( n 0) ( n 1))
  • 1
  • ( (fibonacci (- n 1))
  • (fibonacci (- n 2)))))
  • FIBONACCI
  • (fibonacci 5)
  • 8
  • (trace fibonacci)
  • (FIBONACCI)

9
  • (fibonacci 5)
  • 1 Entering FIBONACCI, argument-list (5)
  • 2 Entering FIBONACCI, argument-list (4)
  • 3 Entering FIBONACCI, argument-list (3)
  • 4 Entering FIBONACCI, argument-list (2)
  • 5 Entering FIBONACCI, argument-list
    (1)
  • 5 Exiting FIBONACCI, value 1
  • 5 Entering FIBONACCI, argument-list
    (0)
  • 5 Exiting FIBONACCI, value 1
  • 4 Exiting FIBONACCI, value 2
  • 4 Entering FIBONACCI, argument-list (1)
  • 4 Exiting FIBONACCI, value 1
  • 3 Exiting FIBONACCI, value 3
  • 3 Entering FIBONACCI, argument-list (2)
  • 4 Entering FIBONACCI, argument-list (1)
  • 4 Exiting FIBONACCI, value 1
  • 4 Entering FIBONACCI, argument-list (0)
  • 4 Exiting FIBONACCI, value 1

10
Tail recursive procedures a way to make
recursion efficient
  • Example compute the number of elements in a list
    (version 1)
  • (defun count-elements-1 (list-1)
  • (if (endp list-1)
  • 0
  • ( 1 (count-elements-1 (rest list-1)))))
  • COUNT-ELEMENTS-1
  • (setf list-1 '(a b c d))
  • (count-elements-1 list-1)
  • 1 Entering COUNT-ELEMENTS-1, argument-list
    ((A B C D))
  • 2 Entering COUNT-ELEMENTS-1, argument-list
    ((B C D))
  • 3 Entering COUNT-ELEMENTS-1,
    argument-list ((C D))
  • 4 Entering COUNT-ELEMENTS-1,
    argument-list ((D))
  • 5 Entering COUNT-ELEMENTS-1,
    argument-list (NIL)
  • 5 Exiting COUNT-ELEMENTS-1, value 0
  • 4 Exiting COUNT-ELEMENTS-1, value 1
  • 3 Exiting COUNT-ELEMENTS-1, value 2
  • 2 Exiting COUNT-ELEMENTS-1, value 3
  • 1 Exiting COUNT-ELEMENTS-1, value 4

11
Tail recursion (cont.)
  • Example compute the number of elements in a
    list (version 2)
  • (defun count-elements-2 (list-1)
  • (count-elements-2-aux list-1 0))
  • COUNT-ELEMENTS-2
  • (defun count-elements-2-aux (list-1 result)
  • (if (endp list-1)
  • result
  • (count-elements-2-aux (rest list-1) ( 1
    result))))
  • COUNT-ELEMENTS-2-AUX
  • (count-elements-2 list-1)
  • 1 Entering COUNT-ELEMENTS-2-AUX,
    argument-list ((A B C D) 0)
  • 2 Entering COUNT-ELEMENTS-2-AUX,
    argument-list ((B C D) 1)
  • 3 Entering COUNT-ELEMENTS-2-AUX,
    argument-list ((C D) 2)
  • 4 Entering COUNT-ELEMENTS-2-AUX,
    argument-list ((D) 3)
  • 5 Entering COUNT-ELEMENTS-2-AUX,
    argument-list (NIL 4)
  • 5 Exiting COUNT-ELEMENTS-2-AUX, value
    4
  • 4 Exiting COUNT-ELEMENTS-2-AUX, value 4
  • 3 Exiting COUNT-ELEMENTS-2-AUX, value 4

12
The Tower of Hanoi example
  • Version 1 uses a doubly recursive procedure.
  • (defun tower-of-hanoi-1 (list-of-disks)
  • (if (endp list-of-disks)
  • 0
  • ( (tower-of-hanoi-1 (rest
    list-of-disks))
  • 1
  • (tower-of-hanoi-1 (rest
    list-of-disks)))))
  • TOWER-OF-HANOI-1
  • Version 2 uses a singly recursive procedure.
  • (defun tower-of-hanoi-2 (list-of-disks)
  • (if (endp list-of-disks)
  • 0
  • ( 1 ( 2 (tower-of-hanoi-2 (rest
    list-of-disks))))))
  • TOWER-OF-HANOI-2

13
Iteration control structure the DOTIMES primitive
  • Dotimes supports iteration on numbers. It has the
    following format
  • (dotimes (ltcount parametergt ltupper-bound
    formgt ltresult formgt)
  • ltbodygt)
  • When dotimes is entered, the upper-bound form is
    evaluated resulting
  • in a number, say n. Numbers between 0 and n-1 are
    assigned to the
  • count parameter one by one, and for each one of
    these numbers the
  • body is evaluated. Finally, the result form is
    evaluated, and its value is
  • returned by dotimes (if the result form is
    missing, dotimes returns NIL).

14
Example compute the n power of m.
  • (defun exponent-2 (m n)
  • (let ((result 1))
  • (dotimes (count n result)
  • (setf result ( m result)) )))

  • (print result)
  • EXPONENT-2
  • (trace exponent-2)
  • (EXPONENT-2)
  • (exponent-2 3 3)
  • 1 Entering EXPONENT-2, argument-list (3 3)
    trace is not very useful here.
  • 1 Exiting EXPONENT-2, value 27
    Incorporating print forms to see
  • 27
    intermediate
    results is better.

15
Iteration control stucture the DOLIST primitive
  • Dolist supports iteration on lists. Its format is
    the following
  • (dolist (ltelement parametergt ltlist formgt
    ltresult formgt)
  • ltbodygt)
  • When dolist is entered, the list form is
    evaluated returning a list of elements.
  • Each one of them is assigned to the element
    parameter, and the body is
  • evaluated. Finally, the result form is evaluated,
    and its value is returned by
  • dolist (if the result form is missing, dolist
    returns NIL).

16
Example count number of as in a list.
  • (defun count-a (list-1)
  • (let ((result 0))
  • (dolist (element list-1 result)
  • (when (eql element 'a)
  • (setf result ( 1 result))))))
  • COUNT-A
  • (setf list-1 '(a s d f a s d w a a))
  • (A S D F A S D W A A)
  • (count-a list-1)
  • 4

17
DOTIMES and DOLIST can be terminated by the
(return ltexpressiongt) form
  • Whenever (return ltexpressiongt) is encountered,
    dotimes/dolist
  • terminates and returns the value of ltexpressiongt.
  • Example does the list contain at least n as?
    If yes, return them as soon as they are found.
  • (defun find-n-a (n list-1)
  • (let ((result 0) (a-list nil))
  • (dolist (element list-1 a-list)
  • (cond ((lt n result) (return a-list))
  • ((eql element 'a) (setf result
    ( 1 result))

  • (setf a-list (cons element a-list)))))))
  • FIND-N-A
  • (find-n-a 2 list-1)
  • (A A)

18
The DO primitive works on both numbers and lists,
and is more general than DOTIMES and DOLIST
  • Dolist has the following format
  • (do ((ltparameter 1gt ltinitial value 1gt
    ltupdate form 1gt)
  • (ltparameter 1gt ltinitial value 1gt
    ltupdate form 1gt)
  • ..
  • (ltparameter 1gt ltinitial value 1gt
    ltupdate form 1gt))
  • (lttermination testgt ltintermediate
    formsgt ltresult formgt)
  • ltbodygt)
  • When do is entered, its parameters are set to
    their initial values in parallel
  • (in the same way as in the let form). If there
    are no parameters, an empty
  • parameter list must be provided. The termination
    test is evaluated always
  • before the body is evaluated. If it succeeds,
    intermediate forms and the
  • result form are evaluated the value of the
    result form is returned by do (if
  • no result form is given, do returns NIL).

19
Example compute mn
  • Version 1
  • (defun exponent-3 (m n)
  • (do ((result 1)
  • (exponent n))
  • ((zerop exponent) result)
  • (setf result ( m result))
  • (setf exponent (- exponent 1))))
  • EXPONENT-3
  • (exponent-3 3 3)
  • 27
  • Version 2
  • (defun exponent-4 (m n)
  • (do ((result 1)
  • (exponent n))
  • ( )
  • (when (zerop exponent) (return result))
  • (setf result ( m result))
  • (setf exponent (- exponent 1))))
  • EXPONENT-4
  • (exponent-4 3 3)
  • 27

20
DO assigns initial values to parameters
sequentially (like let)
  • Example which does not work
  • (defun exponent-5 (m n)
  • (do ((result m ( m result))
  • (exponent n (- exponent 1))
  • (counter (- exponent 1) (- exponent
    1)))
  • ((zerop counter) result)))
  • EXPONENT-5
  • (exponent-5 3 3)
  • Debugger warning leftover specials
  • gtgtgt Error Determining function in error.
  • gtgtgt ErrorUnbound variable EXPONENT
  • (ltCOMPILED-FUNCTION 3E196gt ...)
  • DO solves the problem.
  • (defun exponent-6 (m n)
  • (do ((result m ( m result))
  • (exponent n (- exponent 1))
  • (counter (- exponent 1) (- exponent
    1)))
  • ((zerop counter) result)))
  • EXPONENT-6
  • A better solution
  • (defun exponent-7 (m n)
  • (do ((result 1 ( m result))
  • (exponent n (- exponent 1))
  • (counter exponent (- counter 1)))
  • ((zerop counter) result)))
  • EXPONENT-7

21
The LOOP primitive implements infinite loop if
(return ltexpressiongt) is not encountered
  • Loop has the following format
  • (loop ltbodygt)
  • Example count the number of elements in a list.
  • (setf list-1 '(a b c d e))
  • (A B C D E)
  • (setf count-elements 0)
  • 0
  • (loop (when (endp list-1) (return
    count-elements))
  • (setf count-elements ( 1
    count-elements))
  • (setf list-1 (rest list-1)))
  • 5

22
The PROG1 and PROGN primitives allow several
forms to be viewed as a group in which forms are
evaluated sequentially.
  • Prog1 has the following form
  • (prog1 ltform 1gt ltform 2gt ltform ngt).
  • All forms are evaluated, and prog1 returns
    the value of the first form.
  • Progn has the following form
  • (progn ltform 1gt ltform 2gt ltform ngt).
  • All forms are evaluated, and progn returns
    the value of the last form.
  • Example
  • (prog1 (eql 'a 'a) (setf a 5))
  • T
  • (progn (eql 'a 'a) (setf a 5))
  • 5

23
The FORMAT primitive produces more elegant
printing than PRINT
  • Example
  • (format t "Hi there!")Hi there! the t
    argument says that the output should be

  • printed at the terminal. The
    returned value is
  • NIL
    NIL
  • To print a string on a new line, the directive
    should be placed at the
  • beginning of the string
  • (format t "Hi there!")
  • Hi there!
  • NIL
  • The directive tells format to print on a new
    line, if it is not already on
  • a new line, while the a directive tells format
    to insert the value of an
  • additional argument which appears after formats
    string.

24
Examples
  • (progn (format t "Student name a" name)
  • (format t "Major a" major))
  • Student name ANNA
  • Major CS
  • NIL
  • (format t "Student name 10a Major 10a"
    name major)
  • Student name ANNA Major CS
  • NIL
  • (format t "Student name 20a Major 10a"
    name major)
  • Student name ANNA Major CS
  • NIL

25
The Read primitive reads a value from the keyboard
  • Examples
  • (read)hello
    the input is typed immediately after read.
  • HELLO
  • (setf greetings (read))hi
    the input can be assigned to a variable.
  • HI
  • greetings
  • HI
  • (setf greetings (read))(hi there!) if
    the input contains more
  • (HI THERE!)
    than one symbol it must be enclosed in a list.
  • greetings
  • (HI THERE!)

26
Print and read used in combination allow for a
more informative dialog
  • Example
  • (prog1 (print '(Please enter your name))
  • (setf name (read))
  • (print (append '(hi) (list name) '(how
    are you today?))))
  • (PLEASE ENTER YOUR NAME) neli
  • (HI NELI HOW ARE YOU TODAY?)
  • (PLEASE ENTER YOUR NAME)
  • name
  • NELI
  • Do not use in the print argument for
    example, name will be understood
  • as a reference to a package which does not exist
    and will result in an error.

27
Read, Terpri and Format in combination can also
be used for a more informative dialog
  • Example
  • (prog1 (terpri)
  • (format t "Please enter your name ")
  • (setf name (read)) (terpri)
  • (format t "Hi a how are you today?"
    name))
  • Please enter your name neli
  • Hi NELI how are you today?
  • NIL
  • Notice the space between name and in the
    format statement.
Write a Comment
User Comments (0)
About PowerShow.com