lisp tutorial - vub artificial intelligence lab · lisp tutorial disclaimer this tutorial is based...

14
Lisp Tutorial Disclaimer This tutorial is based and uses substantial parts from Chapter 3 of Peter Norvig’s ’Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp’ and multiple chapters from Peter Seibel’s ’Pratical Common Lisp’. These books are highly recommended. 1 Basic concepts The three most basic components of all Lisp programs are functions, variables and macros. Although macros are one of the more interesting and powerful parts of lisp it lies outside the scope of this tutorial. 1.1 Functions The basic skeleton which allows you to define a function, a DEFUN, looks like this: (defun name (parameter*) "Optional documentation string." body-form*) Any symbol can be used as a function name. Usually function names contain only alphabetic characters and hyphens, but other characters are allowed and are used in certain naming conventions. A function’s parameter list defines the variables that will be used to hold the arguments passed to the function when it’s called. If the function takes no arguments, the list is empty, written as (). More on the kinds of parameters later (Section 1.1.1). 1

Upload: others

Post on 24-Mar-2020

13 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Lisp Tutorial - VUB Artificial Intelligence Lab · Lisp Tutorial Disclaimer This tutorial is based and uses substantial parts from Chapter 3 of Peter Norvig’s ’Paradigms of Arti

Lisp Tutorial

Disclaimer

This tutorial is based and uses substantial parts from Chapter 3 of PeterNorvig’s ’Paradigms of Artificial Intelligence Programming: Case Studies inCommon Lisp’ and multiple chapters from Peter Seibel’s ’Pratical CommonLisp’. These books are highly recommended.

1 Basic concepts

The three most basic components of all Lisp programs are functions, variablesand macros. Although macros are one of the more interesting and powerfulparts of lisp it lies outside the scope of this tutorial.

1.1 Functions

The basic skeleton which allows you to define a function, a DEFUN, looks likethis:

(defun name (parameter*)

"Optional documentation string."

body-form*)

Any symbol can be used as a function name. Usually function names containonly alphabetic characters and hyphens, but other characters are allowed andare used in certain naming conventions.

A function’s parameter list defines the variables that will be used to holdthe arguments passed to the function when it’s called. If the function takes noarguments, the list is empty, written as (). More on the kinds of parameterslater (Section 1.1.1).

1

Page 2: Lisp Tutorial - VUB Artificial Intelligence Lab · Lisp Tutorial Disclaimer This tutorial is based and uses substantial parts from Chapter 3 of Peter Norvig’s ’Paradigms of Arti

If a string literal follows the parameter list, it’s a documentation stringthat should describe the purpose of the function. When the function isdefined, the documentation string will be associated with the name of thefunction and can later be obtained using the DOCUMENTATION function.

Finally, the body of a DEFUN consists of any number of Lisp expressions.They will be evaluated in order when the function is called and the value ofthe last expression is returned as the value of the function.

Some examples:

(defun hello-world ()

(print "hello, world!"))

(defun verbose-sum (x y)

"Sum any two numbers after printing a message."

(format t "Summing ~d and ~d.~\%" x y)

(+ x y))

1.1.1 Function Parameter Lists

The basic purpose of a parameter list is, of course, to declare the variablesthat will receive the arguments passed to the function. When a parameterlist is a simple list of variable names–as in verbose-sum–the parameters arecalled required parameters. When a function is called, it must be suppliedwith one argument for every required parameter. Each parameter is boundto the corresponding argument. If a function is called with too few or toomany arguments, Lisp will signal an error.

However, Common Lisp’s parameter lists also give you more flexible waysof mapping the arguments in a function call to the function’s parameters. Inaddition to required parameters, a function can have optional parameters.Or a function can have a single parameter that’s bound to a list containingany extra arguments. And, finally, arguments can be mapped to parametersusing keywords rather than position.

Some examples of optional parameters:

(defun foo (a &optional b)

(list a b)) ;; list is a built-in function that creates a list

