There is a reason, of course, but it is not in ANSI nor AMOP, because
these standards hardly address the issues of a development environment.
Both warnings are hints that something is wrong with the source code.
It's a hint that the order in which program files are loaded (order
of definitions, order of macro expansions, or similar) is wrong.
(defclass ware () ())
(defclass book (ware) ())
(defclass cd (ware) ())
(defclass dvd (ware) ())
(defgeneric add-to-inventory (object))
(defmethod add-to-inventory ((object ware)) nil)
(defvar *bible* (make-instance 'book))
(defvar *book-counter* 0)
(defmethod add-to-inventory ((object book)) (incf *book-counter*))
(defvar *harry-potter-7* (make-instance 'book))
*book-counter* => 1
Since the bible and the harry-potter book were already added to the
inventory, the programmer might have expected that *book-counter* is 2.
It's a hint that different parts of the program, possibly developed
by independent people, are colliding.
Example: same code as above, then additionally:
(defgeneric sell (object price))
(defvar *book-sales-statistics* (make-hash-table))
(defmethod add-to-inventory ((object book))
(let ((stat (gethash (book-title book) *book-sales-statistics*)))
(unless stat (setf stat (make-stat)))
(stat-add stat 1 price)
(setf (gethash (book-title book) *book-sales-statistics*) stat)))
The programmer who programmed the first add-to-inventory@book
method expects that *book-counter* will be incremented. The programmer
who programmed the second add-to-inventory@book method expects
that *book-sales-statistics* gets augmented. If the implementation
gives no warning, one of the two programmers will waste time debugging.
That was the pragmatic, development-driven reasoning. The theoretical
reasoning behind it is as follows:
A generic function is defined by a contract. Whoever puts a method on a
GF, however, is also expecting a contract to be fulfilled. (In the
example above, it is that *book-counter* equals the number of invocations
of add-to-inventory on book instances.)
If the GF was already called before the method was installed, the
method's contract was definitely broken. Maybe the programmer has
foreseen this case (in this example: he could initialize *book-counter*
to the number of instances of book that exist at this moment, rather
than to 0), or maybe not. This is what the warning is about.
This warning can be warranted for the same reason as 1): If the old
method and the new method have a different contract, something is fishy
and possibly wrong, as in 1).
Additionally, the programmers may not even have intended to replace the
method. They may have intended cumulative effects of the two methods.
Of course, there are GFs, like PRINT-OBJECT, for which particular methods
have no different contract than the GF contract. On these GFs, the warnings
are pointless. But these GFs are a minority.