<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE TIP SYSTEM "http://www.tcl.tk/cgi-bin/tct/tip/tipxml.dtd">
<!-- Converted at Thu Jun 20 07:02:41 GMT 2013 -->
<!-- TIP AutoGenerator - written by Donal K. Fellows -->

<TIP number='279'>
<header><title>Adding an Extensible Object System to the Core</title><author address="mailto:neumann@wu-wien.ac.at">Gustaf Neumann</author><author address="mailto:lvirden@yahoo.com">Larry W. Virden</author><status type='project' state='draft' tclversion="8.7" vote='prior'>$Revision: 1.10 $</status><history></history><created day='5' month='oct' year='2006' /></header>
<abstract>This TIP proposes adding OO support to the Tcl core, consisting mostly of a dispatcher plus a small number of helper commands. The TIP allows the coexistence of multiple object systems by providing a common framework, the Tcl Minimal Object System (TMOS). The framework will contain, as well, a small, basic oriented language (Tcl Core Object Oriented Language, TclCOOL) to make it usable in the core without any extensions. All defined commands of the minimal object system are defined in the <emph style="bold">::oo</emph> namespace, which is not used by any current mainstream OO system. It has been designed specifically to allow a relatively simple re-implementation of the known object systems.</abstract>
<body><section title="Rationale and Basic Requirements">
<para>Rather than proposing any kind of OO language, the TIP suggests to add a framework to the core that many existing and future extensions (including XOTcl) can use. This framework alone is not useful as an OO language, but is an environment that can host multiple OO languages in parallel, such as Snit or XOTcl (maybe the language from current <tipref type="text" tip="257"/> as well), without pushing a single model. Languages like Snit or XOTcl can continue to develop, the core developers can optimize and integrate better with the tcl-core, etc.</para>
<para>The framework (Tcl Minimal Object System, TMOS) consists of an flexible object interpreter (dispatcher) able to run the most powerful current object extensions. This dispatcher is accompanied by a &quot;minimal object system&quot; and a small set of predefined, but unattached methods (basic method set) and an &quot;extension mechanism&quot;. For the bootstrapping of different object systems, only a single method for allocating objects or classes is proposed, plus a few commands for setting up the object/class relations and registering methods.</para>
<para>The Tcl Minimal Object System is used for the definition of TclCOOL (Tcl Core Object Oriented Language). TclCOOL is simple but powerful object language realized with TMOS. </para>
<para>Additional object systems (like XOTcl, SNIT or STOOP) can be loaded as an extensions (being not part of the core), and can provide their own method-sets (or re-use the predefined method set, or reuse the methods-set of some extension).</para>
<para>This approach provides a flexibility much higher than in other popular scripting languages and lets object system designers continue to improve their work based on Tcl.</para>
</section>
<section title="The Tcl Minimal Object System">
<para>The minimal object system consists of a base class (<emph style="bold">::oo::object</emph>) and a meta-class (<emph style="bold">::oo::class</emph>, subclass of <emph style="bold">::oo::object</emph>).</para>
<verbatim><vline encoding='base64'>ICAgbmFtZSBvZiBjbGFzcyAga2luZCBvZiBjbGFzcyAgc3VwZXJjbGFzcyAgICAgaW5zdGFuY2Utb2Y=</vline><vline encoding='base64'>ICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09</vline><vline encoding='base64'>ICAgOjpvbzo6b2JqZWN0ICAgY2xhc3MgICAgICAgICAgOjpvbzo6b2JqZWN0ICAgOjpvbzo6Y2xhc3M=</vline><vline encoding='base64'>ICAgOjpvbzo6Y2xhc3MgICAgbWV0YS1jbGFzcyAgICAgOjpvbzo6b2JqZWN0ICAgOjpvbzo6Y2xhc3M=</vline></verbatim>
<para>The meta-class <emph style="bold">::oo::class</emph> has two methods named &quot;<emph style="bold">alloc</emph>&quot; and &quot;<emph style="bold">dealloc</emph>&quot; (names are arbitrary, as shown later) to create objects or classes. <emph style="bold">::oo::object</emph> has no methods at all.</para>
<para>The minimal object system is intended to be specialized by one or more different object systems. An object system is created by sub-classing the base classes, configuring these according to the object systems needs. This configuration consists of defining its relations to the general base and meta-class, and equipping these extension-specific classes with additional functionality (providing methods). The whole configuration of the object system can be done completely from the scripting level.</para>
<para>The minimal object system defines the following commands and methods in the ::oo namespace:</para>
<itemize><item.i><para>Two classes</para><verbatim><vline encoding='base64'>ICAgOjpvbzo6Y2xhc3M=</vline><vline encoding='base64'>ICAgOjpvbzo6b2JqZWN0</vline></verbatim></item.i><item.i><para>Two unexported Tcl commands for OO-language designer</para><verbatim><vline encoding='base64'>ICAgOjpvbzo6YWxpYXM=</vline><vline encoding='base64'>ICAgOjpvbzo6c2V0cmVsYXRpb24=</vline></verbatim></item.i><item.i><para>Three exported Tcl commands to be used by in the languages</para><verbatim><vline encoding='base64'>ICAgOjpvbzo6bXk=</vline><vline encoding='base64'>ICAgOjpvbzo6c2VsZg==</vline><vline encoding='base64'>ICAgOjpvbzo6bmV4dCA=</vline></verbatim></item.i><item.i><para>An unregistered (unattached) set of methods that can be used for classes</para><verbatim><vline encoding='base64'>ICAgYWxsb2MsIGRlYWxsb2MsIGluc3Rwcm9jLCBpbnN0Zm9yd2FyZCwgaW5mbw==</vline></verbatim></item.i><item.i><para>An unregistered (unattached) set of methods that can be used for objects | instvar forward info</para></item.i></itemize>
<para>The Tcl command ::oo::setrelation</para>
<verbatim><vline encoding='base64'>ICAgOjpvbzo6c2V0cmVsYXRpb24gY2xhc3N8b2JqIDxyZWxhdGlvbj4gPHRhcmdldD4=</vline></verbatim>
<para>allows one to define/redefine relations between objects, classes and mixins. This is a primitive command designed for the language developer, not for the user of the implemented object oriented language. The following relations are supported: <emph style="bold">mixin</emph> (abbreviation for per-object mixin), <emph style="bold">instmixin</emph> (for per-class mixin), <emph style="bold">filter</emph> (for per-object filter), <emph style="bold">instfilter</emph> (for per-class filter), <emph style="bold">class</emph>, and <emph style="bold">superclass</emph>. The meaning of these relations is defined by the dispatcher, which is responsible for the linearization of the commands.</para>
<para>The dispatcher determines the invocation order depending on the precedence order and the resolution order. The precedence order defines the priorization of classes and determines therefore the shadowing of methods. The precedence order is per-object mixins, followed by per-class mixins, followed by the class hierarchy. All of these refer not to single classes but to class hierarchies, where the contained classes are linearized; when a class is mixed into a precedence order, where it is already present, it has no effect. The precedence of object specific methods is between mixins and the intrinsic class hierarchy.</para>
<para>The method resolution order overlays the precedence order. While the precedence order determines, what method should be called, the method resolution order determines what other methods should be called before this method. The resolution order supports per class filters (methods to be called before every method dispatch for every instance of this class) and per-object filters (to be called before every method dispatch of this object). Filters are defined in a filter chain, where object specific filters take precedence over class specific filters. Filters can change the results of methods. Immediately before and after certain methods pre- and post-conditions can be evaluated (similar to method-combinators in CLOS), between statements, invariants can be checked.</para>
<para>The invocation order defines the layering of methods, the method chaining (calling shadowed/filtered methods) is performed through the command next. Per-object filters, per-class filters, per-object mixins and per-class mixins can be applied conditionally based on tcl-expressions (guards) executed int the object context.</para>
<para>When an undefined method is invoked on an object, the call (method name and the arguments of the invocation) are passed to the method <emph style="bold">unknown</emph>. If no such method exists, an error message is generated.</para>
<para>The Tcl command ::oo::alias</para>
<verbatim><vline encoding='base64'>ICAgOjpvbzo6YWxpYXMgY2xhc3N8b2JqIG1ldGhvZE5hbWUgPy1vYmpzY29wZT8gPy1wZXItb2JqZWN0PyBjbWROYW1l</vline></verbatim>
<para>registers a command (<emph style="italic">cmdName</emph>) under a certain name (<emph style="italic">methodName</emph>) to an object or class (1st argument) to make the command available as a method. The options <emph style="italic">-objscope</emph> makes instance variables of the object/class appear as local variables, therefore Tcl commands to which variable names are passed (e.g. set, append, lappend, ...) can access instance variables without additional effort. </para>
<subsection title="Example for defining TclCOOL (Tcl Core Object Oriented Language)">

