As a result, the document provides a uniform and consistent view of an essential part of the foundations of object oriented programming.
Author

Document date

Note: For a more detailed introduction into the subject see [].
fundamental partwe mean a structure that encompasses the following fundamental relations:
The goal is to introduce a common mathematical structure such that for most classbased languages, there is a correspondent part of the data model that forms a special case. Such a common mathematical structure would provide a uniform and consistent view of foundations of OOP.
To specify the universe on which the structure is defined, we follow the wellknown OOP guideline:
Any
, Object
, Class
, Int
and i
.

green links.
dark blue links(the class map) with the inheritance.
var Any = classOf[Any] var Object = classOf[Object] var Class = classOf[Class[_]] var Int = classOf[Int] var i = 7 assert (Object.isAssignableFrom(Class)) assert(!Object.isAssignableFrom(Int)) assert ( Class.isInstanceOf [Object]) assert ( Int.isInstanceOf [Object]) assert ( i.isInstanceOf [Int]) assert ( i.isInstanceOf [Any]) //assert( !i.isInstanceOf [Object]) // not supported assert (i.getClass == Int) assert (i.getClass.getClass == Class) println (if (Object == Any) "???" else "OK") // ???The code also shows that in Scala, there is some indirection in support of the
Everything is an objectpattern. In particular:
receiverobject a and a name s the task is to determine the value of the possibly inherited property of a
named(by) s. As a subtask, the
ownerobject y has to be determined that interprets s – i.e. y is an object that
ownsan snamed binding to the requested target value. In a simplified form, the subtask is performed in two steps:
own) an snamed binding.
unresolved.
A::B
.
Note: Setting x = a is exactly what is performed in languages with prototypal inheritance, e.g. JavaScript.
a.b
.
In step (2), if we denote y = x.owner(s) then for each
name s, the .owner(s) map is a partial
closure operator
in inheritance.
(By partial
we mean a restriction to the set
of objects that have an ancestor with an snamed binding.)
However, the existence of such an operator is only guaranteed for
single inheritance
– i.e. when the inheritance relation is a forest.
In general, additional structure is required that equips every ancestor set
with a linear order.
frontsubstructure can have an inmemory representation, so that eigenclasses are mostly fictitious:
object
construct)
have a referenceable eigenclass.
The second, more serious, problem consists in the requirement that metaclasses are classes. Consider the following Ruby code:
class A; end p A.class # Class (class B < Class; end) rescue p $! #... can't make subclass of ClassUsing the (b) definition, we could conclude that in Ruby, there is one and only one metaclass: the
Class
class.
However, since the
Ruby object model is in tight correspondence with the Smalltalk80 object model
(regarding the instance–inheritance structure)
we would obtain the following paradox:
Class
class, Smalltalk has no metaclasses.
(∗)
We provide a solution to the above problems by proposing a new definition of a metaclass:
inheritance descendantis meant in the nonstrict sense – including the metaclass root itself. Metaclasses that are (resp. are not) classes are called explicit (resp. implicit). The paradox (∗) then turns into the statement that except for the
Class
class, Smalltalk has no explicit metaclasses.
The definition applies directly to all of Ruby, Python, Scala, Java, Smalltalk
and CLOS,
although in the case of the latter two languages care must be taken as to what
is meant by class of
in (2).
Unfortunately, the introspection methods class
(in Smalltalk)
and classof
(in CLOS) are misleading here.
For ObjectiveC and Perl we have to use a modified definition due to the multiplicity and degeneracy of metaclass roots:
Ruby  Python  Smalltalk  ObjectiveC  Scala  Java  CLOS  Perl  
S1  Explicit metaclasses  ●  ●  ○  
Implicit metaclasses  ●  ●  ●  
Eigenclasses of terminal objects  ●  ●  
Eigenclasses of eigenclasses  ●  
Multiple inheritance  ○  ●  ○  ◐  ●  ●  
Terminal mixins  ●  ●  
Nonterminal mixins  ●  
Multiple roots  ○  ●  
Degenerated root(s)  ●  ●  
Additional twist links  ●  
Imposed class map  ●  ●  
Nonlinear helix  ●  
Circular classes  ●  
Described by structure  S1_{r}  S1_{p}  S1_{m+w+r}  S1_{c}  S1_{s}  S1_{ℓ}  S1_{@}  
S2  Linearization  ●  ●  ●  ●  ●  
Described by structure  S2_{r}  S2_{p}  S1_{m+w+r}  S1_{c}  S2_{s}  S1_{s}  S2_{ℓ}  S2_{@} 
Notes:
explicit metaclasseshere we mean explicit metaclasses other than metaclass root(s). For Python and CLOS it also means support for usercreated explicit metaclasses. The ○ symbol for Perl indicates that Perl's classes become metaclasses by universal circularity.
terminal mixinswe mean Ruby modules or Smalltalk traits. These are terminal objects that are indirectly involved in inheritance – in particular, being terminal objects, they are NOT descendants of the inheritance root.
nonterminal mixinswe mean Java interfaces or Scala traits. These classlike objects are distinct from classes but are directly involved in inheritance – in particular, they are descendants of the inheritance root.
Multiple rootsmeans that there can be more that one class without inheritance parent(s). The ○ symbol for Smalltalk indicates that in Smalltalk80 (as implemented by Pharo or Squeak), there are multiple classes without ancestors but only a single
mainroot. The
subsidiaryroots arise from additional twist links.
degenerated rootwe mean an inheritance root that is its own class. (Equivalently, it is an inheritance root that is a parent of its eigenclass.)
imposed class mapfeature can be equivalently characterized as a support for a class map with monotonicity breaks w.r.t. inheritance. That is, it is possible that for some objects x, y, x is a descendant of y but the class of x is not a descendant of the class of y.
Nonlinear helixmeans that there is multiple inheritance (even) between helix classes (ancestors of the metaclass root).
circular classesfeature means that in addition to helix classes there are other classes that are its own instances.
pointedobject membership, (Θ, ϵ, m).
Ruby  Python  Smalltalk  ObjectiveC  Scala  Java  CLOS  Perl  
Implementation platform  MRI  CPython  Pharo  GNUStep  JRE  CLISP  Strawberry  
Version  1.9.2  3.2.2  1.3  0.29.1  2.10.0  1.7.0  2.49  5.16.1 
An S1_{p} structure is a structure (O, .ec, .pr, ≤, r, c) where
(O, .ec, .pr) is a primorder algebra.
We will apply established notation and terminology, in particular, definition of .ce and .eci.  
The inheritance ≤
is a partial order on O such that
 
