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

1st pass comments on Art of MOP

Hi.  I still haven't finished reading the whole book, but I thought
you might want to see my comments before it's too late.

In general, the book is pretty good--it's reasonably clear and easy to read.
I'm going to see if I can get some of the traditional-language compiler
people around here to appreciate the issues, and this presentation is a
good one.

Although I've noticed that some of this is addressed in Chapter 4, which I
haven't read yet, I'd like to state that compile-time/optimization issues
are important and interesting, and that I'm disappointed that this book
doesn't devote more time on that.

The following is a log of all of my comments as I read.  Some of the
questions were answered later on, but I've left them in so you can consider
adding some commentary that would make the exposition a little clearer.

Intro: Why require explicit defgeneric before defmethod?  I assume it's just
    because of simplicity of exposition, not because of difficulty of
    implementation.  The rest of the restrictions seem pretty reasonable.

1.3 No justification for why cacheing class precedence list & all slots
    in standard-class, but not other information, such as all effective
    methods or the like

1.3 p11 & 1.5 p29 functions other than the defclass and defgeneric macro
    are not "available to users" -- but they are part of CLtL/X3J13 CLOS.
    Probably need to mention that some CLtL/X3J13 CLOS functions are really
    part of the MOP.

p12 "that it true" should be "that is true"

p13 Why bother confusing reader with "address" of standard-class instance?

p17 Someone could ask "Well, gee, why use after method on initialize-instance
    for standard-class?  Why not just insert in ensure-class?"
    Already starting the process of generalizing the implementation
    needs better justification.
    Maybe the implementation shouldn't use CLOS at all in Chapter 1?
    That would really drive the point home better.

1.3.4 To continue the "recursive descent" exposition, describe compute-class-
    precedence-list in detail before compute-slots, rather than the other
    way around

p22 How to associate slot-name <==> location?
    Is local-slot-location really part of std-instance definition?

p26 Stylistic issue: '() to indicate empty list instead of just () would
    be clearer

p31 Mention that you're ignoring the case that a regular function is already
    defined for the function name

p32 Missing (BLOCK 'PAINT ...) around body in fig 1.5

p34 Mention that there's no checking that lambda lists agree

    Why separate the lambda-list, body, &environment, when storing #'(lambda
    (...) ...) would avoid the problem?

p41 [p34 comment continued, as it turns out]
    Adding call-next-method & next-method-p is part of the justification;
    but couldn't this have been done another way? (e.g. FLET and special

    EVALHOOK could be used instead of a mythical EVAL with environment arg

p43 "The classed named" should be "The classes named"

p50 "==>" looks too much like the "evaluates to" symbol of CLtL, rather than
    like a prompt

p51 Why is convert-to-string needed? isn't class-name always a string?

p57 "latter label a" should be "latter labels a"

p59 "the presense of" should be "the presence of"

p62 "each generic function has at least one method" ? no

p69 Two periods after "don't provide.." should have only one period

p72-73 Another goal: avoidance of duplication of mechanisms--encourages using
    standard CLOS for implementing itself

p81 Last paragraph--why not depend on whether it's a rainy Tuesday?

p82 "with the class metaobject for standard-object and t coming at the end"
    should be plural: "class metaobjects"

p86 Where did it say that users couldn't redefine system-defined classes?
    Sure, one can easily outlaw defmethod compute-class-precendence-list on
    standard-class, but how is new programmer supposed to know where the
    line is?  "standard" in the name?

p88 "non-empty list of ... metaobject" should be plural: "metaobjects"

general: Does every function that is in the "public" metaobject protocol
    need to be a method?  What about internal functions?  Of course not,
    but how does one decide?  [maybe this is discussed in Chapter 4...]
    I'd hope there were some specific principles rather than responses to
    the needs of individual applications as they came along.

p103 "by not replaced" should be "but not replaced"

p108 allocate-instance on standard-class: why no override?  But that's what
    we want!

    "Slots marks with" should be "Slots marked with"

p111 Gotta setf (gethash ...) with value of delete

p112 Missing spaces in "make-instanceandinitialize-instance"

    "information this is" should be "information that is"

[haven't read Chapter 4 yet]

p143 evalhook allows use of env for eval

    another reason why not: overhead: time & space

I tried the Closette implementation on VAX LISP V3.1 and have a few comments:
(1) It basically seemed to work
(2) The address of an allocated object can be determined by (SYS::ADDRESS-OF x)
    It can be read-time conditionalized by #+:VAXLISP
(3) The compiler blew up trying to evaluate the call to (EXPORT EXPORTS),
    because EXPORTS wasn't defined.  I put an EVAL-WHEN (COMPILE LOAD EVAL)
    around the DEFVAR of EXPORTS.
(4) The compiler blew up because CANONICALIZE-DIRECT-SUPERCLASSES wasn't
    defined.  So I gave up and loaded the source file first, and then
    compiled closette.  This worked, so the change I made in (3) isn't needed.
    A comment to the effect that you might need to load the code before
    compiling would be welcome.
(5) There were a lot of warning messages from the compiler about variables
    being bound but not used, during bootstrapping.


BTW, note that my address is now  @tle.enet.dec.com, not @aitg.enet.dec.com.