[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]


This message contains a number of comments on the recently-mailed Common
Lisp manual.  I also have a bunch of comments on the business of
Arrays, Vectors, and Fill-pointers that I will save for another message,
and a bunch of things relating only to the presentation itself that I
will send direct to Guy.  I am assuming that Guy plans to produce a
draft of the missing sections before the meeting, and that the list of
queries in the manual are automatically agenda items.  All page numbers
are keyed to the Colander Edition of 29 July.

Page 11: The statement that variable bindings are by default lexical and
indefinite is a very fundamental departure form past Lisps.  It makes
little trouble for a file-to-file compiler, but really impacts the
interpreter heavily, slowing it down by perhaps a factor of 2 whether
the indefinite-extent feature is used or not.  Some clever
special-casing may reduce this penalty at the price of considerable
added complexity.  I can live with this if everyone else can, but we
need to go into this with our eyes open, and not slip this into the
language in a single sentence.  I opposed this change until I realized
that even to make interpreter variables local by default is a messy
business, so we may as well go the whole way; the current situation, in
which compiled variables defautl to local and interpreted variables to
special, is clearly unacceptable.

Page 19: I oppose the use of an infix J to represent complex numbers.
Hard to read and non-lispy.  If users do a lot of complex hackery and
find #C(n1 n2) too hard to type, they can define a macro to make it
{n1 n2} or some such.

Page 25, first full par: Strings and bit-vectors are specializations of
vector, which in turn implies that they are arrays.  The rest of the
manual is consistent about this, but here it says that they are 1-D
arrays, which might or might not also be vectors.  The phrase "string
vector" is (or should be) redundant, not to mention hideous.

Page 33: I object to making bit-vectors self-evaluating forms, unless
ALL vectors are to be self-evaluating.  (Actually, I would make
everything except a symbol or a list evaluate to itself, but Guy wants
to make passing a general vector to EVAL an error, so that someday we
can define this to be something useful.)  Whatever we do about other
types, it seems really strange to make eval of a vector an error unless
that vector happens to hold 1-bit items.  Strings are different enough
that it doesn't bother me to make them self-eval.

Page 33: Note that in that same paragraph is another of those little
one-liners: keywords will eval to themselves.  The mechanism for this is
left up to the implementor -- it could be wired into eval and the
compiler, or it could just be a setq at make-symbol time.  Having seen
this both ways, I think it is a good idea, on balance.  It is really
ugly to have to type (foo ':key1 val1 ':key2 val2 ...).  And we
certainly don't want to be in the position of having to quote keywords
to EXPRs and not to macros and special forms -- very confusing.  The
price we pay for this is not being able to use the keywords as variable
names in keyword-taking functions, since we cannot assign values to them
-- hence the funny tapdance on page 38-39.

Page 42, query:  I oppose this alleged "safety feature".  It is always a
risk to redefine something, but macros are no worse than anything else.
I might go along with a query when the user redefines ANY built-in
function, as long as there is a switch to make this go away.

Page 46: I favor the suggestion that TYPEP of one argument be renamed to
something else, since it is not really a predicate.  Nothing with "%",
though -- this is a user-level function, though it should be used at
top-level and internally, and not in user-level code.

Page 51: I favor the suggestion that arrays of identical size whose
elements match should be EQUALP, regardless of the element-type of the

Page 51, 120, 132, 133: Guy and I both now feel that the FUZZ argument
to EQUALP should be flushed, along with FUZZY= and FUZZINESS, which
exist only so that EQUALP can be defined in terms of them.  If EQUALP
gets two flonums of different types, they are coerced, compared, and
then must be exactly equal for EQUALP to hold.  Similarly, the hairy
tolerance arguments to MOD and REM must go.  The sentiment behind all of
this is that we don't want to put some sort of half-assed treatment of
precision and tolerance into the white pages.  For most uses this is
just confusing, and when you really want it, it is not good enough.  We
need a yellow pages module to do this right, with each number carrying
around a precision figure, perhaps in conjunction with a package for
infinite-precision flonums.

Page 67: Like lexical variables, including FLET, LABELS, and MACROLET in
the language slows down the interpreter even if these are not used.
Again, we need to explicitly consider whether this is worth the cost.

Page 81-83: Can we agree to rename these things so that the names are
consistent?  All of them should have one prefix, chosen from
"MULTIPLE-VALUE-", "MV-", or "MV".  I don't really care which we choose,
but we should not have a mixture.

Page 98: I like the IGNORE declaration better than naming variables
"IGNORE".  The OPTIMIZE declaration is nearly useless as it is -- there
have to be several levels of Speed vs. safety optimization in the VAX,
for instance.  If we can't come up with something better, we should
leave this kind of declaration up to the implementation and put nothing
into the white pages.

Page 102: There was some discussion earlier about the names for PUTPR
and friends, but Guy viewed this as being sufficiently inconclusive that
he went with the unfortunate decisions made at the November meeting.  I
propose that we retain GET and REMPROP, which had no order-of-arguments
problems anyway, and that we rename the proposed PUTPR to PUT.  The
latter will probably not be used much anyway, if people get used to
using SETF.

