1.15: 6.12: adda/oop/multi-object modifications:
. the object notation: "( object`operation )
is saying that the given object is modifying itself;
whereas, if no modification was expected,
the preferred syntax would be "( operation(object) ).
Showing posts with label polymorph. Show all posts
Showing posts with label polymorph. Show all posts
2014-06-12
2010-04-30
structural subtype polymorphism
4.25: adda/oop/structural subtype polymorphism:
. in addition to polymorphs and evolvers
there are generals, where type is not named;
instead,
the given obj' must support the same operations
as expected by the formal symbol
that the obj' was assigned to;
and, in order to show
where it's getting this support from,
the obj' must carry a type.tag;
this would be in addition to
a possible subtype tag that the type'mgt would use
to discriminate between a polymorph's subtypes .
. in addition to polymorphs and evolvers
there are generals, where type is not named;
instead,
the given obj' must support the same operations
as expected by the formal symbol
that the obj' was assigned to;
and, in order to show
where it's getting this support from,
the obj' must carry a type.tag;
this would be in addition to
a possible subtype tag that the type'mgt would use
to discriminate between a polymorph's subtypes .
polymorphic vs evolutionary subtyping
4.23: adda/oop/polymorphic vs evolutionary subtyping:
. the crux of subtyping is being
compatable with multiple types;
structural subtyping is allowing compatability between
any interfaces that share operations having
the same name and parameters;
nominal subtyping is where compatability is declared:
a subtype is compatible with its supertype
because it defined itself as supporting that supertype .
. the 2 types of nominal subtyping
are tentatively named here:
polymorphic subtyping, and
evolutionary subtyping .
. the term polymorphic refers to a single genome
that results in individuals of varying form;
eg, drones, queen, workers .
. evolution is about extending the capabilities
that were inherited .
. when considering the design of syntax for oop,
I noticed a difference between
{polymorphic subtyping (polymorphs)
, evolutionary subtyping (evolvers)
} that would cause their syntax to differ:
. the polymorphs are exemplified by the numbers,
which include the subtypes {Q,R,N,Z,C,...}.
. an obj' of type"number needs to recognize
all the binary operations (biop's)
that are recognized by any of its subtypes; [1]
this implies that a subtype's set of biop's
can never be an extension of
its supertype's biop set
-- it must instead be a subset .
. this is in stark contrast to evolvers
where a subclass's set of operations
come from not only inheriting those of superclass's
but also by declaration of new operations .
1:
proving (using number as an example)
the supertype of a polymorph needs to recognize
the union of all its subtypes' operations:
. any time a binary operation occurs on
on an arbitrary pair of subtypes of number,
the most general response must be
to ask the supertype how to handle
any combination of subtyping in
{Q,R,N,Z,C,...}x{Q,R,N,Z,C,...} .
. even though there may be biop's
that only one subtype can perform,
in the general case
-- with dynamically changing subtypes
and user-defined polymorphs --
the only modular approach
is to leave it up to the supertype
to decide on whether a pair of subtypes
can legally be used by a given biop .
. the alternative to modularity
is to reprogram the compiler
to know what the supertype's job is,
so that it can supply that code implicitely .
. that might make sense for numbers,
but can compilers be changed in the general case?
(eg, with plugins); otherwise,
polymorphs need to put that code
in their supertype's body .
. the compiler should be able to use
the supertype's body, in a high-level way,
for optimizing code;
eg, if every twin pair (M,M) results in
delegating the implementation to M's method,
then in-line code could include
a run-time check for whether a pair were twins .
. the crux of subtyping is being
compatable with multiple types;
structural subtyping is allowing compatability between
any interfaces that share operations having
the same name and parameters;
nominal subtyping is where compatability is declared:
a subtype is compatible with its supertype
because it defined itself as supporting that supertype .
. the 2 types of nominal subtyping
are tentatively named here:
polymorphic subtyping, and
evolutionary subtyping .
. the term polymorphic refers to a single genome
that results in individuals of varying form;
eg, drones, queen, workers .
. evolution is about extending the capabilities
that were inherited .
. when considering the design of syntax for oop,
I noticed a difference between
{polymorphic subtyping (polymorphs)
, evolutionary subtyping (evolvers)
} that would cause their syntax to differ:
. the polymorphs are exemplified by the numbers,
which include the subtypes {Q,R,N,Z,C,...}.
. an obj' of type"number needs to recognize
all the binary operations (biop's)
that are recognized by any of its subtypes; [1]
this implies that a subtype's set of biop's
can never be an extension of
its supertype's biop set
-- it must instead be a subset .
. this is in stark contrast to evolvers
where a subclass's set of operations
come from not only inheriting those of superclass's
but also by declaration of new operations .
1:
proving (using number as an example)
the supertype of a polymorph needs to recognize
the union of all its subtypes' operations:
. any time a binary operation occurs on
on an arbitrary pair of subtypes of number,
the most general response must be
to ask the supertype how to handle
any combination of subtyping in
{Q,R,N,Z,C,...}x{Q,R,N,Z,C,...} .
. even though there may be biop's
that only one subtype can perform,
in the general case
-- with dynamically changing subtypes
and user-defined polymorphs --
the only modular approach
is to leave it up to the supertype
to decide on whether a pair of subtypes
can legally be used by a given biop .
. the alternative to modularity
is to reprogram the compiler
to know what the supertype's job is,
so that it can supply that code implicitely .
. that might make sense for numbers,
but can compilers be changed in the general case?
(eg, with plugins); otherwise,
polymorphs need to put that code
in their supertype's body .
. the compiler should be able to use
the supertype's body, in a high-level way,
for optimizing code;
eg, if every twin pair (M,M) results in
delegating the implementation to M's method,
then in-line code could include
a run-time check for whether a pair were twins .
subtype polymorphism replacing polymorphic records
4.22: adda/oop/subtype polymorphism replacing polymorphic records:
. the example in [cocoa patterns].book/hierarchy
of using a graphics tree to express subgraphics
reminded me of how expressions use trees:
. generic trees are intuitively implemented as
variant records, (I'm not sure why these aren't called
polymorphic records ...)
and, this had me realizing how oop subclasses
are using their subclass tag
as a variant record discriminant:
[4.28: for example,
an expression tree has an eval operation
for both the branch and leaf variants
of its variant record structure;
therefore, it's a candidate for replacement by
an oop structure:
the branch subclass's eval
has to eval all args's
then apply the given operation;
the leaf subclass's eval
has to return its immediate value .]
. in both the case of oop and of variant record,
the low-level implementation could involve
a tagged record:
a record where one of the fields
is a code indicating which variant or subclass
the current state belongs to .
. to see a record as an ADT (abstract datatype),
imagine its list of components rephrased as
the operations that come with those components .
. show how oop's subtype polymorphism can save space
the way a variant rec's polymorphism can .
[4.28: variant rec's assume
that the size of all variants
is known at compile time;
and if all the sizes are known to be
approx'ly the same,
then the implementation might use
an immediate placement
rather than a pointer .
. among oop cases, it's true for polymorphs (eg, numbers)
that the size of all variants is known at compile time;
but not generally true for evolvers
(because they can evolve after compile time)
so then, polymorphs can benefit from a
tag system that can indicate
whether the obj's placement is immediate
or found by a pointer .
. on the other hand, oop's polymorphism can be
a time waster:
if half the instances
implement an operation as null,
then it would be more efficient to
case the tag
and make the call only when the instance
supports that operation;
that, in fact,
is why oop allows both styles:
oop can do anything a variant record can
by allowing a client to ask an obj'
what subclass or variant
it currently belongs to .
. summary of variant discrimination
vs subclass polymorphism:
. every node visit can either case the tag
in order to decide on operations to apply;
or a visit can simply
use those operations that are
supported by every subclass .
so, when you ask an oop obj' to do an act,
you're asking a subtype
to do its version of the act .]
. the example in [cocoa patterns].book/hierarchy
of using a graphics tree to express subgraphics
reminded me of how expressions use trees:
. generic trees are intuitively implemented as
variant records, (I'm not sure why these aren't called
polymorphic records ...)
and, this had me realizing how oop subclasses
are using their subclass tag
as a variant record discriminant:
[4.28: for example,
an expression tree has an eval operation
for both the branch and leaf variants
of its variant record structure;
therefore, it's a candidate for replacement by
an oop structure:
the branch subclass's eval
has to eval all args's
then apply the given operation;
the leaf subclass's eval
has to return its immediate value .]
. in both the case of oop and of variant record,
the low-level implementation could involve
a tagged record:
a record where one of the fields
is a code indicating which variant or subclass
the current state belongs to .
. to see a record as an ADT (abstract datatype),
imagine its list of components rephrased as
the operations that come with those components .
. show how oop's subtype polymorphism can save space
the way a variant rec's polymorphism can .
[4.28: variant rec's assume
that the size of all variants
is known at compile time;
and if all the sizes are known to be
approx'ly the same,
then the implementation might use
an immediate placement
rather than a pointer .
. among oop cases, it's true for polymorphs (eg, numbers)
that the size of all variants is known at compile time;
but not generally true for evolvers
(because they can evolve after compile time)
so then, polymorphs can benefit from a
tag system that can indicate
whether the obj's placement is immediate
or found by a pointer .
. on the other hand, oop's polymorphism can be
a time waster:
if half the instances
implement an operation as null,
then it would be more efficient to
case the tag
and make the call only when the instance
supports that operation;
that, in fact,
is why oop allows both styles:
oop can do anything a variant record can
by allowing a client to ask an obj'
what subclass or variant
it currently belongs to .
. summary of variant discrimination
vs subclass polymorphism:
. every node visit can either case the tag
in order to decide on operations to apply;
or a visit can simply
use those operations that are
supported by every subclass .
so, when you ask an oop obj' to do an act,
you're asking a subtype
to do its version of the act .]
Subscribe to:
Posts (Atom)