Page 121
Once you understand the semantics of open
and
close
, forget about them. Always use
with-open-file
.
Also, be aware that the read-line
example at the
bottom of the page may behave differently in different
implementations. In some, the read-line
will see the
return following the expression you just entered and return an empty
string, after which Lisp will see the "Please enter ...
"
and complain that Please
is an unbound variable.
Page 122
In case you're curious, the name pseudo-cat
comes
from the Unix shell function cat
, which is commonly used
to print files to the screen. Why cat
? It's short for
"catenate." cat
was designed to concatenate files. Unix designers
like short names, not clear ones.
What does concatenation have to do with printing? First, in Unix, by default, all shell commands send the output to the screen. Second, by a not unreasonable extension, if you concatenate a file to nothing, you get the file. Unix designers like reusing existing commands, even if the semantics is unintuitive, so concatenating a file to nothing became the standard way to print the file to the screen.
Warning: Don't use a flag like EOF
to signal
the end of file
value with the Lisp read
function. If the input file has the
symbol EOF
in it, your function will be
fooled into thinking the file has ended. See Exercise 2 of this chapter.
This confusion can't happen
with read-line
or read-char
because they
return strings or characters, not symbols.
Page 123
Warning: The fact that read-from-string
takes both
optional and keyword arguments causes strange things to happen when
you want the latter and not the former. See page 293.
Page 124
Though (format nil ...)
is a very useful method for
constructing strings, be aware that it's not printing, it's building
a string. Use (format t ...)
for printing, or
(format stream ...)
if you have a stream variable
connected to a file.
There's a lot more about format
in the Glossary
at the back of the book. And if that's not enough, check
out Section 22.3
at the Common Lisp Hyperspec.
Also, in general, use ~S
for all debugging output.
~A
will
sometimes hide information critical to debugging an errant function,
such as what package a symbol is coming from.
Page 126
You could also implement the circular buffer with a circular list. See page 208.