;; examples of calling foo

(foo 1) ==> (1 NIL) ;; optional parameters have a default value of NIL

(foo 1 2) ==> (1 2)

2

Page 3: Lisp Tutorial - VUB Artificial Intelligence Lab · Lisp Tutorial Disclaimer This tutorial is based and uses substantial parts from Chapter 3 of Peter Norvig’s ’Paradigms of Arti

(defun foo (a &optional (b 5))

(list a b))

(foo 1) ==> (1 5) ;; you can supply another default value

(foo 1 2) ==> (1 2)

More versatile than optional parameters are keyword parameters. Theseallow you to explicitly name the parameters so that ordering doesn’t matter.For example

(defun foo (&key a b c)

(list a b c))

When this function is called, each keyword parameter is bound to thevalue immediately following a keyword of the same name. Keywords arenames that start with a colon and that they’re automatically defined as self-evaluating constants.

If a given keyword doesn’t appear in the argument list, then the corre-sponding parameter is assigned its default value, just like an optional param-eter. Because the keyword arguments are labeled, they can be passed in anyorder as long as they follow any required arguments. For instance, foo canbe invoked as follows:

(foo) ==> (NIL NIL NIL)

(foo :a 1) ==> (1 NIL NIL)

(foo :b 1) ==> (NIL 1 NIL)

(foo :c 1) ==> (NIL NIL 1)

(foo :a 1 :c 3) ==> (1 NIL 3)

(foo :a 1 :b 2 :c 3) ==> (1 2 3)

(foo :a 1 :c 3 :b 2) ==> (1 2 3)

In general, if you find yourself writing a function that uses both &op-tional and &key parameters, you should probably just change it to use all&key parameters–they’re more flexible, and you can always add new keywordparameters without disturbing existing callers of the function.

Lisp also provides a catchall parameter after the symbol &rest. If afunction includes a &rest parameter, any arguments remaining after valueshave been doled out to all the required and optional parameters are gatheredup into a list that becomes the value of the &rest parameter. For example:

3

Page 4: Lisp Tutorial - VUB Artificial Intelligence Lab · Lisp Tutorial Disclaimer This tutorial is based and uses substantial parts from Chapter 3 of Peter Norvig’s ’Paradigms of Arti

(defun foo (a b &rest more)

(list a b more))

(foo 1 2 3 4 5) ==> (1 2 (3 4 5))

;; to get a nice list we should have done

(defun foo (a b &rest more)

(append (list a b) more))

(foo 1 2 3 4 5) ==> (1 2 3 4 5)

1.2 Variables

As in other languages, in Common Lisp variables are named places that canhold a value. However, in Common Lisp, variables aren’t typed the way theyare in languages such as Java or C++. That is, you don’t need to declarethe type of object that each variable can hold. Instead, a variable can holdvalues of any type and the values carry type information that can be usedto check types at runtime. Thus, Common Lisp is dynamically typed–typeerrors are detected dynamically. For instance, if you pass something otherthan a number to the + function, Common Lisp will signal a type error.On the other hand, Common Lisp is a strongly typed language in the sensethat all type errors will be detected–there’s no way to treat an object as aninstance of a class that it’s not.

One way to introduce new variables you’ve already used is to define func-tion parameters. As you saw in the previous Section, when you define afunction with DEFUN, the parameter list defines the variables that will holdthe function’s arguments when it’s called. For example, this function definesthree variables–x, y, and z–to hold its arguments.

(defun foo (x y z) (+ x y z))

Another form that introduces new variables is the LET special operator.The skeleton of a LET form looks like this:

(let (variable*)

body-form*)

where each variable is a variable initialization form. Each initialization formis either a list containing a variable name and an initial value form or–as

4

Page 5: Lisp Tutorial - VUB Artificial Intelligence Lab · Lisp Tutorial Disclaimer This tutorial is based and uses substantial parts from Chapter 3 of Peter Norvig’s ’Paradigms of Arti

