## oop.pkg
# Compiled by:
#
src/lib/std/standard.libpackage oop: Oop { # Oop is from
src/lib/src/oop.api fun identity x = x;
# We use this type and value to
# represent the subclass state
# of a class when there is in
# fact no subclass/substate:
#
Oop_Null = OOP_NULL;
# These two are from Bernard Berthomieu's
# "OOP Programming Styles in ML" Appendix 2.1.1:
#
# The idea here is that if we have a four-deep
# class hierarchy, instances of the leaf class
# contain state declared by that class plus
# state declared by all three ancestral classes,
# which we represent by nested tuples like so:
#
# ( root_class_state,
# ( next_class_state,
# ( next_class_state,
# ( leaf_class_state, oop::NULL )
# )
# )
# )
#
# The local state of each class consists of a
# (state, substate)
# pair where "state" is the local state for this
# class and "substate" is the chain of tuples
# recording the state records of our subclasses,
# with the oop::NULL value being used essentially
# as a NULL pointer to tie off the tuple-chain at
# the leaf end.
#
# Code from any particular class only directly manipulates
# its local state, so we need a way to extract that local
# state for manipulation and then later reconstruct the
# complete nested-tuple sequence constituting the full
# object state.
#
# We do this via recursive calls, each class talking directly
# only to its superclass. Each class exports an "unpack"
# function for extracting the local state of its subclass
# and a "repack" function for doing the reverse, folding
# the possibly updated subclass local state back in.
#
# The following two functions are convenience functions
# used in implementing such unpack/repack functions.
#
# The "repack" function updates our local state via a
# provided "update_state" function and then recreates
# the full object state tuple-chain via the "repack"
# function:
#
fun repack_object update_state (repack, (state, substate))
=
(repack (update_state state, substate));
#
# Our "unpack" function implements most of the functionality
# needed by the class "unpack" functions. It extracts the subclass
# state record "substate" while creating a repack function
# which knows how to to recreate the object.
#
# The return value includes both the recreation function
# and the extracted "substate" record:
#
fun unpack_object (repack, (state, substate))
=
( \\ new_substate = repack (state, new_substate), # Create 'repack' fn for our subclass.
substate # Always a (state', substate') pair.
);
# For the Phase II oop approach we're using REF cells
# to distinguish objects of one class from another.
# REF cells are equal to themselves and unequal to all
# other REF cells, so by marking all members of a given
# class using the same REF cell we can make the required
# distinction.
#
# We never get or set the value of these
# REF cells; we are only interested in the cells themselves,
# not their values.
#
# Here we establish a "null pointer" REF cell to put in
# unused "my subclass is ..." slots:
#
no_subclass = REF 0;
};