[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Goals and Major Design Principles
Rather than immediately getting bogged down in technical design details
like how instance variables are accessed, I think we should try to
reach agreement on the goals of this effort and major design principles.
Here are some issues that I think are important:
* Hooks vs. Subset
One strategy that has been frequently mentioned is to define a collection of
primitive hooks upon which various objects systems can be implemented. From
the designers point of view, this is a wonderful idea, as it allows each
designer to do his own thing while we delay making any decisions. However,
this strategy fails to satisfy the need of Common Lisp USERS for a standard
definition they can USE to write code. So, while I support the (possibly
unrealistic) idea of a standard implementation base for objects, I think it is
more important that we attempt to come up with a usable "common subset" (in the
Common Lisp tradition) that is agreeable to the largest number of people.
* Start Simple
Because of the number of technical issues where substantial disagreement
appears to exist, we may have to restrict our definition severely to reach
agreement in a reasonable period of time. Given a choice between a severely
restricted definition (a "common subset") that appears soon versus a complete
and widely endorsed design that takes years to hammer out, I would recommend
the former as the more valuable. Certainly, it is easier to add new features
later than to change or remove features once they get into the definition.
* Multiple Objects Systems
The strategy of providing standard primitive hooks allows for the possibility
of supporting multiple coexisting objects systems. While there is merit in
this idea, I think our primary goal should be the definition of a single,
The Common Lisp objects system should be chosen to be efficient, particularly
on stock hardware, and usable on "small" machines. The efficiency goal argues
against including nonessential features in the standard that penalize all
message passing, regardless of whether the feature is used or not. (For
example, some features may require additional "hidden" arguments to method
functions.) The "small" machine goal argues against definitions that require
large run-time (as opposed to compile-time) data structures or on-the-fly
compilation. For example, one must be careful not to promise too much support
for incremental redefinition. A development system can always provide more
support than the definition requires.
* Avoid Exposing Implementation Details
To allow the most freedom to the implementor, and to allow future extensions
to the language, the objects system should avoid exposing implementation
details. In particular, it should avoid exposing the nature of any "hidden"
arguments to method functions, as these can vary based on the implementation
strategy and the features supported. This goal may preclude the definition of
a useful set of publicly-available primitive hooks.
* Relation to Defstruct
Unfortunately, any object system is likely to have a significant overlap with
Defstruct. We must consider reducing the redundancy, either by defining the
object system as a variant/extension of defstruct (ugh), or by flushing
* Messages to Non-Instances
It is desirable that messages can be sent to any Lisp object, not just
instances. Problems might arise if we attempt to allow users to define
methods for non-instances, particularly if we intend to support multiple
coexisting objects systems. Certainly, we would have to clearly define the
type hierarchy for the primitive types.
* Retroactive Changes
Once message passing exists in Common Lisp, many things could be redefined to
take advantage of it. For example, the stream functions could be defined in
terms of message passing, allowing users to define new stream types. How much
redefinition should be done?
In my opinion, a major design issue is encapsulation, meaning the ability to
separate the implementation of a "class" from its external interface, allowing
implementation changes that do not change the external interface to be
relatively transparent to users. Although encapsulation is claimed to be one
of the important features of object-oriented programming, the objects
languages that I have seen all fail to support encapsulation in their
definitions of inheritance. I am working on a proposal that fully supports
encapsulation, but in its present form I know it will be unacceptable to those
who take advantage of some of the less disciplined features of other systems.
This area is one where I would prefer to start with a conservative definition
(that does not destroy encapsulation) rather than immediately endorsing the
more powerful but less disciplined features.