a shorthand for initializing the variable to NIL–a plain variable name. Thefollowing LET form, for example, binds the three variables x, y, and z withinitial values 10, 20, and NIL:

(let ((x 10) (y 20) z)

...)

The scope of function parameters and LET variables–the area of the programwhere the variable name can be used to refer to the variable’s binding–isdelimited by the form that introduces the variable. This form–the functiondefinition or the LET–is called the binding form.

If you nest binding forms that introduce variables with the same name,then the bindings of the innermost variable shadows the outer bindings. Forinstance, when the following function is called, a binding is created for theparameter x to hold the function’s argument. Then the first LET creates anew binding with the initial value 2, and the inner LET creates yet anotherbinding, this one with the initial value 3. The bars on the right mark thescope of each binding.

(defun foo (x)

(format t "Parameter: ~a~%" x) ; |<------ x is argument

(let ((x 2)) ; |

(format t "Outer LET: ~a~%" x) ; | |<---- x is 2

(let ((x 3)) ; | |

(format t "Inner LET: ~a~%" x)) ; | | |<-- x is 3

(format t "Outer LET: ~a~%" x)) ; | |

(format t "Parameter: ~a~%" x)) ; |

Each reference to x will refer to the binding with the smallest enclosingscope. Once control leaves the scope of one binding form, the binding fromthe immediately enclosing scope is unshadowed and x refers to it instead.Thus, calling foo results in this output:

CL-USER> (foo 1)

Parameter: 1

Outer LET: 2

Inner LET: 3

Outer LET: 2

Parameter: 1

NIL

5

Page 6: Lisp Tutorial - VUB Artificial Intelligence Lab · Lisp Tutorial Disclaimer This tutorial is based and uses substantial parts from Chapter 3 of Peter Norvig’s ’Paradigms of Arti

Another binding form is a variant of LET, LET*. The difference is that in aLET, the variable names can be used only in the body of the LET–the partof the LET after the variables list–but in a LET*, the initial value forms foreach variable can refer to variables introduced earlier in the variables list.Thus, you can write the following:

(let* ((x 10)

(y (+ x 10)))

(list x y))

but not this:

(let ((x 10)

(y (+ x 10)))

(list x y))

2 Lists

Besides lists you also have vectors and arrays in LISP, but we will not discussthem in this tutorial. In this section we will simply enumerate some basicfunctions you can call on lists.

The key to understanding lists is to understand that they’re largely anillusion built on top of objects that are instances of a more primitive datatype. Those simpler objects are pairs of values called cons cells, after thefunction CONS used to create them.

CONS takes two arguments and returns a new cons cell containing thetwo values.2 These values can be references to any kind of object. Unless thesecond value is NIL or another cons cell, a cons is printed as the two valuesin parentheses separated by a dot, a so-called dotted pair.

(cons 1 2) ==> (1 . 2)

The two values in a cons cell are called the CAR and the CDR after thenames of the functions used to access them. At the dawn of time, thesenames were mnemonic, at least to the folks implementing the first Lisp onan IBM 704.

Because the values in a cons cell can be references to any kind of object,you can build larger structures out of cons cells by linking them together.Lists are built by linking together cons cells in a chain. The elements of the

6

Page 7: Lisp Tutorial - VUB Artificial Intelligence Lab · Lisp Tutorial Disclaimer This tutorial is based and uses substantial parts from Chapter 3 of Peter Norvig’s ’Paradigms of Arti

list are held in the CARs of the cons cells while the links to subsequent conscells are held in the CDRs. The last cell in the chain has a CDR of NIL,which represents the empty list as well as the boolean value false.

This arrangement is by no means unique to Lisp; it’s called a singly linkedlist. However, few languages outside the Lisp family provide such extensivesupport for this humble data type.

