binary operator support for evolvers

4.25: adda/oop/biop'support for evolvers:

. unlike polymorphs such as type"number,
when an evolver gets a biop (binary operation),
it doesn't have a type'mgt that knows
who all its subtypes are,
so it doesn't know how to do conversions,
and can't delegate a biop call
to a particular subtype .

. one approach, though not generalizable,
is to have all biop methods be defined by
the root type,
and defined in terms of unary operations .
. all evolutions of that root type
would then inherit a working biop,
even if they had defined their own unary op's .

. the unary op's should provide code too,
just to be consistent?
ie, evolver subtyping involves complete impl'inheritance ?
. it should be up to the individual root.type
as to whether or not it chooses to
share a given method;
but if it wants the biop's to work
the way they do for polymorphs,
then it will provide the methods for all biop's .]

. a dynamic scripting approach,
like one might expect from a lisp system,
would be where all evolutions or subclasses
are allowed to read and modify
a supertype's biop-managing script .
. a subtype would register itself
and complete a table:
subclass x subclass x biops;
or, do whatever other rescripting was needed
in order handle the various combinations of subclasses
that are sent a biop message .

. a strategy for how to design evolvers
is to keep in mind why inheritance is good here:
it offers a form of type-checking
along with interface-based programming .
--[4.29: it offers nominal in addition to
structural subtype polymorphism (generics).]
. generics is when any type will do
if it supports the same interface
(I call these typeless obj's "(generals)).
. nominal type checking includes
the given type'name and all its descendants .
. the type'tag points to type'mgt
which is a node in a tree (or lattice);
that node has ptr's to all sources of inheritance .
. the 2 arg's of a biop must share
one or more supertypes,
and one of the supertypes must support that biop .
. if more than one?
[4.29: as when using multiple ada`packages,
the biop could be qualified to indicate
which node in the type.class lattice
the operation should be executed by .]
[4.30: qualifying an infix operator
could look rather confusing;
another option is raising an exception when
multi-inheritance is getting ambiguous .
. Ada05 allows multi-inheritance only with
interfaces (methods are not inherited,
and there's no concept of a biop).]

4.29: adda/oop/evolvers supporting biop's:

. what if an evolver wanted to inherit from a polymorph?
as long as adda promotes generics or interfaces .
. inheritance that expresses a
nominal subtype polymorphism
may not be good for contract-based prog'ing:
. types that support the same interface
could be modeling very different things;
so there should be a distinction made between
whether the model or the interface is supported .
eg, when I say the formal is a number,
I probably don't mean
the assigned obj'should do clock arithmetic
-- even if the interfaces are the same .]

. how does it support biop's ?
it needs to ask both arg's who their type'mgt is,
and see if they have a common superclass,
then see if any of them have a method for that biop .
but, num is a closed type, (not an evolver):
the biop it supports is not tolerating any
unrecognized subtype names .

. similar to the idea that there are
separate inheritances for interface and impl',
not every interface inheritance
has to imply the type is compatable with
the one it inherited from .

. just as polymorphs have some way of cooperating
in order do binary operations on various subtypes,
the evolvers need some universal way of describing value:
ie, the one job of the root.type
is having a way to define the supported values
in terms of some composition of public types;
[4.30: ie,
a subtype doesn't have to reveal how it stores a value,
but it does need to support exporting of a value
in some public form,
similar to offering a printed version
but instead of exporting as text,
it would be an efficient binary form .]
. for example,
number could describe its polymorphs
as an evolver would:
instead of subtypes knowing each other
and providing conversion routines,
the root.type, number,
could define a record of integers
(or a pointer to symbol in one case)
that describes all the parts of any number:
( mant'int#, [irrational]/ -- mantissa
, mant'frac'numerator#
, mant'frac'denominator#
, exp'int#, exp'frac# -- exponent
, sign'int#, sign'frac# -- large for complex numbers .
); [4.30:
. for types that are not numeric,
the root.type could express itself as
some tree of certain classes of symbols,
like the way english can be described,
with a grammar and a vocab' .]

. is that idea useful for the problem of
integrating popular notions of oop with biop's?

. the obj'c oop is assuming privacy from
even subclassers, not just clients;
therefore, any biop's must be defined in terms of
the superclass's unary op's .
. as shown by class"numbers,
there will be situations where only a
universal value format will be useful:
the biop will ask both arg's
to convert themselves to universal,
and then after working on a pair of univerals,
the biop can ask the receiver
to convert the universal to the type prefered;
[4.30: ie, within an evolver class,
one of the subtype's assignment functions
is expected to accept a universal-formatted value .]