THOUGHTS ON OTM

GOALS

	Maximum re-usability, not through recompilation (i.e. possibility to
	invoke super's implementation, unlike eiffel)

	Transparant object distribution (like Objective-C with NeXT's DO,
	unlike any other language)

FEATURES

	multiple behavioural inheritance, single state inheritance

	compile-time strong type checking, dynamic binding of dynamic types,
	static binding of static (== builtin) types.

	static types: char, short, int, long, float, double, (integer
	bitfields shorter than long), sequences of static types and objects.

	dynamic types: objects

	possibility of class extension and method redefinition.

TYPES

	The OTM data types are those a processor is designed to handle
	(called basic types), sequences of them, plus objects.

	There are no structs, unions or pointers.  This, of course, hampers
	writing device drivers in OTM, but drivers need to be too close to
	the hardware for the software to be abstract enough anyway.  The
	reason for omitting pointers are obvious.  Omitting structures
	prevents the struct value return problem.

	Question: Can the struct value return problem be avoided by type
	checking and by seperating `normal' and `struct' forward functions?
	The advantage of struct returning is that it can be used to
	implement multiple-valued returns (with things called tuples, not
	structs).

    BASIC TYPES

	The basic types are the integer and floating point types available
	on contemporary processors, such as 8, 16, 32 and 64 bits integers
	and 32 and 64 bits floating point values.  All basic values
	(i.e. values with a basic type) are signed.

    SEQUENCES

	A sequence is a collection of basic typed values or (pointers to)
	objects, which is indexable in a way natural to a processor.
	Sequences are provided to enable the fast manipulation of
	collections of basic typed values, mostly needed for I/O operations.

    OBJECTS

DYNAMIC BINDING

	Dynamic binding is _fast_.  Doing [rcv method: arg ...] is
	implemented as

	(rcv->isa->table[major (sel)][minor (sel)]) (rcv, arg, ...)

EXCEPTIONS

	The only allowed exception is something similar to calling abort ().
	Unless exceptions can be made to work while preserving (with check!)
	conditions and invariants.

CONDITIONS

	OTM supports preconditions, postconditions and invariants in much
	the same way as Eiffel.

	Question: Must it be possible for deferred methods (which lack an
	implementation within the declaring class) to specify conditions
	which must be met by all implementations of the method?  If this
	were resolved at compile time, adding a condition to a deferred
	method in a new version of a library does not automatically invoke
	the condition checks in not-recompiled code.

	Answer: Yes, but not by resolving it at compile time.

SEPERATE I/F and IMPLEMENTATION

	An interface defines the messages to which a class responds.  Since
	subclasses of state classes must know the instance variables layout
	of their super state class, the instance variables are also present
	in the interface.

	A class may be defined by more than one interface.  However, there
	must always be exactly one interface defining inheritance of a state
	class.

	Any method defined in an implementation must be declared in the
	interface of that class.  This is especially true if defining a
	deferred method.

	Question: Is it also true for defining a method already implemented
	by one of the parents?

CLASSES

	There are two kinds of classes: Those which define only behaviour of
	its instances and those which define state and (optionally)
	behaviour.

	Every state class, if it has ancestors, has exactly one state class
	among its ancestors.  All other ancestors are stateless.

	It is possible for a _class_ to inherit the _instance_ methods of a
	stateless class.  It is also possible for an _instance_ to inherit
	the _class_ methods of a stateless class.

OBJECTS

	A class is an object.  For each class, there is exactly one class
	object at any time.  Note that, in essence, the class object of a
	stateless class is itself an instance of some (unknown) state class.

	An object is an instance of a state class.

	Example:

	class Basic
	{
	  /* No class variables.  */
	}

	/* Allocate and return a new instance of the receiving class.  */
	(self) alloc;

	end;

	instance Basic
	{
	  private class (self) isa;
	  private int administration: some_bits;
	}
	end;

BINDING

	There are no functions.  Does this imply that really everything is
	dynamically bound?  For instance, equal-ity testing is a frequent
	operation, which should be efficient like eq-uality testing (using
	`==').  But the test can not be written as `[a equal: b]', since the
	receiving object `a' can be void.  Eiffel solves this by the `equal'
	and `is_equal' attributes.  The former would be written like `[self
	equal: a : b]', but would be expensive if dynamically bound every
	time.

	Thus, it seems ok for some methods which are closely related to the
	_language_ semantics (as opposed to the program or library being
	written using it) to be statically bound.  BUT we do not want to
	give the programmer the opportunity to specify his own static
	methods (other than through `protected').

	Maybe, it is okay for some behavioural classes to be fully
	statically bound.  These can still be extended, but method
	replacement is not allowed.  In fact, the static types are
	statically bound.

HIDING

	Instance variables can be `public' (available to all), `private'
	(available to subclasses) or `protected' (available only to the
	current class).  Public instance variables cause an implicit
	declaration and definition of an accessor method.  Private instance
	variables (the default) are actually accessed directly, whether in
	the declaring class or a subclass thereof.  Protected instance
	variables are accessed directly.

	Public instance variables declared to be `mutable' cause the
	implicit declaration and definition of a set method named `setFoo:'
	for an instance variable `foo'.

	Public and private class variables have the same semantics as
	instance variables.  Protected class variables are not inherited by
	subclasses.

	Question: Is this desirable?  Or do we want `normal' protected class
	variables and a special kind for the protected class variables
	introduced above?

	Methods can be public, private or protected.  Access restrictions
	are the same as for instance variables.  The default is public.
	Public and private methods are dynamically bound.  Protected methods
	first declared in this class are statically bound.  Methods
	protected by this class but implemented by a superclass are still
	dynamically bound.  (This triggers the system validity issue.)

	Question: Does one want the possibility to redefine the visibility
	of a method?  Yes, one does, see Eiffel, the book, par 22.6.
	Another question: Does one _need_ system validity?  Probably, yes,
	to keep all the static typing die hards happy.

METHOD REDEFINITION

	Class extension (like Objective-C categories) and method
	redefinition are an extremely important feature, because of the
	following, rather pragmatic, reason: They allow a programmer to fix
	bugs in a library he needs to use but for which the source code is
	not available.

	Method redefinition is possible and allowed, but the conditions,
	types and protection specified for the replaced method still apply.

	The order of building the runtime information of classes (and
	instances) is defined by the breadth first traversal of the
	inheritance graph.  But in what order does one apply extension
	definitions?

REPEATED INHERITANCE

	Repeated inheritance can only apply to stateless classes.

	Question: What are the semantics?  If already responded-to methods
	(by a superclass) are not overridden by the behaviour from the
	directly inherited repeated inheritance, the meaning repeated
	inheritance is void.

SYNTAX

	Apart from the information in the preceding paragraphs on syntax,
	the following applies:

	Identifiers are chopped strict case insensitive.  This means that
	foo is different from FOO, but equal to all other possible case
	mixtures.  This rule enforces consistent use of identifier names.

LOCAL GOTO'S

	Local goto's do exist but not explicitly.  The implicit local goto's
	are `break', `continue' and `return'.  The reason for allowing, for
	instance, break is to avoid having to write:

		int flag = 0;
		while (loop_condition && !flag)
		  {
		    if (some_condition)
		      flag = 1;
		    else
		      ...
		  }

	instead of simply

		while (loop_condition)
		  {
		    if (some_condition)
		      break;
		    ...
		  }

THOUGHTS

	Mutability and immutability part of the language?

	Static state classes?  These are statically bound and can not be
	subclassed.  Then one can write a device driver! (NOT.)  Na, too
	much trouble with GC, struct return, &c.

	We don't want pointers to pointers, but doubly linked lists are so
	nice with them for the backwards pointer!  (Only in C, not in, for
	instance, double conses in Objective-C).

	We'd like to be able to define methods like `numberWithInt' and
	`numberWithChar' without explicitly repeating the type in the name
	of the method.

PLAYGROUND

interface Number instance

/* Default return type is the type of the receiver.  */
infix *;

/* This equals the default return type.  */
self faculty;

end;

implementation Number instance

self
faculty
{
  if ([self < 2])
    = 1;
  else
    = [self * [[self - 1] faculty]];
} /* faculty */

end;