When talking about structures built out of cons cells, a few diagrams canbe a big help. Box-and-arrow diagrams represent cons cells as a pair of boxeslike this: The box on the left represents the CAR, and the box on the right is

the CDR. The values stored in a particular cons cell are either drawn in theappropriate box or represented by an arrow from the box to a representationof the referenced value. For instance, the list (1 2 3), which consists of threecons cells linked together by their CDRs, would be diagrammed like this:However, most of the time you work with lists you won’t have to deal with

individual cons cells–the functions that create and manipulate lists take careof that for you. For example, the LIST function builds a cons cells under thecovers for you and links them together; the following LIST expressions areequivalent to the previous CONS expressions:

(list 1) ==> (1)

(list 1 2) ==> (1 2)

(list 1 2 3) ==> (1 2 3)

Similarly, when you’re thinking in terms of lists, you don’t have to use themeaningless names CAR and CDR; FIRST and REST are synonyms for CARand CDR that you should use when you’re dealing with cons cells as lists.

(defparameter *list* (list 1 2 3 4))

(first *list*) ==> 1

(rest *list*) ==> (2 3 4)

(first (rest *list*)) ==> 2

7

Page 8: Lisp Tutorial - VUB Artificial Intelligence Lab · Lisp Tutorial Disclaimer This tutorial is based and uses substantial parts from Chapter 3 of Peter Norvig’s ’Paradigms of Arti

Because cons cells can hold any kind of values, so can lists. And a single listcan hold objects of different types.

(list "foo" (list 1 2) 10) ==> ("foo" (1 2) 10)

The structure of that list would look like this:

3 Special Forms

Besides the syntax of atoms and function calls, Lisp has a small numberof syntactic expressions. They are known as special forms. They serve thesame purpose as statements in other programming languages, and indeedhave some of the same syntactic markers, such as if and loop. The mostcommonly used special forms are: Most programming languages provide a

Sometimes, however, the maxims are in conflict, and experience will tell you

which one to prefer. Consider the following two ways of placing a new key/value

pair on an association list:'

(push (cons key val) a-list)

(setf a-list (acons key val a-list))

The first is more concise. But the second is more specific, as it uses the acons

function, which is designed specifically for association lists. The decision between

them probably hinges on obscurity: those who find acons to be a familiar function

would prefer the second, and those who find it obscure would prefer the first.

A similar choice arises in the question of setting a variable to a value. Some prefer