For every objects x, y,
 
For helix objects, the following holds:
 
For every class x and every eigenclass e,
 
The set O.pr of primary objects forms a closure system in
the inheritance ≤.
Let .c denote the corresponding closure operator, i.e. for a nonterminal object x, x.c is the least class y such that x ≤ y. (For a terminal x, x.c = x.) Let .class denote the composition .ec.c (and .class(i) its ith application, i ≥ 0).  
For every object x,
 
For every nonhelix class x and every i > 0,
 
The set C of classes is finite. 
side view.
Full structure  Restriction to primary objects  
Inheritance  Instance tree  



M
< r.ec(2).

Corresponding Python code:class M(type): pass class N(type, metaclass=M): pass class A(metaclass=N): pass class B(A): pass b = B() 
←
class M(type): pass class N(type): pass class A(metaclass=M): pass # metaclass conflict class B(A,metaclass=N): pass 
Proposition:
(1) 
For every objects x, y,

(2) 
For every objects x, y,

(3)  An object is terminal if it is both maximal and minimal in ≤. 
(4)  The inheritance root r is the unique object that is maximal in ≤ but not minimal. 
Corollary: An S1_{p} structure is fully determined by the ϵ relation.
Note: In the sequel we provide alternative axiomatization of S1_{p} structures based on the ϵ relation.
X
are referred to as X
s.
An instance of X
is said to be an X
.
Observations:
Class
is the name of the metaclass root c then
Class
es
is synonymous to nonterminal objects(i.e. classes and eigenclasses).
Notation  Composition  Terminology  y restricted to 
ϵ•  (ϵ) ○ (Μ)  x kindof y  
ϵ  (.ec) ○ (≤)  x memberof y  C, O.ec 
(ϵ) ○ (.c)  x instanceof y  C  
.class  (.ec) ○ (.c)  x directinstanceof y (the class of x is y) 
C 
Proposition A:
(1) 
Assuming just
 