Page 117, query: I have no objection in principle to requiring support
for complex numbers, but only AFTER someone has delivered to all of us a
complete, portable set of number functions, that contains full support
for complexes.  This package must also be efficient -- complexes must
not slow down arithmetic when they are not being used -- and in the
public domain.  Guy plans to write such a thing (or oversee the writing)
someday, but until he delivers, complexes cannot go into the required
part of the language.  Some of us have to deliver full, legal
implementations of Common Lisp by certain dates, and we cannot count on
having this code ready by then.  I prefer having a glitch.

Page 130: Has anyone got a reasonable algorithm coded up for
rationalize?  If not, this function must be flushed from the white

Page 131: I like "ceiling" and "trunc" as names.  Just perverse, I

Page 132: As noted before, the tolerance arguments to MOD and REM must
go.  These slipped into the language when I wasn't looking.  I'm not
sure where these came from, but if I had seen them arrive I would have
violently opposed them at the time; instead, I will violently oppose
them now.

Page 138: I, too, would like to see a redefinition of HAULONG and
HAIPART to fit better wtih two's complement arithmetic.  This change
should be accompanied by a change of name, since it would be no great
loss to consign the old names to the Maclisp compatibility package.

Page 141: Should random be passed an optional state-object explicitly
instead of looking at a special variable?  Seems cleaner.

Page 155: I agree that, if there were no precedents, EQL is a better
default test for the Sequence and List functions than EQUAL.  Maclisp
blew this by giving the good names to the EQUAL versions of things.
However, I consider it totally unacceptable for Common lisp to redefine
heavily-used functions like MEMBER to use EQL.  If we go to EQL as the
default, it is imperative that we find a new name for the MEMBER-like
function, and probably also for the DELETE-like function, so that MEMBER
and DELETE still do the old thing using EQUAL.  What about MEM and DEL
for the new versions?  With MEMBER and DELETE defined as special cases of
those.  ASSOC can continue to use equal, since the genric form will be
FIND with a key extractor.

Page 185: I have gradually come around to the idea that SETF should
replace most of the user-level updating functions, especially given the
problems with argument order in ASET.  I would keep the traditional
things like SETQ and RPLACA around, but wouldn't mind flushing ASET,
VSET, SETELT, SETNTH, and the ever-popular RPLACHAR and RPLACBIT.

Page 188:  I think that allowing multi-D arrays to have fill pointers is
a terrible idea.  Worse than terrible.

Page 189: If ADJUST-ARRAY-SIZE is going to work on multi-D arrays, its
arguments must provide new values for each dimension.  Trying to parcel
out a single new-size parameter among all of the dimensions is really
hideous.  For 1-D arrays and vectors, I have no problem with the
proposed form, though the descriptions could be made a bit clearer.

Page 209: I would put Eval and frined into the control structures
chapter, and DESCRIBE and INSPECT into the chapter on semi-standard

Page 213: We need a kind of stream that really passes the commands and
data to a user-supplied function of closure and another kind where the
user-supplied function gets the commands and supplies the data.
Probably the right way to do this is to pass the command (OUCH,
FLUSH-OUTPUT, or whatever) as the first arg to the function and the
evaluated args to that command as the &rest arg.  This is sort of flavor
like, but as long as we don't get into inheritance and mixing I have
objection to this.  That would give us enough rope to do all sorts of
weird I/O things.

Page 214: So, what about CHARPOS, LINENUM, and so on?  Build these in or
leave them to the user?  Clearly in some cases these things are

Page 234: Arrays???  I would like arrays not to print their guts by
default, or at least to be subject to something like prinlevel and
prinlength, or maybe a special print-array-guts switch.

Page 242: OUT must not constrain the user to sending out only positive
integers.  I think it would be best to ship anything that is NUMBERP,
truncating quietly if necessary.  If the user wants to check, let him do
it.  Remember that binary I/O is used for all sorts of godawful hacks,
and should not be surrounded by lifeguards.

Page 252: Y-OR-N-P and YES-OR-NO-P should both be moved to the chapter
on semi-standard stuff, since they have portable interfaces but are free
to get the question answered in a system-dependent way.  We also need a
general menu selection function of the same sort, but FQUERY is not
right for this task and should be flushed or moved to the yellow pages.

Page 259: I would like to see a more coherent description of the need for
:unspecific, or else flush it.  I also think that the filename objects
should contain a slot for system-type (UNIX, ITS, TOPS-20...) rather
than trying to derive this from the name of the host.

Chapter 23: This is not as far from what I would like to see as Guy
suggests.  I would suggest we eliminate error-restart altogether, along
with the flags in CERROR, and then go with this.  Of course, we need to
define a lot of built-in handlers as well.

Page 279: All of the compiler stuff should go into the semi-standard
stuff chapter as well: here is how you call the compiler, but what it
does is totally up to the implementation.  The COMPILE function needs to
say something about how it interacts with any lexical environment that
was around when the EXPR was defined.

Last chapter: A chapter is planned here that will describe things that
can be called from portable Lisp code, but whose actions are whatever
the implementor thinks is "the right thing" for his system.  Included
are things like TRACE, INSPECT, PPRINT, COMPILE, functions to get the
time of day and the runtime, Y-OR-N-P, etc.  Some of these will be done
very differently on systems with multiple windows, or with time-of-day
clocks, etc., but the idea is to provide a standard interface for
whatever is available.

-- Scott