(setq x val 1 because it is most specific; others use (setf x val 1, feeling that it is

more consistent to use a single form, setf, for all updating. Whichever choice you

make on such issues, remember the sixth maxim: be consistent.

3.2 Special Forms

As noted in chapter 1, "special form" is the term used to refer both to Common Lisp's

syntactic constructs and the reserved words that mark these constructs. The most

commonly used special forms are:

definitions conditional variables iteration

def u n

defstruct

defvar

defparameter

defconstant

defmacro

1 abel s

and 1 e t do

case 1 et* do*

cond POP do1 i s t

i f push dotimes

or setf 1 oop

unl ess i ncf

when decf

other

decl a re

f uncti on

progn quote

return

trace

untrace

To be precise, only decl are, function, i f , 1 abel s, 1 et, 1 et*, progn and quote

are true special forms. The others are actually defined as macros that expand into

calls to more primitive special forms and functions. There is no real difference to the

programmer, and Common Lisp implementations are free to implement macros as

special forms and vice versa, so for simplicity we will continue to use "special form"

as a blanket term for both true special forms and built-in macros.

l~ssociation lists are covered in section 3.6.

way to group related data together into a structure. Common Lisp is noexception. The defstruct special form defines a structure type (known as arecord type in Pascal) and automatically defines functions to get at compo-nents of the structure. The general syntax is:

(defstruct structure-name

"optional documentation"

slot* ...)

8

Page 9: Lisp Tutorial - VUB Artificial Intelligence Lab · Lisp Tutorial Disclaimer This tutorial is based and uses substantial parts from Chapter 3 of Peter Norvig’s ’Paradigms of Arti

As an example, we could define a structure for names:

(defstruct name

first

(middle nil)

last)

This automatically defines the constructor function make-name, the recog-nizer predicate name-p, and the accessor functions name-first, name-middleand name-last. The (middle nil means that each new name built by make-name will have a middle name of nil by default. Here we create, access, andmodify a structure:

(setf b (make-name :fi rst ’Barney :last ’Rubble)) ==>

#S(NAME :FIRST BARNEY :LAST RUBBLE)

(name-first b) => BARNEY

(name-middle b) => NIL

(name-last b) => RUBBLE

(name-p b) => T

(name-p ’Barney) => NIL ; only the results of make-name are names

(setf (name-middle b) ’Q) => Q

b => #S(NAME :FIRST BARNEY :MIDDLE Q :LAST RUBBLE)

3.1 Special Forms for Conditionals

We have seen the special form if, which has the form

(if test then-part else-part)

where either the then-part or the else-part is the value, depending on thesuccess of the test. Remember that only nil counts as false; all other valuesare considered true for the purpose of conditionals. However, the constant tis the conventional value used to denote truth (unless there is a good reasonfor using some other value).

The syntax of cond is a series of cond-clauses, each consisting of a testexpression followed by any number of result expressions:

(cond (test result ...)

(test result ...)

...)

9

Page 10: Lisp Tutorial - VUB Artificial Intelligence Lab · Lisp Tutorial Disclaimer This tutorial is based and uses substantial parts from Chapter 3 of Peter Norvig’s ’Paradigms of Arti

cond goes through the cond-clauses one at a time, evaluating each test expres-sion. As soon as a test expression evaluates non-nil, the result expressionsfor that clause are each evaluated, and the last expression in the clause isthe value of the whole cond.

3.2 Special Forms for Variables and Places

The special form setf is used to assign a new value to a variable or place,much as an assignment statement with = or := is used in other languages. Aplace, or generalized variable is a name for a location that can have a valuestored in it.

(setf x 0) ;; in Pascal this would be x := 0;

Because lists are so important to Lisp, there are special forms for adding anddeleting elements from the front of a list-in other words, for treating a list asa stack. If list is the name of a location that holds a list, then (push x list)will change list to have x as its first element, and (pop list) will return thefirst element and, as a side-effect, change list to no longer contain the firstelement. push and pop are equivalent to the following expressions:

(push x list) = (setf list (cons x list))

(pop list) = (let ((result (first list)))

(setf list (rest list))

result)

Just as a list can be used to accumulate elements, a running sum can beused to accumulate numbers. Lisp provides two more special forms, i ncfand decf, that can be used to increment or decrement a sum. For both formsthe first argument must be a location (a variable or other setf-able form)and the second argument, which is optional, is the number to increment ordecrement by. For those who know C, (incf x) is equivalent to ++x, and(incf x 2) is equivalent to x+=2. In Lisp the equivalence is:

(incf x) = (incf x 1) = (setf x (+ x 1))

(decf x) = (decf x 1) = (setf x (- x 1))

3.3 Functions and Special Forms for Repetition

Many languages have a small number of reserved words for forming iterativeloops. For example, Pascal has while, repeat, and for statements. In contrast,

10

Page 11: Lisp Tutorial - VUB Artificial Intelligence Lab · Lisp Tutorial Disclaimer This tutorial is based and uses substantial parts from Chapter 3 of Peter Norvig’s ’Paradigms of Arti

Common Lisp has an almost bewildering range of possibilities, as summarizedbelow: To explain each possibility, we will present versions of the function

be a location (a variable or other setf-able form) and the second argument, which

is optional, is the number to increment or decrement by. For those who know C,

( i ncf x) is equivalent to ++x, and ( i ncf x 2 is equivalent to x+=2. In Lisp the

equivalence is:

( i n c f x ) = ( i n c f x 1) = ( s e t f x (+ x 1))

(decf x ) = (decf x 1 ) = ( s e t f x ( - x 1 ) )

When the location is a complex form rather than a variable, Lisp is careful to expand

into code that does not evaluate any subform more than once. This holds for push ,

pop, i ncf, and decf. In the following example, we have a list of players and want

to decide which player has the highest score, and thus has won the game. The

structure pl aye r has slots for the player's score and number of wins, and the function

determi ne - wi nner increments the winning player's wi ns field. The expansion of the

i ncf form binds a temporary variable so that the sort is not done twice.

( d e f s t r u c t p layer (score 0 ) (wins 0 ) )

(defun determine-winner (p layers )

"Increment t h e WINS f o r t h e p layer w i t h h ighes t score."

( i n c f ( p l ayer-wins ( f i r s t ( s o r t p laye rs # '>

:key # ' p l a y e r - s c o r e ) ) ) ) ) - - -

(defun determi ne-wi nner ( p l ayers 1 " Increment t h e WINS f o r t h e p layer w i t h h ighes t score. "

( l e t (( temp ( f i r s t ( s o r t p laye rs # '> :key # ' p l a y e r - s c o r e ) ) ) )

( s e t f (p layer-wins temp) (+ (p layer-wins temp) 1) ) ) )

Functions and Special Forms for Repetition

Many languages have a small number of reserved words for forming iterative loops.

For example, Pascal has wh i 1 e, re peat, and for statements. In contrast, Common

Lisp has an almost bewildering range of possibilities, as summarized below:

do1 i s t loop over elements of a list

dotimes loop over successive integers

do, do* general loop, sparse syntax

1 OOP general loop, verbose syntax

mapc, mapcar loop over elements of lists(s)

some, every loop over list until condition

f i nd , reduce, etc. more specific looping functions

recursion general repetition

length, which returns the number of elements in a list. First, the special formdolist can be used to iterate over the elements of a list. The syntax is:

(dolist (variable list optional-result)

body...)

This means that the body is executed once for each element of the list, withvariable bound to the first element, then the second element, and so on. Atthe end, dolist evaluates and returns the optional-result expression, or nil ifthere is no result expression.

Below is a version of length using dolist . The let form introduces a newvariable, len, which is initially bound to zero. The dolist form then executesthe body once for each element of the list, with the body incrementing 1 enby one each time. This use is unusual in that the loop iteration variable,element, is not used in the body.

(defun length1 (list)

(let ((len 0)) ; start with LEN=O

(dolist (element list) ; and on each iteration

(incf len)) ; increment LEN by 1

len)) ; and return LEN

There is also a dotimes form, which has the syntax:

(dotimes (variable number optional-result)

body...)

and executes the body with variable bound first to zero, then one, all theway up to number - 1 (for a total of number times). Of course, dotimes is

11

Page 12: Lisp Tutorial - VUB Artificial Intelligence Lab · Lisp Tutorial Disclaimer This tutorial is based and uses substantial parts from Chapter 3 of Peter Norvig’s ’Paradigms of Arti

not appropriate for implementing length, since we don’t know the number ofiterations ahead of time. There are two very general looping forms, do andLOOP. The syntax of loop is an entire language by itself, and a decidedlynon-Lisp-like language it is.Rather than list all the possibilities for LOOP,we will just give examples Here are three versions of length using loop:

(defun length4 (list)

(loop for element in list

count t)

(defun length5 (list)

(loop for element in list

summing 1)

(defun length6 (list)

(loop with len = 0

until (null list)

for element = (pop list)

do (incf len)

finally (return len)))

3.3.1 Repetition through Recursion

Lisp has gained a reputation as a ”recursive” language, meaning that Lispencourages programmers to write functions that call themselves. As we haveseen above, there is a dizzying number of functions and special forms forwriting loops in Common Lisp, but it is also true that many programs handlerepetition through recursion rather than with a syntactic loop.

One simple definition of length is ”the empty list has length 0, and anyother list has a length which is one more than the length of the rest of the list(after the first element).” This translates directly into a recursive function:

(defun length9 (list)

(if (null list)

0

( + 1 (length9 (rest list)))))

12

Page 13: Lisp Tutorial - VUB Artificial Intelligence Lab · Lisp Tutorial Disclaimer This tutorial is based and uses substantial parts from Chapter 3 of Peter Norvig’s ’Paradigms of Arti

3.4 Functions on Numbers and Sets

The most commonly used functions on numbers are listed here. There arequite a few other numeric functions that have been omitted. One of the

3.8 Functions on Numbers The most commonly used functions on numbers are listed here. There are quite a few other numeric functions that have been omitted.

(+ 4 2 ) +6 add ( - 4 2 ) + 2 subtract (* 4 2 ) + 8 multiply (1 4 2 ) + 2 divide (> 100 99 1 + t greater than (also >=, greater than or equal to) (= 100 100 ) + t equal (also I=, not equal) (< 99 100 ) + t less than (also <=, less than or equal to) ( random 100 + 42 random integer from 0 to 99 (expt 4 2 1 + 16 exponentiation (also exp, ex and 1 og) (sin pi) +0.0 sinefunction(alsocos,tan,etc.) (asin 0) + 0.0 arcsine or sin-' function (also acos, a t a n , etc.) ( mi n 2 3 4 ) + 2 minimum (also max) (abs -3) + 3 absolute value (sqr t 4) + 2 square root (round 4.1) + 4 roundoff (also truncate, floor, ceiling) ( rem 11 5 1 + 1 remainder (also mod)

3.9 Functions on Sets One of the important uses of lists is to represent sets. Common Lisp provides functions that treat lists in just that way. For example, to see what elements the sets r = { a , b, c, d ) and s = { c , d , e ) have in common, we could use:

> ( s e t f r ' ( a b c d l ) + ( A B C D) > ( s e t f s ' ( c d e l ) +- (C D E l > ( i n t e r s e c t i o n r s ) + (C D)

This implementation returned ( C D ) as the answer, but another might return ( D C 1. They are equivalent sets, so either is valid, and your program should not depend on the order of elements in the result. Here are the main functions on sets:

( i n t e r s e c t i o n r s ) + ( c d l find common elements of two sets (un ion r s ) +- ( a b c d e 1 find all elements in either of two sets ( s e t - d i f f e r e n c e r s ) + ( a b ) find elements in one but not other set (member ' d r ) +- ( d l check if an element is a member of a set (subsetp s r ) + n i l see if all elements of one set are in another ( a d j o i n ' b s ) + (b c d e 1 add an element to a set ( a d j o i n 'c s ) =+ ( C d e l . . . but don't add duplicates

important uses of lists is to represent sets. Common Lisp provides functionsthat treat lists in just that way. Here are the main functions on sets:

3.8 Functions on Numbers The most commonly used functions on numbers are listed here. There are quite a few other numeric functions that have been omitted.

(+ 4 2 ) +6 add ( - 4 2 ) + 2 subtract (* 4 2 ) + 8 multiply (1 4 2 ) + 2 divide (> 100 99 1 + t greater than (also >=, greater than or equal to) (= 100 100 ) + t equal (also I=, not equal) (< 99 100 ) + t less than (also <=, less than or equal to) ( random 100 + 42 random integer from 0 to 99 (expt 4 2 1 + 16 exponentiation (also exp, ex and 1 og) (sin pi) +0.0 sinefunction(alsocos,tan,etc.) (asin 0) + 0.0 arcsine or sin-' function (also acos, a t a n , etc.) ( mi n 2 3 4 ) + 2 minimum (also max) (abs -3) + 3 absolute value (sqr t 4) + 2 square root (round 4.1) + 4 roundoff (also truncate, floor, ceiling) ( rem 11 5 1 + 1 remainder (also mod)

3.9 Functions on Sets One of the important uses of lists is to represent sets. Common Lisp provides functions that treat lists in just that way. For example, to see what elements the sets r = { a , b, c, d ) and s = { c , d , e ) have in common, we could use:

> ( s e t f r ' ( a b c d l ) + ( A B C D) > ( s e t f s ' ( c d e l ) +- (C D E l > ( i n t e r s e c t i o n r s ) + (C D)

This implementation returned ( C D ) as the answer, but another might return ( D C 1. They are equivalent sets, so either is valid, and your program should not depend on the order of elements in the result. Here are the main functions on sets:

( i n t e r s e c t i o n r s ) + ( c d l find common elements of two sets (un ion r s ) +- ( a b c d e 1 find all elements in either of two sets ( s e t - d i f f e r e n c e r s ) + ( a b ) find elements in one but not other set (member ' d r ) +- ( d l check if an element is a member of a set (subsetp s r ) + n i l see if all elements of one set are in another ( a d j o i n ' b s ) + (b c d e 1 add an element to a set ( a d j o i n 'c s ) =+ ( C d e l . . . but don't add duplicates

3.5 Overview of Data Types

Here is a table of the most commonly used data types:

13

Page 14: Lisp Tutorial - VUB Artificial Intelligence Lab · Lisp Tutorial Disclaimer This tutorial is based and uses substantial parts from Chapter 3 of Peter Norvig’s ’Paradigms of Arti

3.11 Overview of Data Types This chapter has been organized around functions, with similar functions grouped together. But there is another way of organizing the Common Lisp world: by con- sidering the different data types. This is useful for two reasons. First, it gives an alternative way of seeing the variety of available functionality. Second, the data types themselves are objects in the Common Lisp language, and as we shall see, there are functions that manipulate data types. These are useful mainly for testing objects (as with the typeca s e macro) and for making declarations.

Here is a table of the most commonly used data types:

Type Example Explanation character #\c A single letter, number, or punctuation mark. number 4 2 The most common numbers are floats and integers. float 3.14159 A number with a decimal point. integer 4 2 A whole number, of either fixed or indefinite size: f ixnum 123 An integer that fits in a single word of storage. bi gnum 123456789 An integer of unbounded size. function #'sin A function can be applied to an argument list. symbol sin Symbols can name fns and vars, and are themselves objects. nu1 1 ni 1 The object ni 1 is the only object of type null. keyword : key Keywords are a subtype of symbol. sequence ( a b c ) Sequences include lists and vectors. l i s t ( a b C ) A list is either a cons or nu1 1. vector # ( a b C ) Avector is a subtype of sequence. cons ( a b C ) A cons is a non-nil list. a t om t An atom is anything that is not a cons. string "abc" A string is a type of vector of characters. array #1A( a b c ) Arrays include vectors and higher-dimensional arrays. structure #S(type . . . I Structuresaredefinedbydefstruct. hash-table . . . Hash tables are created by make - has h - t a bl e.

Almost every data type has a recognizer predicate-a function that returns true for only elements of that type. In general, a predicate is a function that always returns one of two values: true or false. In Lisp, the false value is ni 1, and every other value is considered true, although the most common true value is t . In most cases, the recognizer predicate's name is composed of the type name followed by p: cha racterp recognizes characters, numberp recognizes numbers, and so on. For example, ( number p 3 1 returns t because 3 is a number, but ( numbe rp "xu 1 returns n i 1 because " x " is a string, not a number.

Unfortunately, Common Lisp is not completely regular. There are no recognizers for fixnums, bignums, sequences, and structures. Two recognizers, n u 1 1 and a tom, do not end in p. Also note that there is a hyphen before the p in hash - t a b 1 e- p, because the type has a hyphen in it. In addition, all the recognizers generated by defstruct have a hyphen before the p.

14