| OPERATING CLISP |
Starting CLISP
$ clisp
i i i i i i i ooooo o ooooooo ooooo ooooo
I I I I I I I 8 8 8 8 8 o 8 8
I \ `+' / I 8 8 8 8 8 8
\ `-+-' / 8 8 8 ooooo 8oooo
`-__|__-' 8 8 8 8 8
| 8 o 8 8 o 8 8
------+------ ooooo 8oooooo ooo8ooo ooooo 8
Welcome to GNU CLISP 2.42 (2007-10-16)
Copyright (c) Bruno Haible, Michael Stoll 1992, 1993
Copyright (c) Bruno Haible, Marcus Daniels 1994-1997
Copyright (c) Bruno Haible, Pierpaolo Bernardi, Sam Steingold 1998
Copyright (c) Bruno Haible, Sam Steingold 1999-2000
Copyright (c) Sam Steingold, Bruno Haible 2001-2007
>
Open a File
> (load "/path/to/file.lp")
;; Loading file /path/to/file.lp ...
;; Loaded file /path/to/file.lp
T
Handling
Errors
When handling errors, the user is given the ability to see an
error report, and to see different options they have to fix the
error. Here, we can see that there is only one restart available,
R1. If R1 is triggered then the code will abort the operation. We
also could have typed abort. Using abort to quit out of an error
will always return back out of all of the different break
points.
> (expt 5)
*** - EVAL: too few arguments given to EXPT: (EXPT 5)
The following restarts are available:
ABORT :R1 ABORT
Break 1 > :R1
>
Were we still inside of a break point, we could have typed 'help'
to see some of the other available debugging options, including the
ability to inspect an error, and the ability to back-trace what
caused the error. Here is the help information
Commands may be abbreviated as shown in the second column.
COMMAND ABBR DESCRIPTION
Help :h, ? this command list
Error :e Print the last error message
Inspect :i Inspect the last error
Abort :a abort to the next recent input loop
Unwind :uw abort to the next recent input loop
Reset :re toggle *PACKAGE* and *READTABLE* between the
local bindings and the sane values
Quit :q quit to the top-level input loop
Mode-1 :m1 inspect all the stack elements
Mode-2 :m2 inspect all the frames
Mode-3 :m3 inspect only lexical frames
Mode-4 :m4 inspect only EVAL and APPLY frames (default)
Mode-5 :m5 inspect only APPLY frames
Where :w inspect this frame
Up :u go up one frame, inspect it
Top :t go to top frame, inspect it
Down :d go down one frame, inspect it
Bottom :b go to bottom (most recent) frame, inspect it
Backtrace-1 :bt1 list all stack elements
Backtrace-2 :bt2 list all frames
Backtrace-3 :bt3 list all lexical frames
Backtrace-4 :bt4 list all EVAL and APPLY frames
Backtrace-5 :bt5 list all APPLY frames
Backtrace :bt list stack in current mode
Backtrace-l :bl list stack in current mode.
Limit of frames to print will be prompted for.
Frame-limit :fl set the frame-limit. This many frames will
be printed in a backtrace at most.
Break+ :br+ set breakpoint in EVAL frame
Break- :br- disable breakpoint in EVAL frame
Redo :rd re-evaluate form in EVAL frame
Return :rt leave EVAL frame, prescribing the return values
The following restarts are available:
ABORT :R1 ABORT
Getting help on a
function
CLISP allows the user to retrieve help on any function they would
like to use by calling 'description' with the name of the function
they would like help on. Here is an example:
> (describe 'cos)
COS is the symbol COS, lies in #, is accessible in 15
packages ASDF, CLOS, COMMON-LISP, COMMON-LISP-CONTROLLER, COMMON-LISP-USER,
EXPORTING, EXT, FFI, POSIX, READLINE, REGEXP, SCREEN, SYSTEM, XLIB, XPM, names
a function.
#<PACKAGE COMMON-LISP> is the package named COMMON-LISP. It has 2 nicknames
LISP, CL.
It imports the external symbols of 1 package CLOS and exports 978 symbols to
14 packages ASDF, COMMON-LISP-CONTROLLER, XLIB, XPM, READLINE, REGEXP,
POSIX, EXPORTING, FFI, SCREEN, CLOS, COMMON-LISP-USER, EXT, SYSTEM.
#<SYSTEM-FUNCTION COS> is a built-in system function.
Argument list: (#:ARG0)
For more information, evaluate (DISASSEMBLE #'COS).
>
Quitting
> (quit)
Bye.
|
| COMMENTS |
| OVERVIEW
Comments in Lisp, like most other languages, are for the purpose
of documentation. Lisp also has an added comment type that allows
one to get a description of a function without having to look at the
code file. This style of comment is called a Function Description
Comment. Single Line Comments
;single line comments are started with a semi-colon
Block Comments
#|
this is a block comment, it will
allow the programmer to comment out multiple lines.
It is also good for commenting out broken functions, etc.
|#
Function Description Comments
(defun double (x)
"This multiplies the passed argument by two"
(* x 2))
|
| SYMBOLS |
| OVERVIEW
A symbol in Lisp is simply any string of characters, numbers, and
hyphens. Generally, user defined symbols should start with a
character; however, this is not a strictly enforced
style. Set the value of a Symbol
> (setq a 10)
10
Pass a symbol as an argument to a function
> (+ a 10)
20
Temporarily set value of a symbol
> (let ((a 5)) (* a 10))
50
> a
10
Reserved Symbols
Lisp reserves the symbols t and nil.
t stands for true, and nil stands for
false. These symbols can not be changed.
|
| NUMBERS |
| OVERVIEW
Numbers in Lisp are a string of digits that can optionally be
preceded by a + or -. Lisp has built in facilities to handle real,
rational, and complex numbers. Most standard arithmetic functions
are available for use, including (but not limited to) +, -, /, *,
floor, ceiling, mod, trigonometric functions, etc. Lisp does not
limit the memory allocated to a single number, and will support
large integers up to the largest size the available memory supports.
Using large integers, or bignum's will significantly
increase computation time. Number Types
> 32
32
> -17
-17
> 3/4
3/4
> 3.141592653589
3.141592653589
> 1.06e-23
1.06e-23
> #c(3.14 0.75)
#C(3.14 0.75)
Arithmetic
Operations
> (exp 1)
2.7182817
> (+ 4 1/4)
17/4
> (expt 3 4)
81
> (+ 1 2 3 (* 4 5 6))
126
|
| CONSES |
| OVERVIEW
Conses are simple, two field records. They are the foundation for
lists, trees, and many other structures that can be used very
successfully in lisp code. Cons allow setting and retrieving each
field separately, namely with the car and cdr
functions. Allocate a cons
> (cons 5 4)
(4 . 5)
car and cdr
> (car (cons 4 5)) ;first can be used as a synonym for car
4
> (cdr (cons 4 5)) ;rest is a synonym for cdr
5
> (setq a (cons 10 20))
(10 . 20)
> (car a)
10
> (setf (cdr a) 30) ;here, we see the set field function
30
> a
(10 . 30)
|
| LISTS |
| OVERVIEW
As the name Lisp implies (List Processing), lisp handles lists
very well. The simplest, and most frequently used, list is a linked
list. Linked lists are made by using stacked conses. The car of each
cons is an element in the list, and the cdr of each one is the link
to the next element. The cdr can either be another cons (allowing
for another element in the list), or it can be nil, signifying the
end of the list. To help keep notation clean and compact, this style
of list can be accomplished with the list
function. Making a list
> (list 4 5 6)
(4 5 6)
> (cons 4 (cons 5 (cons 6 nil)))
(4 5 6)
Appending lists
together
> (append (list 4 5 6) (list 7 8 9))
(4 5 6 7 8 9)
Remove element from list by value
> (delete 4 (list 1 2 4 3 4 5 2))
(1 2 3 5 2)
Sorting a
list
> (sort (list 1 2 4 3 4 5 2) #'>)
(1 2 2 3 4 4 5)
Using a list as a tree
> (setq a (list 1 2 3 4))
(1 2 3 4)
> (setq b (list 5 6 7 a))
(5 6 7 (1 2 3 4))
> (list 'a 'b 1 2 a) ;if you just want to include the character, put a single quote before it
(A B 1 2 (1 2 3 4))
There are many other list operations that can be preformed
easily. These include sorting, reversing, mapping, pushing, popping,
and much more. Do not write a function if someone else might have
already written it, it is probably part of the available code.
Note: When printing the contents of a linked
list to the screen, lisp will omit the dot seen in regular cons
notation if the cdr is another cons, or if the cdr is nil (meaning
the end of the linked list). |
| MAPPING |
| OVERVIEW
Mapping is one of the most outstanding features in lisp. Mapping
allows the user to apply a function over all of the items in a list,
vector, or other structure. MAPCAR, MAPC, and MAPCAN process
successive list elements. MAPLIST, MAPL, and MAPCON will process
lists and successive sublists. MAP and MAP-INTO work on multiple
sequence types, not just lists. MAPCAR
MAPCAR simply applies the passed function against the rest of the
arguments supplied.
> (mapcar #'+ (list 1 2 3) (list 4 5 6))
(5 7 9)
MAPC
MAPC is similar to MAPCAR, except that instead of generating a
new list and returning it, just returns the first list passed in
> (mapc #'(lambda (x y) (print (* x y))) (list 1 0 2) (list 3 4 5))
3
0
10
(1 0 2)
MAPLIST
MAPLIST works like MAPCAR, but generates a list of the results of
the function executed on the lists, and all of the successive
sublists.
> (maplist #'list (list 1 2 3) (list 4 5 6))
(((1 2 3) (4 5 6)) ((2 3) (5 6)) ((3) (6)))
MAPL
MAPL is like MAPC in that it does not generate a new list and
return it, but it also processes all of the lists given as
arguments, and their successive sublists. MAPL returns the first
passed list.
> (mapl #'(lambda (x y) (print (append x y))) (list 1 0 2) (list 3 4 5))
(1 0 2 3 4 5)
(0 2 4 5)
(2 5)
(1 0 2)
MAP
MAP works on lists, vectors, and nil. It operates much like
MAPCAR, but lets you define what type it is operating over. When
operating on nil, MAP always returns NIL.
> (map nil #'+ (list 1 2 3) (list 4 5 6))
NIL
> (map 'list #'+ (list 1 2 3) (list 4 5 6))
(5 7 9)
> (map 'vector #'+ (list 1 2 3) (list 4 5 6))
#(5 7 9)
> (map '(vector number 3) #'+ (list 1 2 3) (list 4 5 6))
#(5 7 9)
|
| FUNCTIONS |
| OVERVIEW
Lisp, being a functional language, uses nested functions to
accomplish tasks very effectively. This also means that being able
to write an effective function can mean the difference between clean
code and an atrocity infested with bugs. Most simple actions in lisp
are functions - this includes +, -, list, append etc.
Using a Function
> (+ 4 5 6)
15
> (append (list 1 2) (list 3 4))
(1 2 3 4)
Defining a
Function
> (defun add-two (x) (+ 2 x))
ADD-TWO
> (add-two 5)
7
> (defun small-math (x) ;functions with multiple statements
(setq x (* x 3)) ;will return the value of the last statement
(setq x (+ x 2))
(+ x 1))
SMALL-MATH
> (small-math 5)
18
Functions with
optional arguments
A function can be defined that takes an optional number of
arguments. This is accomplished by using the &optional symbol.
Any arguments after &optional in the argument list are
optional.
> (defun optional-func (x &optional y)
(if y x 0))
OPTIONAL-FUNC
> (optional-func 5)
0
> (optional-func 5 10)
5
> (defun another-func (x &optional (y 4)) ;we can also use this notation to give optional arguments
(+ x y)) ;default values
ANOTHER-FUNC
> (another-func 5)
9
> (another-func 5 10)
15
Functions with
unlimited arguments
A function can be created that takes unlimited arguments by
passing the &rest argument followed by a parameter. The
parameter then collects the rest of the passed arguments in a list
for processing, and binds it to the symbol.
> (defun return-rest (x &rest y) y)
RETURN-REST
> (return-rest 5)
NIL
> (return-rest 5 10 15 20)
(10 15 20)
Keyword
Arguments
Keyword arguments allow the user to pass arguments in any order
because they are associated with keywords.
> (defun key-func (&key x y) (cons x y))
KEY-FUNC
> (key-func :y 10)
(NIL . 10)
> (key-func :x 5 :y 10)
(5 . 10)
> (key-func)
(NIL)
Passing a function
as an argument
There are two ways to pass a function as an argument, you can
either use the 'function' function, or the the prefix of #'.
> #'+
#<SYSTEM-FUNCTION +>
> (function +)
#<SYSTEM-FUNCTION +>
> (defun callfunc (x) (funcall x 2 3))
CALLFUNC
> (callfunc #'+)
5
> (callfunc (function *))
|
| PRINTING |
| OVERVIEW
Like with most other languages, lisp has the ability to print
various forms of data to the console. This is mainly accomplished
with the print and format functions. The print function allows
simple and easy printing of variables, and the format function
allows formatted output. print Function
> (print 5)
5 ;this is the '5' that is printed
5 ;this is the '5' that is returned
format
Function
The format function's second argument is either t, nil, or a
stream. If the argument is t, then the output goes to terminal. If
the argument is nil, then the function prints nothing and instead
returns a string representation. If the argument is a stream, then
the output is sent over that stream.
> (format t "an atom: ~S, a list: ~S and ~% an integer: ~D" nil (list 10 5 15) 44)
an atom: NIL, a list: (10 5 15) and
an integer: 44
NIL
|
| ARRAYS |
| OVERVIEW
Arrays are one of the simpler structures in lisp - they are very
similar to arrays in other languages, but are not limited by having
a single type. The 'make-array' command makes an array, and the
'aref' command allows the user to reference an element of an
array. Making an Array
> (make-array '(3 3)) ;here, we are passing a list, not what it executes to, so we use the '
#2A((NIL NIL NIL) (NIL NIL NIL) (NIL NIL NIL))
> (make-array 4) ;no need for parens on single dimensional arrays
(NIL NIL NIL NIL)
Accessing an
Array
> (aref (make-array 4) 1)
NIL
Note: Array
indices always start at 0 |
| STRINGS |
| OVERVIEW
Strings in Lisp are much like strings in C in that they are
stored as a single dimensional character array. To use a string in
lisp, we can simply place a sequence of characters in double quotes.
If you want to write a string that has a double quote, the quotation
mark can be preceded by a backslash (as an escaping character). Here
is an example:
> "Look! A String with a \""
"Look! A String with a \""
Notably, a string executes to itself. Get the length
of a string
> (length "hi there")
8
Access a character
in a string
> (char "abc" 1)
#\b ;this is lisp's notation for a character
> (aref "abc" 1)
#\b ;remember, strings are just arrays
Concatenate
strings
> (concatenate 'string "abc" "def")
"abcdef"
|
| STRUCTURES |
| OVERVIEW
Structures in lisp are very similar to structures in C, or
records in Pascal. They allow data to be stored and accessed with an
associated keyword. To define a struct, you simply need to call the
'defstruct' method with the name of the struct and the keywords of
its members. Once a structure definition is made, then functions to
make a new instance and access its fields are also made
available. Defining a Structure
> (defstruct foo ;name of the struct is foo
alpha
bravo
charlie)
FOO
We now have the commands 'make-foo', 'foo-alpha', 'foo-bravo',
and 'foo-charlie' available for use. Make instance of
structure
> (make-foo)
#s(FOO :ALPHA NIL :BRAVO NIL :CHARLIE NIL)
> (make-foo :bravo "a string!")
#s(FOO :ALPHA NIL :BRAVO "a string!" :CHARLIE NIL) ;we can also define a value for a field when creating the structure instance.
Access member in
structure
> (foo-bravo (make-foo :bravo "a string!"))
"a string!"
Alter value of field
in structure
> (setq a (make-foo))
#S(FOO :ALPHA NIL :BRAVO NIL :CHARLIE NIL)
> (setf (foo-charlie a) '(1 2 3))
(1 2 3)
> a
#S(FOO :ALPHA NIL :BRAVO NIL :CHARLIE (1 2 3))
'setf' allows us to set a field within a
structure |
| CONDITIONALS |
| OVERVIEW
Like with most other languages, conditionals (often in the form
of the classic 'if' and 'then', play a huge part in the operation of
lisp programs. Lisp uses the atom 'nil' to mean false, and anything
else to mean true. If a program is being written that needs to have
the ability to generate a boolean value, the most often used atom to
represent true is 't'. Lisp provides the logical operators and, or,
not, and the like for simple boolean manipulation. The most basic of
the lisp conditional is the 'if' function, but lisp also provides an
if-else like function called cond and a couple
others. Using if statements
If statements are in the form (if boolean_value
then_value else_value).
> (if NIL 5 6)
6
> (if 4 5 6)
5
Using when
statements
'when' statements are much like if statements, except take an
unlimited number of arguments, checking if the first one is not nil,
then executing the remainder.
> (when t
(print "Hello"))
"Hello" ;printed value
"Hello" ;returned value
> (when nil
(print "World!"))
NIL
Using cond
'cond' is equivalent to a set of if...else if..else if...
statements.
> (setq a 87)
87
> (cond
((> a 90) "Great job!")
((> a 80) "OK job!")
((> a 70) "Do better!")
((> a 60) "Do something!")
(t "Go home!")) ;if nothing else has already been true, it will execute this
"OK job!"
Using the case
statement
> (setq a 'Y)
B
> (case a
(w 5)
((x y) 6) ;x or y
((z i) 7) ;z or i
(otherwise 8))
6
|
| ITERATIONS |
| OVERVIEW
The simplest iteration function in lisp is 'loop', a construct
that simply iterates over its body until it hits the 'return'
special form (special forms are things in lisp that look like
functions but are not. Unfortunately, they are out of the
scope of this document. Simple use of 'loop'
> (setq x 0)
0
> (loop
(setq x (+ x 1))
(print x)
(if (= x 10) (return NIL)))
1
2
3
4
5
6
7
8
9
10
NIL
Using
'dolist'
'dolist' binds a locally scoped variable to each element in a
list successively and executes until it reaches the end of the
list
> (dolist (x '(A B C))
(print x))
A
B
C
NIL
Note:dolist will always return nil
|
| SORTING |
| OVERVIEW
Lisp provides a couple of easy to use sorting functions called
'sort' and 'sort' stable. The functions are allowed to be
destructive functions, however, so they may destroy the arguments
that are passed into them. We can avoid this by calling copy-list or
copy-tree if needed. sort also takes a function for it to use for
comparison., in the examples below, we use the greater than and less
than functions; however, any function could be used. sort-stable is
the stable version of sort, meaning that if there are two elements
that are equal according to the comparison function, they will occur
in the same order in the sorted list as they do in the unsorted
list Using sort
> (sort '(4 2 5 5 6 2) #'>)
(6 5 5 4 2 2)
> (sort '(6 5 4 3 2 1) #'<)
(1 2 3 4 5 6)
|
| EQUALITY |
| OVERVIEW
Lisp provides a number of functions for comparing to see if two
thing are equal. It is important to always use a function that
actually compares the objects in the manner intended, as different
comparison functions do not compare in the same
way. Comparing Numbers
> (= 4 4)
T
> (= 4 5)
NIL
> (= 4 4.0)
T
> (= 4 #c(4.0 0))
T
Comparing memory
addresses
> (setq x (cons 'a 'b))
(A . B)
> (setq y x)
(A . B)
> (eq x y)
T
> (eq (cons 'a 'b) (cons 'a 'b))
NIL
|
| FILE SYSTEM ACCESS |
| OVERVIEW
Lisp provides a large number of functions for accessing the file
system for I/O purposes. Most of the functions are self
explanatory. Open a file
> (open "/path/to/file")
#<INPUT BUFFERED FILE-STREAM CHARACTER #P"/path/to/file" @1>
Read from a
file
> (let ((in (open "/path/to/file.txt")))
(format t "~a~%" (read-line in))
(close in))
Some text was in this file
T
Write to a
file
> (with-open-file (stream "/some/file/name.txt" :direction :output)
(format stream "Some text."))
T
|
|