define. The major difference in syntax is that in Lisp the formal arguments are written in parentheses while the function name os not. Here are some examples from the textbook:
(defun sum-greater (x y z) (> (+ x y) z)) (defun our-length (lst) (let ((len 0)) ;; notice the use of the function dolist (dolist (obj lst) (incf len)) len)) ;;; same as above written using recursion. Less efficient but perfectly fine (defun our-length (lst) (if (null lst) 0 (+ (our-length (cdr lst)) 1)))
(eq object1 object2)Two objects are eq if they have the same location in memory. This works for symbols, not for numbers and characters.
(eql object1 object2)this is the most widely used equality predicate. It is true if the two objects are eq, but also if they are the same character or two numbers that look the same when printed. When both elements are integers,
(= object1 object2)will also work.
(equal object1 object2)this is used to compare objects that have cons boxes (such as lists), strings, bit-vectors, and path-names. Of course, objects that are eql are also equal.
(equalp object1 object2)this is the most general predicate, and works also for arrays, structures, hash-tables.
setfis a very general function for assignments.
(setf < place> < value>)is used to assign a new value to a place. A place can be a variable, or a function call whose first element is
cdr, or most combinations of
cdr. For instance,
(setf (car lst) 'a)is equivalent to the Scheme expression
(set-car! lst 'a)
defconstant, or, more commonly,
setf, on which more is said later. The common convention is to use a * around the names of any global variable, as in
*counter*, to make it easier to see that it is a global variable.
&optional, auxiliary parameters (using
&aux), keywords (using
&key), and a variable number of parameters (using
&rest). These parameters can be initialized by replacing the parameters name with a list
&auxallows to define local parameters in the list of parameters, instead of defining them with let. It makes the code shorter and easier to read. Look for examples in mapping.
&keyallows to specify keywords. keywords parameters can have default values and be passed in any order. If a function includes keywords, the keywords are passed when the function is called by specifying what is the keyword. Many system defined functions use keywords to make them more flexible. For instance:
;; see if d is a member of the car of each element in the list (member 'd '((a . 2) (d . 4) (c . 1)) :key #'car) = ((D . 4) (C . 1)) ;; uses equal for the equality test instead of eql (member '(d . 4) '((a . 2) (d . 4) (c . 1)) :test #'equal) = ((D . 4) (C . 1)) (member '(d . 5) '((a . 2) (d . 4) (c . 1)) :test-not #'equal) = ((A . 2) (D . 4) (C . 1))
&restbinds all the remaining arguments as a list to the
(defun num-of-args (&rest lst) (length lst)) (num-of-args 'a 'b 'c 'd) = 4 (num-of-args 'a '(b c)) = 2 (num-of-args) = 0
cdrof an empty list. The value is
;; list here is a parameter (defun print-squares (list) ;; list here is again a parameter (dolist (element list) ;; but here it is a function (print (list element (expt element 2)))))Default choice of the namespace. When Lisp is given a list as a form to evaluate, if the first symbol in the list is not a special form or a macro. Lisp assumes it is the name of a function, and, consequently, uses its value in the functional namespace. For everything else Lisp uses the regular value.
Exceptions to the default choice of the namespace. Whenever the default choice of namespace is not appropriate we need to tell Lisp to select the other namespace. We do it in the following way:
(function < fn>), which is commonly abbreviated as
#'This is typically used in a function call when a function is passed as an argument to another function.
funcallto specify that the value of the symbol has to be used as a function and to pass its appropriate argument(s). To be more precise, we will write
(funcall < fn> &rest < arguments>)whenever we want to use the functional value of
< fn>and apply it to its arguments. This typically happens in the body a function that takes a function as an argument.
(defun filter (fn l) (cond ((null l) nil) ((funcall fn (car l)) (cons (car l) (filter fn (cdr l)))) (t (filter fn (cdr l)))))
funcallis needed since
fnis not the function we want to apply but the name of the function we want to apply.
Example: (filter #'oddp '(1 4 3 8 9)) = (1 3 9)When
filteris called we need to use
#'to specify that we want the functional value of the symbol
So, to repeat briefly how to select a namespace which it not the one used by default:
funcall, as in
(funcall fn &rest arguments), for the symbol
(function fn), which is commonly abbreviated as
(symbol-function 'foo)returns the current global function definition of
foo. This signals an error if there is no functional value. The predicate
(fboundp 'foo)can be used to check if
foois the name of a global function.
(symbol-value 'foo)returns the current value of the special variable
fooThis signals an error if there is no value. The predicate
(boundp 'foo)can be used to check if
foois the name of a special variable.
(symbol-name 'foo)returns the string that is the name of the symbol. This string cannot be modified
(symbol-plist 'foo)returns the property list of the symbol
specialhave indefinite scope. Constants have also indefinite scope.
specialvariable; the connection to a file established by
;;; USING THE LEXICAL SCOPE AND INDEFINITE EXTENT TO CREATE A VARIABLE ;;; THAT BEHAVES LIKE A GLOBAL VARIABLE BUT CAN BE ACCESSED ONLY IN A ;;; CONTROLLED WAY ;;; this create a local variable, counter, whichis shared by a group ;;; of functions. ;;; This allows multiple functions to operate on the same variable which ;;; is protected from any other access ;;; If multiple counters are needed it is better to use a generator ;;; (see the page on generators) (let ((counter 0)) ;; incf increments counter by 1 (defun bump-up () (incf counter)) (defun bump-down () (decf counter)) (defun counter-value () counter)) (bump-up) (bump-up) (counter-value)