[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Comments on Chapter 2
Comments on Chapter 2, draft dated Nov 11 1987 15:57 (when I checked
yesterday, this was still the most recent on SAIL). This is a mixture
of editorial comments and several comments on the substance of the
specification. I apologize for not having time to separate them.
2-3: It looks like this is the place for the disclaimer that says the
current version of chapter 2 doesn't try to be careful about the division
of labor between the generic functions it describes and their methods,
and that this will be revisited and revised when chapter 3 is finished.
2-3: The method signature example has &opt where it should have
&optional. The description implies that M is the name of a method,
whatever that is, but examination of method signatures in the text shows
that M is really the name of a generic function. Also in all the method
signatures, the text in brackets naming the kind of method should be
flush right.
2-5: cboundp, class-name, cmakunbound, and symbol-class aren't really
general Common Lisp support tools. I would move them to the "functions
underlying" table.
2-6: I find this notation inordinately confusing, but I don't have any
suggestions for improving it. I could suggest getting rid of the
extensions and using only standard BNF. That would mean that we would
not be able to specify in the BNF syntax restrictions that an item can
appear only once; that would have to be left to the text. If people
feel that editorially it's worth having that information in the BNF and
that therefore we need this idiosyncratic notation, I can live with it.
2-8 add-method arguments: I don't understand the reference to a generic
function not having a lambda-list. How is that possible?
2-9 call-next-method second dash bullet: "and there is no applicable
primary method" should be "and there are no more primary methods" or
words to that effect. Actually I'm not sure if these bullets are really
needed here, or if it would be better to leave all that stuff up to
chapter 1.
2-11 cboundp arguments: I'm not sure what "the null environment" this
refers to is. Since chapter 2 isn't really trying to explain how these
environments work (I assume we're going to do that in chapter 3?) maybe
it would be best not to say anything more than the analogy to &environment
in macros.
2-12 change-class arguments last sentence: (symbol-class symbol) should
be (symbol-class new-class) since the method signature uses new-class
as the parameter name.
2-15 class-changed: Since users can write methods for this, and this is
not a meta object generic function, we can't get away here with
obscuring the division of labor between the generic function and its
methods. This is explained pretty well in chapter 1 now, so the
explanation of what the standard primary method can be relied upon by
other methods to do can be lifted from there.
2-15 class-changed purpose: "evalued" should be "evaluated".
2-18 class-of purpose and values: There is a terminology problem here.
An object is an instance of only one class, we can't speak of the most
specific class of which the object is an instance. The terminology I
prefer is that an object "is a member" of the class of which it "is
an instance" and also "is a member" of each superclass of that class.
This comes from the use of "member" with types. I don't think chapter 1
has introduced that term, however; perhaps it ought to. The easiest
way to fix the writeup of class-of is simply to say "The function
class-of returns the class of which the given object is an instance."
It's for reasons like this that we need a glossary. Is the glossary
file on SAIL up to date? We should include it in the X3J13 88-002
document.
2-19 cmakunbound: see comment on 2-11
2-21 defclass syntax: generic-function-name is a bit trickier once
:writer is added here. For :reader and :accessor generic-function-name
is a symbol, but for :writer it's either a symbol or a list (setf symbol).
I suggest calling the argument to :reader and :accessor reader-function-name
and calling the argument to :writer writer-function-name. The next page
contains italicized words with no obvious referent other than this syntax
table, so don't forget to keep the next page consistent with any changed names.
2-23 defclass :initarg slot option: This paragraph refers twice to a
":initform argument". I think this is a typo for ":initform slot option."
2-23 defclass :initform and :default-initargs: The dynamic environment of
evaluation is the same for both of these, but the wording of the description
differs. I like the wording used with :default-initargs better and I suggest
that :initform be changed.
2-23 defclass :default-initargs option: An initialization argument name isn't
allowed to appear more than once in a single :default-initargs option, delete
the reference to that (second to last sentence).
2-24, 1-15: 2-24 defines exactly when defclass redefines a class, in
terms of the "proper name" concept. 1-15 is vague on this. We should
make sure the two chapters agree. What 2-24 says is what we want,
right? Editorial comment: the wording on 2-24 isn't so hot, because it's
a run-on sentence and because the word "class" appears enough times to
make my head spin.
2-24: With the introduction of :writer, occurrences of "accessor" on this
page should probably be "writer", since :accessor is now understood as
an abbreviation for :reader plus :writer.
2-26: I don't understand why method-specifier is a separate nonterminal.
With method-description, -specifier, and -qualifier, things get confusing.
Why not make method-description include the complete syntax directly?
method-specifier isn't referenced anywhere else.
2-27 last line: "proclain proclamation" should be "declaration
proclamation", "declaration" in boldface.
2-29 first line: This says that removing a :method from a defgeneric and
re-evaluating the defgeneric does not remove the old method. While that's
a good default behavior, we should make sure not to rule out smart program
development environments that know better what is going on and remove the
old method in cases where the user thinks that's appropriate. In the Error
Terminology introduced in chapter 1, implementations should be free to
extend this. Redefinition is a program development environment issue, not
really a language issue, anyway.
2-30 define-method-combination syntax: I guess this should be using that
double-bracket notation I said I didn't like for short-form-option and
for long-form-option. None of the options is allowed to appear multiple
times.
2-33 last line: Delete the word "argument", it's confusing to call the
doc-string an argument.
2-35, 2-36: The examples headed ";A simple way to try several methods
until one returns non-nil" are actually examples of trying several methods
until one returns nil. In addition, it's confusing that these are 'and'
method combination just like the examples on 2-34. "and" should be changed
to "or" throughout the four examples on pp. 2-35 and 2-36.
2-36 last example: It's probably better style to use length rather than
list-length.
2-37 defmethod purpose: Starting off the purpose discussion with lambda-list
congruence seems odd. Perhaps that paragraph should be moved to Remarks.
2-38 defmethod second remarks paragraph: This implies that equality of
parameter specializers is defined by the Lisp EQUAL function, but that
can't really be true. In an EQL parameter specializer, the objects are
compared with EQL, not EQUAL. There is no Lisp function that directly
implements the test for equality of parameter specializers. Of course
the function is very easy to write. I would just delete "(equal)" here.
2-40 describe purpose and method signatures: Requiring a method for the
class t is wrong. What CLOS actually requires is that for any object
that exists, there is always an applicable method. The language of
method signatures doesn't provide any way to say this, so I think we
should simply say that there is a standard-object method, and there are
enough other methods to ensure that there is always an applicable
method. Note that if there were a method on the class t, it would not
be able to describe anything about its argument, unless it started with
a type dispatch, since it could not know anything about the type of the
argument.
2-42 second bullet: Implementations should be allowed to extend the
set of symbols acceptable as the second argument to documentation, in
line with the error terminology outlined in chapter 1.
2-43 ensure-generic-function second arguments paragraph: "and and"
2-45 generic-flet syntax: In the list of suggested changes he handed
out two years ago, Guy Steele suggested allowing declarations before
the body of flet, labels, and macrolet. The cleanup committee doesn't
seem to have picked up on this (I checked the latest issue status list
I had, which is only a month old). If FLET and LABELS change, of course
GENERIC-FLET and GENERIC-LABELS should change too, so we need to stay
on top of this. If I get a chance I'll send a cleanup reminder.
2-46, 2-47, 2-49: See comment on 2-26.
2-47 generic-function syntax: This takes the same restricted lambda-list
as defgeneric, generic-flet, etc. so the syntax for that should be
copied here. Alternatively the cross-reference under Arguments could
be updated, but that isn't the style in which generic-flet was done.
2-49 generic-labels syntax: See comment on 2-45.
2-51 get-method remarks: See comment on 2-38. Qualifiers are compared
with EQUAL, but specializers have to be compared a different way.
2-52, 2-53, 2-54 initialize-instance: The stuff about
initialize-instance methods on various meta object classes should be
moved into chapter 3. Also it contains some errors, for instance the
methods are :after methods, not primary methods, I'm fairly sure.
2-54 initialize-instance values: I think the value should be a don't
care, since that's what 1-43 implies. Why run the risk of someone
writing a method that returns the wrong value?
2-56 invalid-method-error: This function should not be generic. It
was not generic in the last version I reviewed; I don't know how
genericness accidentally crept in. Once the genericness and method
signature are removed, the rest of the writeup is okay.
2-57 make-instance: The method signatures for standard-method and
standard-generic-function are mistakes and should be removed. The stuff
about making instances of these classes in the remarks section should
be moved to chapter 3. By the way, I believe that the initialization
arguments for a class should be documented with the class, rather than
lumping all classes together under initialize-instance and make-instance.
Right now chapter 2 doesn't document any classes, but certainly chapter
3 will include pages for several classes.
2-58 make-instance first remarks paragraph: boring.
2-59 make-instances-obsolete second purpose paragraph: Cross out
"newly-redefined"; it might not be if the user called the function
explicitly. In the last sentence, change "may" to "will"; once
make-instances-obsolete has been called, it is guaranteed that
update-instance-structure will be called on each instance some
time before the next time a slot value of that instance is accessed.
2-59 make-instances-obsolete second arguments paragraph: Cross out
"symbol and".
2-65 no-applicable-method: I'm not sure that the default method should
be on standard-generic-function, rather than generic-function or t.
Why would we want the default method to be on a more specialized class?
2-66 print-object: See comment on 2-40.
2-68 remove-method method signatures: I don't think the second parameter
should be specialized. I think there are a few other generic functions
in here whose method signatures are overzealously specialized. Only
chapter 3 knows for sure, of course, but it seems to me that most of
these should accept any value for arguments other than the main
specialized one.
2-72 slot-missing method signatures: As on 2-65, shouldn't the default
method be on a less specialized class?
2-73 slot-unbound method signatures: see comment on 2-72
2-74 slot-value second remarks paragraph: The fourth argument to
slot-missing in this case is the symbol setf, not the list
(setf slot-value).
2-75 symbol-class last arguments paragraph: see comment on 2-11
2-76 symbol-macrolet second remarks paragraph: clarify that
symbol-macrolet can be shadowed by let. In other words, symbol-macrolet
only substitutes for occurrences of -symbol- that would be in the scope
of a lexical binding of -symbol- surrounding the body. Also
symbol-macrolet does not substitute for occurrences of a -symbol-
inside an -expansion-. Illustrative examples:
(symbol-macrolet ((x 'foo))
(list x (let ((x 'bar)) x))) => (foo bar), not (foo foo)
and ==> (list 'foo (let ((x 'bar)) x)), not
(let 'foo (let (('foo 'bar)) 'foo)).
(symbol-macrolet ((x (1+ x)))
(print x)) ==> (print (1+ x)), not (print (1+ (1+ (1+ ....
2-77 update-instance-structure second purpose paragraph: Since users can
write methods for this, and this is not a meta object generic function,
we can't get away here with obscuring the division of labor between the
generic function and its methods. This is explained pretty well in
chapter 1 now, so the explanation of what the standard primary method
can be relied upon by other methods to do can be lifted from there.
Also change "evalued" to "evaluated".
2-77 update-instance-structure: change "deleted-slots" to "discarded-slots"
to be consistent with 1-16. Slots that used to be local but are now
shared are included in the discarded-slots.
2-78 update-instance-structure example: In two places in the first
defmethod, "new" should be "pos". Also the comment was erroneously
copied from a class-changed example and a new comment is needed
saying something like transform the coordinates to polar and store
into the new slots. Use of with-slots in the example needs to be
updated to the new with-slots syntax. Also the indentation could
be standardized, some things are indented one space where the style
used everywhere else would have them indented two spaces.
2-80: See comment on 2-26