19.9 Open generic functions
By default, generic functions are sealed. When you use define generic, that is the same as using define sealed generic. No other library can add methods to a sealed generic function — not even on new classes that they may introduce. Methods cannot be added to, or removed from, the generic function at run time. The only methods on a sealed generic function are the methods that are defined in the library where the generic function itself is defined. Because of the restrictions on a sealed generic function, the compiler, using type-inference information, can usually narrow the choice of applicable methods for any particular call to the generic function, eliminating most or all of the overhead of run-time dispatching that would normally be expected of a dynamic language.
We saw in Chapter 13, Libraries and Modules, that we must define a generic function that is part of a shared protocol using define open generic, so that libraries sharing the protocol can implement the protocol for the classes that they define, by adding methods. If we do not define the generic function to be open, other libraries are prohibited from adding methods to the generic function, which would make it useless as a protocol. Unfortunately, a generic function that is open cannot be optimized. Even when the compiler may be able to infer the exact types of the arguments to the generic function in a particular call, because an open generic function may have methods added or removed, even at run time, the compiler must produce code to handle all these possibilities.
Because open generic functions cannot be optimized, you should use them only when necessary. You need to balance the division of your program into libraries against the need to export and open more generic functions if the program is too finely divided. This balance is illustrated by the considerations we made in designing a protocol in Section 13.9, page 214. When we chose to split the time and angle libraries, we were forced to create the say protocol library and open the generic function say. In Section 19.11, we show how to regain certain optimizations when you decide that opening a generic function is required.
Note that generic functions that are defined implicitly in a library — such as those that are defined when you define only a single method, or those that are defined for slot accessors — are sealed by default. If you expect other libraries to add methods to one of these implicit generic functions, you must define the generic function explicitly to be open using define open generic.




