HELP LIKE_FLAVOURS                             Steve Knight, August 1990

This note compares LIB FLAVOURS with LIB OBJECTCLASS.  This comparison
is summarised by the following table and discussed in more detail in the
following sections.

 -- Summary
 -- Incremental Compilation
 -- Efficiency
 -- Integration
 -- Inheritance
 -- Mono Vs Multi Methods
 -- Technique for Extending Methods
 -- Meta-Class Support
 -- Method Hiding
 -- Other Facilities
 -- Further reading

-- Summary ------------------------------------------------------------

Category                    Flavours                Objectclass
--------                    --------                -----------
incremental compilation     excellent               good
efficiency                  good                    excellent
integration with keys       not integrated          good
type of inheritance         multiple                multiple
method-dispatch             mono-method             multi-method
method-extension            before/after daemons    run super method
meta-class support          good                    minimal
method hiding               none                    good

-- Incremental Compilation --------------------------------------------

The problem addressed here is the fact that class definitions can be
compiled several times in the course of a programming session.  Usually
those definitions will remain unchanged but occasionally there will be
an alteration.  This raises a couple of difficulties -- how to react to
recompilations and what to do about instances of obsolete classes. How
do the different OOP systems cope with this?

Flavours takes the approach of maximum flexibility.  A flavour
definition is treated like a re-entract environment.  When new instance
variables or methods are added to a flavour, all instances of that
flavour immediately see the effect.  The cost of this is twofold.
Firstly, keeping instances up to date requires an extra level of
indirection which costs both in store and in time since compile-time
knowledge cannot be exploited.  Secondly, when extra fields are added to
a flavour the initialise method is not re-run and the new instances can
be corrupted.

Objectclasses takes a compromise route -- adopting the exact policy used
by recordclass and defclass.  Recompilations of unchanged class
definitions have no effect.  However, when a class-definition is
changed, a new class is allocated.  This has the benefit of never
corrupting existing objects at the expense of never being able to update
them.

The objectclass policy is less flexible and does not respect the demands
of an incremental environment as well as the flavours policy.  However,
the experience of using recordclass and defclass show that the trade-off
of some flexibility for extra efficiency is a viable one.


-- Efficiency ---------------------------------------------------------

The Flavour's system method-dispatch policy suffers from performance
problems in many areas.  By contrast the Objectclass system generates
methods that are almost as efficient as hand-written code.  (In fact,
occasionally more efficient.)

Flavours addresses some of these problems by providing special syntax
for accessing instance variables and methods in more efficient ways.
There are even different categories of instance variables (ivars,
divars).  All of these ideas work at the expense of exposing the
implementation policy for a given class.

Another approach used by the Flavours system is to cache the last
dispatch lookup.  This provides a significant improvement in performance
for certain programs.

The superior performance of the Objectclass package can be attributed to
the fact that class-structure is immutable.  This is exactly the same
benefit that accrues to the existing *KEYS system in Pop11.  There is
additional complexity caused by the need to re-link methods (and the
super-methods hierarchy) on the fly but these impose only a small
cost-overhead.  (They were a pain to write.)

Rough measurements suggest that the overhead associated with a
method-dispatch in the Flavours system is between 5-20 times higher than
that for the Objectclass system.


-- Integration --------------------------------------------------------

The flavours system sits apart from the ordinary world of Pop11
datatypes. Flavours are not keys and instances are not records or
vectors.  On the other hand, within the methods of the flavour system
ordinary Pop11 code and data structures can be used.  On the other hand,
method invocation is not the same as ordinary procedure application, so
it isn't possible to use familiar control abstractions such as applist
an appdata with methods.  In short, the flavours system is an
upward-extension to the Pop11 language.

The objectclass package, by contrast, was explicitly designed to
smoothly integrate with the existing Pop11 data types.  This design
criterion led to the decision to represent classes as keys, methods as
procedures, and instances as records.  This choice means that ordinary
Pop11 idioms fluidly extend to objectclass programming.  Furthermore, by
sticking to this model powerful programming constructs such as sections
and lconstant declarations properly extend to all aspects of the
objectclass package.  This is not true of the flavours package.

Furthermore, the objectclass package incorporates a mechanism to include
previously built datatypes into the objectclass view of the world.  This
backwards-compatibility mechanism (extantclass) is only partially
effective because many Pop11 variables are compiled as constants.  In
these cases, it is not possible to redefine field-accessors in the way
you might wish.  However, within this restriction, extantclass does the
job.

The value of integration is hard to assess.  However, the objectclass
package clearly shows one possible evolutionary road for the Pop family
of languages.


-- Inheritance --------------------------------------------------------

Both flavours and objectclass embrace multiple inheritance, although
they tackle the inevitable complexities rather differently.  The
flavours system provides an "escape hatch" for when the built-in
inheritance strategy proves problematic -- the meta-flavours.  By
contrast, part of the objectclass manifesto is proper encapsulation
which means that its inheritance strategy is fixed.  (Any other strategy
exposes the implementation of classes when they are used as parents.)

In addition, methods have to properly and efficiently dispatched.  This
is complicated in the presence of multiple inheritance.  The crucial
different between the two systems is that the flavours system can only
dispatch on a single argument whereas the objectclass system permits
method dispatch on multiple arguments.  This is covered in detail in the
next section.


-- Mono Vs Multi Methods ----------------------------------------------

The flavours system identifies method-invocation with "message-passing".
 This means that each method is dispatched on the basis of a message
that characterises the method.  In the case of the flavours system, this
is a Pop11 word.  This suffers from two basic problems: methods don't
interact properly with sections and some methods need to distinguish the
types of several arguments.

