Input/Output
June 8, 2008 | Filed Under Common Lisp - Touretzky
———————————————————
Chapter 9
———————————————————
Input/Output
Strings - double quoted:
(setf a “this is a string”) -> “this is a string”
(stringp a) -> T
(format t a) -> this is a string -> NIL
tilde character leads to special operations
~% -> forces newline
(format t “time flies~%like an arrow”) ->
time flies
like an arrow
NIL
~& forces a newline, unless the cursor is already on a new line
(format t “time flies~&~&like an arrow”) ->
time flies
like an arrow
NIL
vs (format t “time flies~%~%like an arrow) ->
time flies
like an arrow
NIL
~S is replaces by the evaluated expressions that follow the string:
(format t “from ~S to ~S in ~S minutes” ‘boston ‘(new york) 55) ->
“from boston to (new york) in 55 minutes”
NIL
(defun square-talk (n)
(format t “~&~S squareed is ~S” n (*n n))
(square-talk 3) -. 3 squared is 9
NB square-talk does not return 9, it returns NIL as per format
(mapcar #’square-talk ‘(1 2 3 4 5))
1 squared is 1
2 squared is 4….
…(NIL NIL NIL NIL NIL)
~A is the same as ~S, but excludes any escape characters:
(format t “test: ~S” “hi mom”) -> test “hi mom”
(format t “test: ~A” “hi mom”) -> test hi mom
READ takes a lisp object from the keyboard and returns the object as its value:
(defun my-square()
(format t “enter any number: “)
(let ((x (READ)))
(format t “your number squared is: ~S~%”
(* x x))))
YES-OR-NO-P / Y-OR-N-P - returns T if YES/Y or NIL if NO/N
(defun riddle()
(IF (YES-OR-NO-P “Do you seek enlightenment:”)
(format t “Then do not ask for it”)
(format t “Then you have found it”)))
WITH-OPEN-FILE - opens a file for read/write access
(defun save-data (item1 item2 item3)
(WITH-OPEN-FILE (STREAM “c:/data.dat” :direction :output)
(format stream “~S~%” item1)
(format stream “~s~%” item2)
(format stream “~s~%” item3)))
(save-data “this” ‘(is a number) 5))
WITH-OPEN-FILE creates a variable that is set to a stream object, and can be READ from:
(defun read-data()
(WITH-OPEN-FILE (stream “C:/data.dat”)
(let* ((item1 (read stream))
(item2 (read stream))
(item3 (read stream)))
(format t “~A~%” item1)
(format t “~A~%” item2)
(format t “~A~%” item3))))
this
(is a number)
5
———————————————————
Notes on chapter 9 exercises
Using recursion to create a list:
(defun generate (m n)
(cond ((equal m n)(list n))
(T (cons m (generate (+ m 1) n)))))
this produces an list of integers from m to n:
(generate -3 3) -> (-3 -2 -1 0 1 2 3)
recurses until m equal to n, then passes back a list containing n only. this is then cons’d with a progressively smaller m number in each recursion as it passes back.
———————————————————
Format parameters:
pad an input with ~10S - makes a 10 wide output (same with ~10A, etc)
(format t “~&~10S~S” “jim” “jones”)
“jim” “jones”
~D and ~F make decimal and floating point numbers respectively, both take prefixes:
~x,yF - x is width (incl decimal point) y is number of decimal places
(format t “~4,2F” 3/2) -> 1.50
End Of File conditions:
When using READ and error will be thrown if you try to recurse-read beyond the end of the file.
To catch this, use 2 condition tags: NIL to indicate an error should not be thrown, and and EOF value that should be returned in the event of reaching the end of the file. the EOF value should be unique - best to cast a fresh cons cell:
(defun read-all-objects (stream eof-ind)
(let ((result (read stream NIL eof-ind)))
(if (eq result eof-ind)
NIL
(cons result (read-all-objects stream eof-ind)))))
This takes a stream and a new cons cell for the EOF flag. Reads from the stream, and if EOF then the EOF flag gets passed back as the value for result. If not EOF, then cons’s the result. NB if EOF, then passes NIL back - this is the last cell, which thus forms a value list.
(defun read-my-file (filename)
(WITH-OPEN-FILE (stream filename)
(let ((contents (read-all-objects stream (list ‘$EOF$))))
(format t “~&File contains ~S objects, which are:” (length contents))))contents)
Comments
Leave a Reply