1 Variable Declarations Global and special variables – (defvar …) – (defparameter …) –...
-
Upload
lilian-della-williams -
Category
Documents
-
view
223 -
download
0
Transcript of 1 Variable Declarations Global and special variables – (defvar …) – (defparameter …) –...
1
Variable Declarations• Global and special variables
– (defvar …)– (defparameter …)– (defconstant …)– (setq var2 (list 4 5))– (setf …)
• Local variables– (let ((x 10)) …)– (let* ((x 99) …)
2
Global Variables• Declared using defvar and defparameter:
– (defvar <var name> <init value> <documentation>)
>(defvar number-list nil "A list of numbers")
• Assigned values using setf special form:– (setf <place> <new value>)
>(setf x 3)
3
>x
3
• Imperative Paradigm Alert (why?)
3
Global variables are visible throughout the program.
Global variables can be created by giving a symbol and a value to defparameter or defvar.
> (defparameter *foo* 1)
*FOO*
> *foo*
1
> (defvar *bar* (+ *foo* 1))
*BAR*
> *bar*
2
> (defvar *bar* 33)
*BAR*
> *bar*
2
Note: (defparameter v e)
creates a global variable named v and sets its value to be e.
(defvar v e) is just like
defparameter if no global
variable named v exists.
Otherwise it does nothing.
Global Variables, cont.
4Global Constants and Variables
• Define a global constant with defconstant > (defconstant +limit+ 100)
+LIMIT+
> (setf +limit+ 99)
Error: can't assign a global constant
• readability conventions– +symbolname+ identifies symbols as constants – *symbolname* identifies global variables
5Assignment Statements
• Assignment operators: set, setq and setf • The most general is setf• It assigns both local and global variables:
> (setf *blob* 89)
89
> (let ((n 10))
(setf n 2)
n)
2• Initialized n to 10, then executed all the statements
within the scope of let
6
setf • Create global variables implicitly by assigning values
> (setf x (list 'a 'b 'c))
(A B C)
• However, it is better lisp style to use defparameter
to declare global variables• You can give setf any even number of arguments
(setf a 1 b 2 c 3)
is the same as:(setf a 1)
(setf b 2)
(setf c 3)
7
setf cont.• You can do more than just assigning values to
variables!• The first argument to setf can be an expression
as well as a variable name.• In such cases, the value of the second argument is
inserted in the place referred to by the first:> x
(A B C)> (setf (car x) 'n)
N
> x
(N B C)
8
> (setq a (make-array 3))
#(NIL NIL NIL)
> (aref a 1)
NIL
> (setf (aref a 1) 3)
3
> a
#(NIL 3 NIL)
> (aref a 1)
3
setf Examples> (defstruct foo bar)
FOO
> (setq a (make-foo))
#s(FOO :BAR NIL)
> (foo-bar a)
NIL
> (setf (foo-bar a) 3)
3
> a
#s(FOO :BAR 3)
> (foo-bar a)
3
9
Return or Change?• The function remove takes an object and a list and returns
a new list where all occurrences of the object were removed
> (setf lst '(b u t t e r))
(B U T T E R)
> (remove 'e lst)
(B U T T R)• Note: remove does not remove any items from the list!
The original list is untouched after the call to remove:
> lst
(B U T T E R)• To remove the items from a list you would have to use setf:
> (setf lst (remove 'e lst))
(B U T T R)• Functional programming means, essentially, avoiding setf, and
other assignments.
10
I/O Input• (read [<stream>] ...)
– reads the printed representation of an object from a stream
• (read-char [<stream>] ...)– returns one character and advances the stream pointer
• (read-char-no-hang [<stream>] ...)– returns one character if one is available (if so, advances the
stream pointer)
• (read-line [<stream>] ...)– read characters terminated by a newline, returns a string
containing the characters
• (yes-or-no-p [format-string <args>*])– ask the user a yes/no question
(yes-or-no-p "set x to 3?")
11
I/O Output• print - prints and returns object in lisp format
> (print (list "foo" "bar"))
("foo" "bar")
("foo" "bar")• princ - prints for readability, without control characters e.g. " ", returns object lisp
format
> (princ "hello")
hello
"hello"• format - the most general output function
(format <stream> <control-string> <arg>*)– stream t prints to *standard-output*– returns NIL– the second argument is a string template,– the remaining arguments are objects to be inserted into the template:
> (format t "~A plus ~A equals ~A." 2 3 (+ 2 3))
2 plus 3 equals 5.
NIL
12Developing Recursive Functions
• Recursive function calls a copy of itself
1. Do error checking first (if needed)
2. Check for base cases (non-recursive cases)
3. Recursion• must be on a smaller problem
• If number – closer to base case
• If list – shorter or less complex
• Avoid infinite loops!!!!• out of stack space error
13Exercise - Write a filtering function
• A function to filter out negative numbers from a list of numbers.
• Examples:> (filter-negatives '(1 -1 2 -2 3 -4))
(1 2 3)
> (filter-negatives '("string"))
List must contain only numbers
> (filter-negatives '(-1 -2 -2 -3 -4))
NIL
> (filter-negatives '(9 10))
(9 10)
14
Filter-negatives1. Error checking• Is argument a list?
• Continue
• End with error message
2. Test for base case(s)• Is the list empty?
• Return the empty list ()
3. Test the first item• Is it a number?
• If not – error message
• Is it a negative number?
• Ignore it - recurse on the rest of the list and return that result
• Is it a positive number?
• Add that number to the result of recursion on the rest of the list
15
Start the function(defun filter-negatives (inlist)
"takes one argument, a list of numbers
and returns a list containing all the
non-negative numbers in the input"
(cond ; make decisions
; error – not a list?
; base case – empty list?
; what are the more complex cases?
; check first item in list --
; not a number? Error or ignore
; negative number?
; Ignore, process remaining items
; positive number?
; Add to result, process remaining items
) )
16
filter-negatives(defun filter-negatives (inlist)
"takes one argument, a list of numbers and
returns a list containing all the nonnegative
numbers in the input"
(cond ; make decisions
((not (listp inlist); not a list?
(princ "Argument must be a list" )
(terpri) ; print return after string
(list)) ; return an empty list
17
filter-negatives(defun filter-negatives (inlist)
(cond ; make decisions
((not (listp inlist); not a list?
(princ "Argument must be a list" )
(terpri) ; print return after string
(list)) ; return an empty list
; base case – empty list?
((null inlist)
(list)) ; return an empty list
18Recursive Cases – Not a Number
; what are the more complex cases?
; check first item in list
; not a number? Error or ignore
19Recursive cases – Negative Number
; negative number?
; Ignore, process remaining items
20Recursive Cases – Positive Number
; positive number?
; add to result, process remaining items
21
filter-negatives;;; Error checking on input - list of numbers
;;; The base case, the list is empty so return nil
;;; if first item in arg is positive, add it to the result of recursion
;;; if it is negative, throw it away, return = result of recursion
(defun filter-negatives (inlist)
(cond
((not (listp inlist)) ; 1st test
(princ "Argument must be a list") ; print message
(terpri) (list)) ; return empty list, quit
((null inlist) (list)) ; 2nd test - out of items
((not (numberp (car inlist))) ; 3rd test - not a number
(princ "List must contain only numbers") ; print message
(terpri) (list)) ; return empty list, quit
((>= (car inlist) 0) ; 4th test - positive number
(cons (car inlist) ; add 1st to result of
(filter-negatives (cdr inlist)))) ; recursion on rest
((< (car inlist) 0) ; 5th test - negative number
(filter-negatives (cdr inlist)) ; ignore 1st, return value
) ) ) ; = recursion on rest
; Note: the last test could have been t (true)
22
filter-negatives• filter.lisp
• www2.hawaii.edu/~janst/313/lisp/filter.lisp
23
&optional in parameter list• Gives a name to additional variable(s) in
a parameter list.(defun func (arg1 &optional arg2)…)
• No error if variable(s) are present or not(func 10)
(func 10 20)
• Default value can be specified(defun func (arg1 &optional (arg2 init2))…)
(func 10) = (func 10 init2)
24
&key in parameter list• Several optional parameters,• Keywords rather than order is used to match
formal names to actual names > (defun func (width &key ((:height h)) ((:depth d)))
(format t "w = ~d, h = ~d, d = ~d" width h d))
FUNC
> (func 1 :height 2 :depth 3)
w = 1, h = 2, d = 3
NIL
> (func 1 :depth 3 :height 2)
w = 1, h = 2, d = 3
NIL
25
&rest in parameter list• Allows to accept any of number of parameters• Such parameters form a list
> (defun list2 (&rest x) x)
LIST2
> (list2 1 2 3 4 5)
(1 2 3 4 5)
26Exercise: count-occurrences
• Write a function that takes two parameters• The first is an item to look for
• The second parameter is a list
• Returns the number of times item is found• Example:
> (count-occurrences 'a
'(a (a c d a) (c b a)))
1
• www2.hawaii.edu/~janst/313/lisp/count-occurrences.lisp
27
count_all_items• Now write a function that takes the same
two parameters• The first is an item to look for
• The second parameter is a list
• The function returns the number of times the item occurs in the list at any level of nesting
• Example:
>(count_all_items 'a
'(b (a c d a) (c a b)))
should return 3
28Exercise: make-change
• Write a function that calculates change (in US currency)
> (make-change 123)
((1 DOLLARS) (2 DIMES) (3 PENNIES))
(defconstant *us-currency*
'((100 dollars) (50 half-dollars)
(25 quarters) (10 dimes)
(5 nickels) (1 pennies)))
29
make-change
(defun make-change (number)
(
; error checking
; base case(s)
; recursive case(s)
• www2.hawaii.edu/~janst/313/lisp/makechange.lisp