(2) 
For every object x,
 
(3) 
For every object x,
 
(3') 
For every object x and every i ≥ 0,
 
(4) 
Let x, y be objects such that
x ∈ H iff y ∈ H. Then
 
(5)  The inheritance ≤ is upper finite, i.e. every object has finite number of ancestors.  
(6)  Every nonhelix eigenclass chain is an antichain in inheritance.  
(7)  The set of helix objects forms an upset in inheritance. (I.e. if x < y and x is a helix object then so is y.)  
(8)  The set of nonhelix eigenclasses forms a downset in inheritance.  
(9) 
Let ≲ be a relation between primary objects defined by

Proposition B:
Assume just
(i) 

(ii) 
The .class map forms a tree such that c
is the root.
Equivalently, for every class x,

(ii') 
For every class x and every i ≥ 0,

(iii) 
The following is satisfied:

(iv) 
For some helix object h,

Proof:
(i)→(ii')
We first show that
Let x.class(i) = x for some i > 0.
Since x.class(i) = x.ec(i).c
we have x.ec(i) < x, thus x must be a helix class.
But x.class = c for every helix class so that x = c.
(ii')→(i)
Assume x.ec(i) < x for some class x and i > 0.
Denote y = x.ec(i).c.
Then
Proposition:
Proposition:
Observations:
Note:
In the eigenclass alignment
used before,
terminals are drawn in the same column
as the inheritance root r.
This alignment is motivated by the situation when
all descendants of r.ec are eigenclasses
(i.e. there are no explicit metaclasses other than c)
as is the case in Ruby.
Each column then contains objects x with the same eigenclass index
x.eci.
class A: pass class M(A,type): pass 
class M(type): pass class N(M,metaclass=M): pass assert N.__class__ == M 
metalevel separation condition.
For every nonhelix objects x, y,

Proposition A:
Proposition B:
Assume that
the metalevel separation condition
Note: The explicit/implicit terminology is redundant. We could use the primary/secondary terminology established in the 2x2 nomenclature of objects. [].
M
and N
.
Observations:
Proposition:
Corollary: Up to isomorphism, an S1_{p} structure is uniquely given by (O.pr ∪ H, .pr, ≤, .class).
For every class x and every (helix) eigenclass e,

Proposition A: The following conditions are equivalent:
Proposition B:
Assume that
Corollary:
Note: A standalone axiomatization of (O.pr, ϵ, ≤) / (O.pr, .class, ≤) is provided in a specialized section.
Proposition:
x = q.new(p_{1},…,p_{n})
In the following Ruby code,
new primary objects A
and a
are created.
A
is a class such that A
.class = c and
A
.parents = {Object
}.
a
is a terminal object such that
a
.class = A
and
(necessarily) A
.parents = ∅.
class Object alias ec singleton_class end c = Class # c refers to Class, the only explicit metaclass in Ruby A = c.new(Object) # A is a new class  a subclass of Object a = A.new # a is a new terminal  a direct instance of A c.new(c) rescue puts $!.message # can't make subclass of Class c.new(A.ec) rescue puts $!.message # can't make subclass of singleton class A.ec.new rescue puts $!.message # can't create instance of singleton class a.new rescue puts $!.message # undefined method `new' for #<A:0x8b48e0>The last 4 lines show rejected transition requests. Neither c nor the eigenclass
A
.ec
can be inheritance parents of a class.
Neither A
.ec nor a
can have instances.
By an S1_{ϵ} structure we mean a structure (O, ϵ) where
Every object x has a unique smallest container,
called the eigenclass of x, denoted x.ec,
whose all ancestors are containers of x, i.e.
 
Distinct objects have distinct sets of containers, i.e.
for every objects x, y,
 
Terminals are minimal in inheritance, i.e.
for every objects x, y,
 
Helix objects satisfy the following properties:
 
Descendants of nonhelix eigenclasses are eigenclasses, i.e.
for every objects x, y,
 
Primary objects form a closure system in the inheritance, equivalently,
for every object x there is a unique object, denoted x.class,
such that
 
For every object x,
 
Helix ancestors of descendants of nonhelix classes are lower bounded, i.e.
there exists a helix object h such that
for every nonhelix class x,
 
The following finiteness conditions are satisfied:

An eigenclass different from r.ec can only have eigenclasses as descendants. 
Proposition:
For every object x,

(1) 
Proof:
The implication
x ϵ y.ec → x ≤ y
is shown by the diagram on the right.
Assume  
(2) 
Terminal objects have no members.
Proof:
Assume that x ϵ t for a terminal t.
Then x.ec ≤ t, thus,
by  
(3) 
An object x is a helix class iff r.ec < x.
Proof:
Let r.ec < x.
Since x is not minimal it cannot be terminal.
The implication
r.ec < y.ec → r < y
shows that x cannot be an eigenclass.
Thus x is a class. In particular, x ≤ r.
As a consequence, x.ec ≤ r.ec < x so that
 
(4) 
The inheritance root, r, is a helix class.
Proof:
Follows by (3) and  
(5) 
There is a least helix class, the instance root c,
equal to r.class.
In addition, c ≠ r.
Proof:
Follows by (3) and  
(6) 
The sets { r.ec(i)  i ∈ ℕ } and H
are closure systems in (O ∖ T, ≤).
(The corresponding closure operators are denoted .re and .he,
respectively.)
Proof:
By
 
(7) 
Every object x has a unique primary object, x.pr,
i.e.
for every x there exists a primary object p,
Proof: Let x be an object. If x is primary then x.pr = x. For an eigenclass x, let i be such that r.ec(i) = x.re. If p.ec(i+1) = x for some eigenclass p then p ≤ r would imply x = p.ec(i+1) ≤ r.ec(i+1) < r.ec(i) = x.re – a contradiction with the definition of x.re. This means that p.ec(j) = x for some j ≤ i + 1 and a primary object p.  
(8) 
The class map .class forms a tree rooted at the instance root
c.
Equivalently, for every object x,
Proof:
Let h be a helix object satisfying 
Corollary: For a structure S = (O, ϵ) the following are equivalent:
An S1_{ϵ}.pr structure is a structure (O.pr, ϵ, ≤) where
 
The inheritance ≤ is a partial order between objects.  
 
The set H.pr of helix classes is subject to the following conditions:
 
Metaclasses can only have classes as instances.  
Every object x has a least primary container,
x.class.
(In particular, every object is an instance of a class.)  
Cycles in ϵ only occur among helix classes,
i.e.
for every object x and every i > 0,
 
The set C of classes is finite. 
Proposition:
Eigenclass completionFor an S1_{ϵ}.pr structure (O.pr, ϵ, ≤) we define its eigenclass completion as a structure (O, ϵ, .ec, ≤) with the following properties:
Proposition A: (O, ≤) is a partial order. Proof: i.e. for every objects u, v, w,
Proposition B: The .ec map is an order embedding of (O, ≤) into itself. Corollary:
Proof: Follows from the previous proposition and the definition of eigenclass completion. Proposition C: For every objects x, y, there are at most finitely many k such that
Corollary: Every object has finite number of ancestors. Proof: Let x = a.ec(i), y = b.ec(j) for primary objects a, b and let k ≥ 0 be such that a.ec(i) ≤ b.ec(j+k). By condition (ec~B), j+k ≤ i+1, i.e. k is upper bounded by i+1j. For a nonterminal object x, we denote x.re = r.ec(i) such that x ≤ r.ec(i) and i is maximal with such property. Proposition D: For every nonterminal object x and every i ≥ 0,
Proposition E:
Proof:
Proposition F:
The structure (O, ϵ)
is an S1_{ϵ} structure
satisfying Proof:
We prove the conditions
Class map reductionBy
Proposition:
S1_{p}.pr: The primary structure via the class mapFor completeness, we also provide an alternative axiomatization of the primary structure, based on the .class map.An S1_{p}.pr structure is a structure (O.pr, .class, ≤, r, c) where
Proposition: For a structure S = (O.pr, ϵ, .class, ≤) the following are equivalent:
S1_{r}: Terminal mixins (modules)Motivated by the Ruby object model we introduce a generalization of S1_{p} structures that allows extension of object membership via terminal mixins (modules).An S1_{r} structure is an S1_{p} structure equipped with (Μ, m) where
Note: Transitivity of Μ is not asserted so that Μ is not necessarily a partial order []. The composed inheritance ≤•The composed inheritance, ≤•, is defined as (O, ≤) ○ Μ, i.e. ≤• is a relation between objects such that
The kindof relation ϵ•The kindof relation, ϵ•, is defined as ϵ ○ Μ, i.e. ϵ• is a relation between objects such that
Proposition: (ϵ•) = (.ec) ○ (≤•). S1_{s}: Nonterminal mixinsMotivated by the Scala object model we introduce a generalization of S1_{p} structures that allows nonterminal mixins as the third kind of primary objects (in addition to terminals and classes).An S1_{s} structure is a structure (O, .ec, .pr, ≤, r, c, .c) where
Proposition:
ExampleThe following diagram shows an S1_{s} structure that cannot be considered an S1_{p} structure. The eigenclasse has
has 2 parents that are primary objects: A and T .
Therefore,
the set O.pr of primary objects does not form
a closure system.
def p (x:Object) { println (x.toString.replace("Main$$anon$2$", "")) } class A trait T val A = classOf[A] ;p(A) // class A val T = classOf[T] ;p(T) // interface T val a = new A ;p(a) // A@c76887 val b = new A with T ;p(b) // $anon$1@19f9744 val e = b.getClass ;p(e) // class $anon$1 object x extends A ;p(x) // x$@12b644e val y = x.getClass ;p(y) // class x$ assert (A == e.getSuperclass) assert (A == y.getSuperclass) SemiinstanceofIn the previous example,b.isInstanceOf[T] would evaluate to true .
To reflect this, we introduce semiinstanceof as the
rangerestriction of ϵ to semiclasses, i.e.
S1_{c}: Multiple roots and degenerate helixesMotivated by the ObjectiveC object model we introduce a generalization of S1_{p} structures that allows multiple components of inheritance as well as helixes that have only one class.An S1_{c} structure is a structure (O, .ec, .pr, ≤, .r) where
Proposition:
ExampleThe following diagram shows a component of an S1_{c} structure.
#import <Foundation/Foundation.h> @interface A_: NSObject; @end; @implementation A_; @end @interface B_: A_; @end; @implementation B_; @end int main(int argc, const char *argv[]) { id r = [NSObject class]; id e = object_getClass(r); id A = [A_ class]; id f = object_getClass(A); id B = [B_ class]; id g = object_getClass(B); id b = [B new]; return 0; } S1_{m}: Metaclass redirectionMotivated by the Smalltalk80 object model we introduce a generalization of S1_{p} structures that allows redirection of the class map on metaclasses (those from the subroot level of the instance tree).An S1_{m} structure is an S1_{p} structure equipped with (ȼ) where
Metaclass .
The following condition is required:
Proposition:
Note:
Condition (1)(iv) means that metaclass redirection (if any) is A sampleThe following diagram shows a sample S1_{m} structure without explicit metaclasses other than c (which is the case of Smalltalk). The dashed arrow from r.ec to ȼ indicates the metaclass redirection which is inherited by all (implicit) metaclasses. Dashed border forb .ec indicates that in Smalltalk,
eigenclasses of terminal objects are fictitious, see
Object actuality.
S1_{w}: Additional twist linksMotivated by another quirk of the Smalltalk80 object model we introduce a generalization of S1_{p} structures that allows multiple direct descendants of the metaclass root.An S1_{w} structure is a structure (O, .ec, .pr, ≤, r, c) where
Proposition:
ExampleThe following diagram shows an S1_{w} structure that refers to thePseudoContext class as known from Pharo.
Note:
Instantiation of S1_{ℓ}: Nonlinear helix and imposed class mapMotivated by CLOS we introduce a generalization of S1_{p} structures that allows noncomparable helix classes as well as redirection of the class map.PreliminariesLet (X, ≤) be a partial order and .f a function on X. We say that an element p ∈ X is an .fprototype if the following conditions are satisfied:
inheritsthe value of .f from p. Proposition:
DefinitionAn S1_{ℓ} structure is a structure (O, .ec, .pr, ≤, r, c, .¢lass) where
Proposition:
The CLISP builtin core structureThe following diagram shows the builtin core structure of CLOS as implemented by CLISP. The set of displayed classes can be obtained in the following steps:
(∗) Set intersection with C should be applied to exclude eigenclasses.
A sample user structureThe following diagram shows a sample usercreated S1_{ℓ} structure in metaclass alignment. Note that
Helix entryThe diagram in the appendix shows that CLISP allows classes with undefined helix entry.S1_{@}: Circular classesMotivated by the Perl object model we introduce a generalization of S1_{p} structures that allows multiple instance roots (while still preserving a single inheritance root).An S1_{@} structure is a structure (O, .ec, .pr, ≤, r, c) where
Proposition:
Perl circularityBy a Perl S1_{@} structure we mean an S1_{@} structure such that the following properties are satisfied:
Proposition:
Assuming just
A sampleThe following diagram shows a Perl S1_{@} structure together with corresponding Perl code.
S1_{∗} in particular programming languagesRubyRecall that a Ruby S1 structure [] is a structure of the form (O, .ec, .pr, .sc, r, c) with .sc being the superclass partial function. If we express the forest (O, .sc) as its reflexive transitive closure (O, ≤), we obtain the same list of symbols (and the same signature) as for S1_{p} structures.A Ruby S1_{p} structure is then an S1_{p} structure such that the following properties are satisfied
A Ruby S1_{r} structure is an S1_{r} structure (O, ϵ, Μ, m) such that the following conditions are satisfied:
PythonA Python S1_{p} structure is an S1_{p} structure such that the following properties are satisfied
Proposition: A Python S1 structure [] is an S1_{p}.pr structure with just 2 helix classes. ScalaA Scala S1_{s} structure is an S1_{s} structure such that the following properties are satisfied:
Note: In Scala, mixins (elements of Ϯ) are called traits. JavaA Java S1_{s} structure is a Scala S1_{s} structure with additional properties. In Java, elements of Ϯ are called interfaces (instead of traits).
Notes:
Smalltalk80A Smalltalk S1_{m} structure is an S1_{m} structure such that the following conditions are satisfied:
A Smalltalk S1_{w} structure can be defined as an S1_{w} structure satisfying the same conditions as above except for the last one. Additionaly, an extra condition might be imposed that subsidiary classes have no instances. A Smalltalk S1_{r} structure is an S1_{r} structure such that the following holds.
Note: The traits facility in Smalltalk [] does not seem to be mature enough to allow serious description.
ObjectiveCObject membership in ObjectiveC does not conform to the S1_{p} structure for the following 2 reasons:
CLOSA CLOS S1_{ℓ} structure is an S1_{ℓ} structure such that the following properties are satisfied
PerlThe Perl S1_{@} structure has been introduced within S1_{@} structures.Helix classes in comparison
S1_{ϵ,a}: Object actuality and the actualclass mapAn S1_{ϵ,a} structure is a structure (O, ϵ, .a) where
The structure is subject to the following conditions:
For an object x,
we denote x.actuals the (necessarily finite) list of all
nonstrict eigenclass successors of x that are actual.
In particular, if x is primary then x.actuals
is the Proposition:
S1_{s,a}Object actuality for S1_{s} structures is subject to an additional condition.
S1_{c,a}For S1_{c,a} structures,
S1_{m,a}For S1_{m,a} structures, the following additional condition is required:
Proposition: The imposed actualclass map .aȼlass forms a pseudotree (which can be called the (imposed) actualclass pseudotree). Its pseudoroot consists of elements of ȼ.actuals. The following diagram shows a sample Smalltalk80 S1_{m,a} structure with its actualclass pseudotree. The pseudoroot contains theMetaclass class and its eigenclass.
Nonactual eigenclasses are not displayed.
Actuality in particular programming languagesThe following table shows support for actual eigenclasses in the considered programming languages. In Python, Java and CLOS, all actual objects are primary. Smalltalk and ObjectiveC have fixed set of actual eigenclasses consisting of first eigenclasses of classes.
RubyRuby supports dynamic eigenclass actualization. In fact, there are 2 actuality systems in MRI, corresponding to two actualclass maps:
S2_{r}: Linearization of terminal mixinsAn S2_{r} structure is an S1_{r} structure equipped with (≤_{Μ}) where
Proposition:
Inclusion listsFor an object x the (own) inclusion list of x, denoted x.incs, corresponds to (x.incl^{−1}, ≤) without the bottom. More specifically, x.incs is a (possibly empty) list of modules defined by
Proposition: An S2_{r} structure can be expressed as (O, ϵ, .incs, m). In RubyA Ruby S2_{r} structure is an S2_{r} structure such that the S1_{r}reduct (obtained by forgetting the inclusion order) is a Ruby S1_{r} structure.The structure is also specified in [] where it is referred to as the S2 structure. Since inheritance (O, ≤) in Ruby is a forest, the MRO relation is also a forest, which is the designed characteristics. For a sample structure, see [] or an S2_{ϵ} sample. S2_{s}: Linearization of nonterminal mixinsIn an S1_{s} structure, the Μ relation is obtained implicitly is a subset of the inheritance ≤ defined by (x,y) ∈ Μ iff one of the following conditions is satisfied:
ownmeans that all objects strictly between x and y in inheritance are mixins. An S2_{s} structure is an S1_{s} structure equipped with (≤_{Μ}) where
Proposition A:
Proposition B: In contrast to S2_{r} structures, the following properties are satisfied:
In ScalaLike with Ruby S2_{r} structures, a Scala S2_{s} structure is an S2_{s} structure such that the S1_{s}reduct is a Scala S1_{s} structure. Since the inheritance on the set Ͼ of classes is a tree, the MRO relation, restricted to Μ' =Notes:
S2_{p}: Linearization of ancestorsThe Μ relation, in its default semantics (which is overridden in S1_{r} or S1_{s}), equals the inheritance ≤, i.e.
Note: The (c3) condition is enforced by the C3 linearization algorithm []. In PythonBy default, Python uses C3 linearization. A request for creation of a class with c3incompatible parents results in an error. This behavior can be altered by explicitly setting the__mro__
attribute.
Note:
As of version 3.2,
Python allows to set quite arbitrary ancestor lists to In CLOSIn CLOS, the (c3) condition is mandatory – according to Common Lisp HyperSpec [].In PerlBy default, Perl uses depthfirst linearization so that even (c2) is not guaranteed. Optionally, theuse mro 'c3' S2_{ϵ}: IclassesThis section provides anϵaxiomatizationof S2_{r} structures, similarly as S1_{ϵ} structures are S1_{p} structures axiomatized via ϵ. The description introduces iclasses which are objectivizedelements of Μ ∖ O.∆. By an S2_{ϵ} structure we mean a structure (Θ, ϵ, m) where
Sample structureThe following diagrams show a sample S2_{ϵ} structure from Ruby.
Kernel
module together with its inclusion into the Ruby helix.
The structure that corresponds to the merge of both diagrams can be created by the following Ruby code: module M; end module N; include M end class A < BasicObject class << self; include N end end class Object; def ec; singleton_class end end p M .ancestors # [M] p N .ancestors # [N, M] p A .ancestors # [A, BasicObject] p N.ec.ancestors # [Module, Object, Kernel, BasicObject] p A.ec.ancestors # [N, M, Class, Module, Object, Kernel, BasicObject] Notes:
S2_{ϵ} versus S1_{ϵ}Proposition:
S2_{ϵ} versus S2_{r}We denote Μ the relation on O defined by
module in the context of its own includer. The bijection .ω in turn induces a partial order ≤_{Μ} on Μ:
Proposition: Let S = (Θ, ϵ, m) be an S2_{ϵ} structure and denote S_{ r} = (O, ϵ, ≤_{Μ}, m).
Eigenclasses of iclassesAccording to the definition, for every iclass x, the eigenclass map .ec is
AppendixThe ontological structure of ϵThe document [] provides a generalization of object membership as it applies to ontological structures based on RDF Schema. The generalization structure, denoted S1_{o}, is distinguished by the following features:
PrototypesThe document Object Membership with Prototypes [] shows that it is also possible to refine the instanceof relation the opposite way by eigenclass predecessors of objects, rather than successors. Such implicit objects are called (instance) prototypes. The corresponding S1_{ȷ} structures are introduced as structures (Θ, O, ϵ) such that (Θ, ϵ) is an S1_{ϵ} structure without terminal objects, and O is a subset of Θ such that the substructure (O, ϵ) is an S1_{ϵ} structure whose nonterminal objects form the set Θ.ec.↧. Objects from Θ ∖ O are the instance prototypes. The inclusion Θ.ec.↧ ⊆ O establishes a onetoone correspondence between the ith metalevel of (Θ, ϵ) and the (i+1)th metalevel of (O, ϵ) for each natural i.
It is shown how
S1_{ȷ} structures
apply to the JavaScript programming language.
As a particular conclusion which can be drawn,
JavaScript cannot be declared to be The Python Object ModelThe document [] provides a brief description of Python's S1 and S2 structures.CLOS/CLISP metaobject classesThe following diagram shows inheritance between builtin descendants of themetaobject class in CLOS as implemented by CLISP 2.49.
The set of displayed classes equals mo .↧.↥
(without eigenclasses) where
mo is the metaobject class.
Red oval indicates that for the m class (and its descendants),
the helix entry m .he is undefined.
Correspondence to related former documentsSpecialized description of the instance–inheritance structure of the Ruby object model is provided in []. The structure is then further developed in [] together with a comparison with Smalltalk80 []. There are slight differences in notation and terminology which are summarized in the following table.
References
Browser compatibilityTo be viewed correctly, this document requires advanced browser features to be supported, including
Document history
LicenseThis work is licensed under a Creative Commons AttributionNonCommercialShareAlike 3.0 License. 