<subsubsection title="Create base and meta class:">
<verbatim><vline encoding='base64'>ICAgbmFtZXNwYWNlIGV2YWwgdGNsLWNvb2wge30=</vline><vline encoding='base64'>ICAgOjpvbzo6Y2xhc3MgYWxsb2MgOjp0Y2wtY29vbDo6b2JqZWN0</vline><vline encoding='base64'>ICAgOjpvbzo6Y2xhc3MgYWxsb2MgOjp0Y2wtY29vbDo6Y2xhc3M=</vline></verbatim>
<para>After creation, the classes ::tcl-cool::class and ::tcl-cool::object are instances of ::oo::class. This is not what we want to have. <emph style="italic">tcl-cool::object</emph> should be the most general superclass of TclCOOL, and <emph style="italic">tcl-cool::class</emph> should be the most general superclass of TclCOOL. Without this redefinition ::tcl-cool::class and ::tcl-cool::object would not have methods (except alloc and dealloc), even if we provide methods for these base classes.</para>
</subsubsection>
<subsubsection title="Define the basic class relations:">
<para>Since we are bootstrapping the language from a minimal command-set, we will use the setrelation command to define the basic relationships of the freshly defined classes.</para>
<para>First, we define that the superclasses of the newly defined class named <emph style="italic">::tcl-cool::class</emph>) should be the general meta-class ::oo::class and as well <emph style="italic">::tcl-cool::object</emph>. Therefore, ::tcl-cool::class will be a meta-class (its instances are classes) and it will inherit all properties of the most general TclCOOL class.</para>
<verbatim><vline encoding='base64'>ICAgOjpvbzo6c2V0cmVsYXRpb24gOjp0Y2w6OmNvb2w6OmNsYXNzIHN1cGVyY2xhc3Mgezo6b286OmNsYXNzIDo6dGNsLWNvb2w6Om9iamVjdH0g</vline></verbatim>
<para>The next two commands define that ::tcl-cool::object and ::tcl-cool::class are instances of ::tcl-cool::class. In other words, the class of e.g. ::tcl-cool::object is ::tcl-cool::class.</para>
<verbatim><vline encoding='base64'>ICAgOjpvbzo6c2V0cmVsYXRpb24gOjp0Y2wtY29vbDo6b2JqZWN0IGNsYXNzIDo6dGNsLWNvb2w6OmNsYXNzIA==</vline><vline encoding='base64'>ICAgOjpvbzo6c2V0cmVsYXRpb24gOjp0Y2wtY29vbDo6Y2xhc3MgIGNsYXNzIDo6dGNsLWNvb2w6OmNsYXNzIA==</vline></verbatim>
<para>The basic OO-relations of the two basic classes are defined. In a next step of the bootstrapping we attach methods to these classes.</para>
</subsubsection>
<subsubsection title="Define methods for classes:">
<para>We define 3 methods for <emph style="italic">::tcl-cool::class</emph> based on the method-set for classes:</para>
<itemize><item.i><para><emph style="italic">method</emph> is a means to define the methods, which are provided to the instances of the class (<emph style="italic">instproc</emph> in XOTcl)</para></item.i><item.i><para><emph style="italic">forward</emph> is a forwarder for instances of the object (<emph style="italic">instforward</emph> in XOTcl)</para></item.i><item.i><para><emph style="italic">info</emph> is an introspection method for classes</para><verbatim><vline encoding='base64'>ICAgOjpvbzo6YWxpYXMgOjp0Y2wtY29vbDo6Y2xhc3MgbWV0aG9kICA6Om9vOjptZXRob2RzZXQ6OmNsYXNzOjppbnN0cHJvYw==</vline><vline encoding='base64'>ICAgOjpvbzo6YWxpYXMgOjp0Y2wtY29vbDo6Y2xhc3MgZm9yd2FyZCA6Om9vOjptZXRob2RzZXQ6OmNsYXNzOjppbnN0Zm9yd2FyZA==</vline><vline encoding='base64'>ICAgOjpvbzo6YWxpYXMgOjp0Y2wtY29vbDo6Y2xhc3MgaW5mbyAgICA6Om9vOjptZXRob2RzZXQ6OmNsYXNzOjppbmZv</vline></verbatim></item.i></itemize>
</subsubsection>
<subsubsection title="Define methods for objects:">
<para>Next, we define 3 methods for <emph style="italic">object</emph> (actually <emph style="italic">::tcl-cool::object</emph>) based on the method-set for objects:</para>
<itemize><item.i><para><emph style="italic">variable</emph> is a means to import instance variables into the current scope (<emph style="italic">instvar</emph> in XOTcl)</para></item.i><item.i><para><emph style="italic">forward</emph> is a method for delegating calls to different objects</para></item.i><item.i><para><emph style="italic">info</emph> is an introspection method for objects</para><verbatim><vline encoding='base64'>ICAgOjpvbzo6YWxpYXMgOjp0Y2wtY29vbDo6b2JqZWN0IHZhcmlhYmxlIDo6b286Om1ldGhvZHNldDo6b2JqZWN0OjppbnN0dmFy</vline><vline encoding='base64'>ICAgOjpvbzo6YWxpYXMgOjp0Y2wtY29vbDo6b2JqZWN0IGZvcndhcmQgIDo6b286Om1ldGhvZHNldDo6b2JqZWN0Ojpmb3J3YXJk</vline><vline encoding='base64'>ICAgOjpvbzo6YWxpYXMgOjp0Y2wtY29vbDo6b2JqZWN0IGluZm8gICAgIDo6b286Om1ldGhvZHNldDo6b2JqZWN0OjppbmZv</vline></verbatim></item.i></itemize>
<para>The full definition of TclCOOL is available from [<url ref="http://media.wu-wien.ac.at/download/tcl-cool.tcl"/>]</para>
</subsubsection>
</subsection>
</section>
<section title="Methods from Extensions">
<para>This proposal defines only a small method-set (see above). However, it makes it straightforward to reuse the existing method-set (with maybe different names) without forcing an intermediate interpretation layer, or to load an additional method-set as extension. This additional method-set can be loaded dynamically via <emph style="bold">package require</emph>. The object system developer can provided the methods as Tcl commands in the extension&apos;s namespace. These commands can be attached to the objects and classes of the object system to be defined with the command <emph style="italic">::oo::alias</emph>.</para>
<para>The command alias should not allow extensions to register methods on <emph style="bold">::oo::object</emph> and <emph style="bold">::oo::class</emph>. All application object systems should only be allowed to register their methods on the language specific superclasses.</para>
<para>The exact API for methods accessing the dispatcher internals will be specified in another TIP.</para>
<para>The primitive commands (like <emph style="bold">my</emph>, <emph style="bold">next</emph>, <emph style="bold">self</emph>, <emph style="bold">configure</emph>, ...) are provided by the OO namespace, and these can be provided by the extension writers by accessing the dispatcher structure and its stack.</para>
</section>
<section title="Strengths of the Approach">
<itemize><item.i><para>All OO extensions can use the powerful dispatcher</para></item.i><item.i><para>If a certain extensions don&apos;t require filters, mixins, etc., they simply don&apos;t have to activate these.</para></item.i><item.i><para>The XOTcl dispatcher can be seen as a prototype implementation, but it should be replaced by a more efficient implementation with tighter core integration, provided the regression tests of the languages (e.g., XOTcl) continue to work.</para></item.i><item.i><para>The prototype implementation based on the current XOTcl 1.5.3 alpha release</para><itemize><item.i><para>is proven to work and sufficiently bug-free,</para></item.i><item.i><para>is free of memory leaks,</para></item.i><item.i><para>thread safe,</para></item.i><item.i><para>provides execution of the destroy callbacks when a thread or program exits,</para></item.i><item.i><para>provides uplevel transparency for interceptors,</para></item.i><item.i><para>is well suited for IDEs (an arbitrary class from a class tree can be reloaded and redefined without altering the relations between classes and/or instances)</para></item.i></itemize></item.i><item.i><para>All OO systems are treated equal</para><itemize><item.i><para>since we do not want to allow to register methods on <emph style="bold">::oo::object</emph> or <emph style="bold">::oo::class</emph>, there is no &quot;preferred&quot; object system,</para></item.i><item.i><para>every object system defines its own classes with its own names and own methods (although, it can reuse methods from all extensions with arbitrary names, as shown above)</para></item.i><item.i><para>there is no need to namespace export from &quot;oo::*&quot; (these are no end-user commands).</para></item.i><item.i><para>nobody is forced on any predefined semantics</para></item.i></itemize></item.i><item.i><para>no extensions are locked out</para><itemize><item.i><para>existing &quot;high level&quot; extensions (like XOTcl) and their applications (e.g. OpenACS) continue to work</para></item.i><item.i><para>since other OO language definitions are not part of the core, their development can continue, </para></item.i><item.i><para>other OO languages can easily benefit from the new core functionality</para></item.i><item.i><para>the dispatcher is based on a superset of the requirements of existing languages, so these should be able to use it.</para></item.i><item.i><para>extending the dispatcher requires a TIP.</para></item.i></itemize></item.i><item.i><para>This proposal is in the Tcl tradition of Tcl as a 2-level meta-language, since it provides a highly adjustable framework for object oriented languages.</para></item.i><item.i><para>Providing such a framework will attract people and put Tcl in front of the other OO scripting languages.</para></item.i></itemize>
</section>
<section title="Sample Implementation">
<itemize><item.i><para>XOTcl 1.5.3alpha is the reference dispatcher (it should be rewritten for inclusion in the core, and serves here only as proof-of-concept) [<url ref="http://media.wu-wien.ac.at/download/xotcl-1.5.3-alpha2.tar.gz"/>].</para></item.i><item.i><para>Example of the TclCOOL language (to be the <emph style="italic">part</emph> of the framework) [<url ref="http://media.wu-wien.ac.at/download/tcl-cool.tcl"/>]</para></item.i><item.i><para>Example of a subset of ITcl based on this TIP (implemented with the framework, runs already part of the itcl regression tests: protection.test and basic.test, in the latter, only three error messages differ) [<url ref="http://media.wu-wien.ac.at/download/itcl.tcl"/>]</para></item.i><item.i><para>Example of the XOTcl language (as implemented <emph style="italic">with</emph> the framework): See generic/predefined.xotcl in the XOTcl 1.5.3alpha reference implementation</para></item.i></itemize>
</section>
<section title="Copyright">
<para>This document has been placed in the public domain.</para>
</section>
</body></TIP>