On the other hand, the "mono"-methods choice has the advantage of
associating methods with a particular class.  This provides a nicely
integrated explanation of inheritance based around the inheritance
hierarchy. Another advantage is that within a method the
instance-variables can be made available as variables, since one of the
arguments (self) is special.

The objectclass system uses the multi-methods system, popularised by
various Lisp-based object systems, including CLOS.  This system has the
disadvantage of needing a relatively complex explanation for
method-shadowing.  On the other hand, it subsumes the mono-method
approach and provides for general method-dispatching.  The objectclass
solution also solves the problem of integrating with sections, since
methods procedures which are bound to ordinary variables.

It is occasionally argued that multi-methods incur a cost-overhead.  The
objectclass package is specially designed to avoid this.  Although
dispatching on several arguments inevitably takes longer than
dispatching on a single argument, the objectclass package does not incur
any overhead when the multi-methods facility is not exploited.  (In
short, you only pay for what you use & what you use is cheap in any
case.)

The multi-methods model of the objectclas package is more general and
integrates more nicely into the Pop11 procedural programming model.  In
fact, writing a method is exactly like writing the class-apply of a
recordclass. However, the argument is not one sided, since flavour's
methods are easy to understand and can conveniently refer to instance
variables and this is quite an attractive feature.

(As a point of interest, this convenience feature was deliberately
rejected in the objectclass package because it leads to a loss of data
abstraction. Using it means that the method being defined is exposed to
the implementation of instance variables as slots or methods.  This
causes lots of problems when the implementation of the object is changed
which is supposed to be easy with OOPS.)


-- Technique for Extending Methods ------------------------------------

The Objectclass package provides the most common and popular way of
extending methods -- you are able to invoke the super-method by calling
-call_next_method-. This is implemented very efficiently in the
Objectclass package by a smart-linking technique.

In the Flavours package, you extended a method by adding before or after
demons.  These demons did not obey the usual inheritance rules so that
it was impossible to redefine a method and prevent the demons being run.
 As a consequence, it was not always safe to think of adding a demon as
extending a method in the same way.

The inability to safely extend Flavours methods was one of the primary
factors in the decision to create an alternative OOPS in Pop11.


-- Meta-Class Support -------------------------------------------------

The meta-class support provided by the Flavours system is comprehensive
and excellent whereas that of the Objectclass system is virtually
non-existant. However, the requirement for meta-class support in the
Objectclass system is not especially great -- partly because of the
presence of multi-methods. Multi-methods reduce the importance of
meta-classes considerably.

For example, since multi-methods in the Objectclass system can be
specified without any class tagging, there is no need for a
vanilla-class.  Since there is no vanilla-class, there's less need to
create a new class hierarchy.

The other main use for meta-classes, which is to alter the inheritance
hierarchy, also does not apply in the Objectclass system.  (See the
previous section on the important of correct inheritance in providing
encapsulation.)

However, it is probably still true that the higher levels of the class
system could be improved.  Since the Objectclass package mirrors the
keys-system of Pop11, this is unlikely to be easy to provide.


-- Method Hiding ------------------------------------------------------

Since the objectclass package uses ordinary identifiers all the time for
all of the entities, it works perfectly with the Pop11 sections
mechanism.  In particular, methods can be hidden using the sections
mechanism.  The flavours package doesn't provide any form of method
hiding and since methods are actually represented by words you cannot
use the sections mechanism to implement this.

The objectclass package can also exploit the lconstant and lvars
declarations to achieve the effect of method hiding.  The flavours
package can't use this mechanism either since methods are not associated
with variables but words.


-- Other Facilities ---------------------------------------------------

It should also be added that Flavours is a more developed and  mature
system than Objectclass at the time of writing.  It provides a
number of additional "peripheral" capabilities which have no direct
analogue in Objectclass.  This section tries to list some of these areas
where the packages differ.

Dynamic Instance Variables
    Flavours provides a way of dynamically localising instance variables
    so that they are accessible outside the scope of a method.  This
    solves a nasty problem raised by the fact that methods are different
    semantic entities from procedures with different scoping rules.

    There is no directly corresponding facility in Objectclass and
    neither is there any need for it.  The same effect is achieved by
    dlocalising arguments of a method.

Behaviour Enquiries
    In Flavours it is possible to enquire about the behaviour of any
    instance at run-time using the method -willrespondto-.  This ability
    requires retention of the method structure at run-time which is
    direct opposition to the Objectclass approach of discharging all
    work at compile time.

    A similar effect can be achieved by dynamically localising method
    failure.  So the typical uses of -willrespondto- in Flavours can
    be simulated by -failsafe- in Objectclass.  However, the full
    power of -willrespondto- can only be effected by using -method_path-
    which inhibits optimisation (see below).

Optimisation at Delivery Time
    In Objectclass, special attention was paid to the issues of being
    able to deliver applications.  As a consequence it is possible to
    force the compilation of methods and junk run-time tables prior
    to the ultimate syssave.  The procedure -optimise_objectclass-
    provides modest control over the internals relevant to delivery.

    This contrasts with Flavours in which no controls have been
    provided.  There's no reason to suppose that this feature couldn't
    be grafted onto Flavours, of course.

    One issue that's carefully pinned down in Objectclass is the
    ability to destroy the run-time method tables.  This is only
    safe if no class/method creation happens at run-time.  As a
    consequence, the programmer is warned if there is a conflict and
    can override the warning if appropriate.  This ability is of
    considerable practical importance, since it reduces the storage
    of methods to zero.


-- Further reading ----------------------------------------------------

HELP * FLAVOURS             an overview of flavours
HELP * OBJECTCLASS          an overview of the objectclass system

-----------------------------------------------------------------------


--- C.all/lib/objectclass/help/like_flavours
--- Copyright University of Sussex 1993. All rights reserved.
