| <!DOCTYPE html |
| PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "../xhtml1-strict.dtd"> |
| <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> |
| <head> |
| <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> |
| <link rel="stylesheet" type="text/css" href="../css/ot.css" /> |
| <link rel="stylesheet" type="text/css" href="../css/otjld.css" /> |
| <title>OT/J Language Definition v1.3</title> |
| </head> |
| <body class="otdt"> |
| <div id="content"> |
| <table class="nav"> |
| <tr> |
| <td class="back"><a id="top"></a><a href="s1.2.1.html" rel="prev"><< §1.2.1 Modifiers for roles</a></td> |
| <td class="top"><a href="index.html" rel="contents">↑ Table of Contents ↑</a></td> |
| <td class="next"><a href="s1.2.3.html" rel="next">§1.2.3 Protected roles >></a></td> |
| </tr> |
| </table> |
| <div class="breadcrumb"><a class="nav" href="s1.html" rel="section">§1 Teams and Roles</a> > <a class="nav" href="s1.2.html" rel="section">§1.2 Role classes and objects</a></div> |
| <div class="sect depth3" id="s1.2.2"> |
| <h3 class="sect">§1.2.2 Externalized roles<a class="img" href="s1.2.2.html" |
| title="PermaLink to §1.2.2 Externalized roles"><img style="vertical-align:text-top;margin-left:5px;" src="../images/permalink.png" |
| alt="" /></a></h3> |
| <div class="syntaxlink"><a href="sA.html#sA.9.2" title="§A.9.2 ActualTypeArgument" |
| class="syntax">→ Syntax §A.9.2</a></div> |
| <p>Normally, a team encapsulates its role against unwanted access from the outside. |
| If roles are visible outside their enclosing team instance we speak of |
| <strong>externalized roles</strong>. |
| |
| </p> |
| <p>Externalized roles are subject to specific typing rules in order to ensure, |
| that role instances from different team instances cannot be mixed in |
| inconsistent ways. In the presence of implicit inheritance |
| (<a href="s1.3.1.html" |
| title="§1.3.1 Acquisition and implicit inheritance of role classes" |
| class="sect">§1.3.1</a>) inconsistencies could otherwise occur, which lead |
| to typing errors that could only be detected at run-time. |
| Externalized roles use the theory of |
| "virtual classes" <a href="s1.html#fn1-virtual-classes" class="int">[1]</a>, |
| or more specifically |
| "family polymorphism" <a href="s1.html#fn2-family-polymorphism" class="int">[2]</a>, |
| in order to achieve the desired type safety. |
| These theories use special forms of <em>dependent types</em>. |
| Externalized roles have <em>types that depend on a team instance</em>. |
| |
| </p> |
| <p><a href="s1.2.3.html" title="§1.2.3 Protected roles" class="sect">§1.2.3</a> deduces even stronger forms of encapsulation |
| from the rules about externalized roles. |
| |
| </p> |
| <div class="subsect depth4" id="s1.2.2.a"> |
| <h4 class="subsect">(a) <span class="title">Visibility</span><a class="img" href="s1.2.2.a.html" title="PermaLink to (a) Visibility"><img style="vertical-align:text-top;margin-left:5px;" src="../images/permalink.png" |
| alt="" /></a></h4> |
| <p>Only instances of a <code>public</code> role class can ever be externalized. |
| |
| </p> |
| </div> |
| <div class="subsect depth4" id="s1.2.2.b"> |
| <h4 class="subsect">(b) <span class="title">Declaration with anchored type</span><a class="img" href="s1.2.2.b.html" |
| title="PermaLink to (b) Declaration with anchored type"><img style="vertical-align:text-top;margin-left:5px;" src="../images/permalink.png" |
| alt="" /></a></h4> |
| <p>Outside a team role types are legal only if denoted relative |
| to an existing team instance (further on called "anchored types"). |
| The syntax is: |
| </p> |
| <div class="listing plain"><pre><em>final</em> MyTeam myTeam = <i>expression</i>; |
| <em>RoleClass<@myTeam></em> role = <i>expression</i>;</pre></div> |
| <p>The syntax <code>Type<@anchor></code> is a special case of a parameterized type, more specifically a <a href="s9.html" title="§9 Value Dependent Classes" class="sect">value dependent type (§9)</a>. |
| The type argument (i.e., the expression after the at-sign) can be a simple name or a path. It must refer to an instance |
| of a team class. |
| The role type is said to be <em>anchored</em> to this team instance.<br /> |
| The type-part of this syntax (in front of the angle brackets) must be the simple name of a role type directly contained |
| in the given team (including roles that are acquired by implicit inheritance).<br /></p> |
| <div class="note"> |
| <h5>Note:</h5> |
| Previous versions of the OTJLD used a different syntax for anchored types, where the role type was prefixed with the anchor |
| expression, separated by a dot (<code>anchor.Type</code>, |
| see <a href="sA.html#sA.6.3" title="§A.6.3 AnchoredType" class="sect">§A.6.3</a>). A compiler may still support that path syntax but it should be flagged as being deprecated. |
| |
| </div> |
| </div> |
| <div class="subsect depth4" id="s1.2.2.c"> |
| <h4 class="subsect">(c) <span class="title">Immutable anchor</span><a class="img" href="s1.2.2.c.html" |
| title="PermaLink to (c) Immutable anchor"><img style="vertical-align:text-top;margin-left:5px;" src="../images/permalink.png" |
| alt="" /></a></h4> |
| <p>Anchoring the type of an externalized role to a team instance |
| requires the team to be referenced by a variable which |
| is marked <code>final</code> (i.e., immutable). |
| The type anchor can be a path <code>v.f1.f2...</code> where |
| <code>v</code> is any final variable and <code>f1</code> ... |
| are final fields. |
| |
| </p> |
| </div> |
| <div class="subsect depth4" id="s1.2.2.d"> |
| <h4 class="subsect">(d) <span class="title">Implicit type anchors</span><a class="img" href="s1.2.2.d.html" |
| title="PermaLink to (d) Implicit type anchors"><img style="vertical-align:text-top;margin-left:5px;" src="../images/permalink.png" |
| alt="" /></a></h4> |
| <p>The current team instance can be used as a default anchor |
| for role types: |
| |
| </p> |
| <ol> |
| <li>In non-static team level methods role types are by default interpreted as anchored to <code>this</code> (referring to the team instance). I.e., the following two declarations express the same: |
| |
| <div class="listing plain"><pre><b>public</b> RoleX getRoleX (RoleY r) { <i> stmts </i> } |
| <b>public</b> RoleX<@<em>this</em>> getRoleX (RoleY<@<em>this</em>> r) { <i> stmts </i> }</pre></div> |
| </li> |
| <li> |
| In analogy, <em>role methods</em> use the enclosing team instance as the |
| default anchor for any role types. |
| </li> |
| </ol> |
| <p>Note, that <code>this</code> and <code><em>Outer</em>.this</code> are always |
| <code>final</code>.<br /> |
| The compiler uses the pseudo identifier <strong><code>tthis</code></strong> to denote |
| such implicit type anchors in error messages. |
| |
| </p> |
| </div> |
| <div class="subsect depth4" id="s1.2.2.e"> |
| <h4 class="subsect">(e) <span class="title">Conformance</span><a class="img" href="s1.2.2.e.html" title="PermaLink to (e) Conformance"><img style="vertical-align:text-top;margin-left:5px;" src="../images/permalink.png" |
| alt="" /></a></h4> |
| <p>Conformance between |
| two types <code>RoleX<@teamA></code> and <code>RoleY<@teamB></code> |
| not only requires the role types to be compatible, but also |
| the team instances to be provably <em>the same object</em>. |
| The compiler must be able to statically analyze anchor identity. |
| |
| </p> |
| </div> |
| <div class="subsect depth4" id="s1.2.2.f"> |
| <h4 class="subsect">(f) <span class="title">Substitutions for type anchors</span><a class="img" href="s1.2.2.f.html" |
| title="PermaLink to (f) Substitutions for type anchors"><img style="vertical-align:text-top;margin-left:5px;" src="../images/permalink.png" |
| alt="" /></a></h4> |
| <p>Only two substitutions are considered for determining |
| team identity: |
| |
| </p> |
| <ol> |
| <li> |
| For type checking the application of team methods, |
| <code>this</code> is <strong>substituted</strong> by the actual call target. |
| For role methods a reference of the form <code><em>Outer</em>.this</code> |
| is substituted by the enclosing instance of the call target. |
| |
| </li> |
| <li>Assignments from a <code>final</code> identifier |
| to another <code>final</code> identifier are transitively |
| followed, i.e., if <code>t1, t2</code> are final, |
| after an assignment <code>t1=t2</code> |
| the types <code>R<@t1></code> and <code>R<@t2></code> are considered |
| identical. Otherwise <code>R<@t1></code> and <code>R<@t2></code> |
| are incommensurable.<br /> |
| Attaching an actual parameter to a formal parameter in a |
| method call is also considered as an assignment with respect to |
| this rule. |
| |
| </li> |
| </ol> |
| </div> |
| <div class="subsect depth4" id="s1.2.2.g"> |
| <h4 class="subsect">(g) <span class="title">Legal contexts</span><a class="img" href="s1.2.2.g.html" title="PermaLink to (g) Legal contexts"><img style="vertical-align:text-top;margin-left:5px;" src="../images/permalink.png" |
| alt="" /></a></h4> |
| <p>Anchored types for externalized roles may be used in the |
| following contexts: |
| |
| </p> |
| <ol> |
| <li>Declaration of an attribute</li> |
| <li>Declaration of a local variable</li> |
| <li>Declaration of a parameter or result type |
| of a method or constructor |
| </li> |
| <li>In the <code>playedBy</code> clause of a role class |
| (see <a href="s2.1.html" title="§2.1 playedBy relation" class="sect">§2.1</a>). |
| </li> |
| </ol> |
| <p>It is not legal to inherit from an anchored type, since |
| this would require membership of the referenced team instance, |
| which can only be achieved by class nesting. |
| |
| </p> |
| <div class="note"> |
| <h5>Note:</h5> |
| Item 4. |
| — within the given restriction — admits the case where |
| the same class is a role of one team and the base class for |
| the role of another team. Another form of nesting is |
| defined in <a href="s1.5.html" title="§1.5 Team and role nesting" class="sect">§1.5</a>. |
| |
| </div> |
| </div> |
| <div class="subsect depth4" id="s1.2.2.h"> |
| <h4 class="subsect">(h) <span class="title">Externalized creation</span><a class="img" href="s1.2.2.h.html" |
| title="PermaLink to (h) Externalized creation"><img style="vertical-align:text-top;margin-left:5px;" src="../images/permalink.png" |
| alt="" /></a></h4> |
| <p>A role can be created as externalized using either of these equivalent forms:</p> |
| <div class="listing plain"><pre>outer.<b>new</b> Role() |
| <b>new</b> Role<@outer>()</pre></div> |
| <p>This requires the enclosing instance <code>outer</code> to be |
| declared <code>final</code>. The expression has the |
| type <code>Role<@outer></code> following the rules of |
| externalized roles.<br /> |
| The type <code>Role</code> in this expression must be a simple |
| (unqualified) name. |
| |
| </p> |
| </div> |
| <div class="subsect depth4" id="s1.2.2.i"> |
| <h4 class="subsect">(i) <span class="title">No import</span><a class="img" href="s1.2.2.i.html" title="PermaLink to (i) No import"><img style="vertical-align:text-top;margin-left:5px;" src="../images/permalink.png" |
| alt="" /></a></h4> |
| <p>It is neither useful nor legal to import a role type.<br /></p> |
| <div class="note"> |
| <h5>Rationale:</h5> |
| Importing a type allows to use the unqualified name in situations that would otherwise require to use the fully qualified |
| name, |
| i.e., the type prefixed with its containing package and enclosing class. Roles, however are contained in a team <i>instance</i>. |
| Outside their team, role types can only be accessed using an anchored type which uses a team instance to qualify the |
| role type. |
| Relative to this team anchor, roles are <i>always</i> denoted using their simple name, which makes importing roles useless. |
| |
| </div> |
| <p>A static import for a constant declared in a role is, however, legal. |
| |
| </p> |
| </div> |
| <h5 class="listing">Example code (Externalized Roles):</h5> |
| <div class="listing example frame" id="l1.2.2-1"> |
| <table class="listing"> |
| <tr class="line odd"> |
| <td class="ln">1</td> |
| <td><pre><b>team</b> <b>class</b> FlightBonus <b>extends</b> Bonus {</pre></td> |
| </tr> |
| <tr class="line even"> |
| <td class="ln">2</td> |
| <td><pre> <b>public</b> <b>class</b> Subscriber {</pre></td> |
| </tr> |
| <tr class="line odd"> |
| <td class="ln">3</td> |
| <td><pre> <b>void</b> clearCredits() { ... }</pre></td> |
| </tr> |
| <tr class="line even"> |
| <td class="ln">4</td> |
| <td><pre> }</pre></td> |
| </tr> |
| <tr class="line odd"> |
| <td class="ln">5</td> |
| <td><pre> <b>void</b> unsubscribe(Subscriber subscr) { ... }</pre></td> |
| </tr> |
| <tr class="line even"> |
| <td class="ln">6</td> |
| <td><pre>}</pre></td> |
| </tr> |
| </table> |
| </div> |
| <div class="listing example frame" id="l1.2.2-2"> |
| <table class="listing"> |
| <tr class="line odd"> |
| <td class="ln">7</td> |
| <td><pre><b>class</b> ClearAction <b>extends</b> Action {</pre></td> |
| </tr> |
| <tr class="line even"> |
| <td class="ln">8</td> |
| <td><pre> <em>final</em> FlightBonus context;</pre></td> |
| </tr> |
| <tr class="line odd"> |
| <td class="ln">9</td> |
| <td><pre> <em>Subscriber<@context></em> subscriber;</pre></td> |
| </tr> |
| <tr class="line even"> |
| <td class="ln">10</td> |
| <td><pre> ClearAction (<em>final</em> FlightBonus bonus, <em>Subscriber<@bonus></em> subscr) {</pre></td> |
| </tr> |
| <tr class="line odd"> |
| <td class="ln">11</td> |
| <td><pre> context = bonus; <span class="comment">// unique assignment to 'context'</span></pre></td> |
| </tr> |
| <tr class="line even"> |
| <td class="ln">12</td> |
| <td><pre> subscriber = subscr;</pre></td> |
| </tr> |
| <tr class="line odd"> |
| <td class="ln">13</td> |
| <td><pre> }</pre></td> |
| </tr> |
| <tr class="line even"> |
| <td class="ln">14</td> |
| <td><pre> <b>void</b> actionPerformed () {</pre></td> |
| </tr> |
| <tr class="line odd"> |
| <td class="ln">15</td> |
| <td><pre> subscriber.clearCredits();</pre></td> |
| </tr> |
| <tr class="line even"> |
| <td class="ln">16</td> |
| <td><pre> }</pre></td> |
| </tr> |
| <tr class="line odd"> |
| <td class="ln">17</td> |
| <td><pre> <b>protected</b> <b>void</b> finalize () {</pre></td> |
| </tr> |
| <tr class="line even"> |
| <td class="ln">18</td> |
| <td><pre> context.unsubscribe(subscriber);</pre></td> |
| </tr> |
| <tr class="line odd"> |
| <td class="ln">19</td> |
| <td><pre> }</pre></td> |
| </tr> |
| <tr class="line even"> |
| <td class="ln">20</td> |
| <td><pre>}</pre></td> |
| </tr> |
| </table> |
| </div> |
| <div class="codecomment"> |
| <h5>Effects:</h5> |
| <ul> |
| <li>Lines 1-6 show a terse extract of a published example |
| <a href="http://www.objectteams.org/publications/index.html#NODe02" class="ext">[NODe02]</a>. Here passengers can be subscribers in a flight bonus program. |
| </li> |
| <li>Lines 7-20 show a sub-class of <code>Action</code> which is |
| used to associate the action of resetting a subscriber's credits |
| to a button or similar element in an application's GUI. |
| </li> |
| <li>Attribute <code>context</code> (line 8) and parameter |
| <code>bonus</code> (line 10) serve as anchor for the type of |
| externalized roles. |
| </li> |
| <li>Attribute <code>subscriber</code> (line 9) and parameter |
| <code>subscr</code> (line 10) store a Subscriber role outside the |
| FlightBonus team. |
| </li> |
| <li>In order to type-check the assignment in line 12, the compiler |
| has to ensure that the types of LHS and RHS are anchored to |
| the same team instance. This can be verified by checking that |
| both anchors are indeed <code>final</code> and prior to the |
| role assignment a team assignment has taken place (line 11).<br /><span class="underline">Note,</span> that the Java rules for <strong>definite assignments</strong> to |
| final variables ensure that exactly one assignment to a variable occurs |
| prior to its use as type anchor. No further checks are needed. |
| |
| </li> |
| <li>It is now legal to store this role reference and use it at |
| some later point in time, e.g., for invoking method |
| <code>clearCredits</code> (line 15). |
| This method call is also an example for implicit team activation |
| (<a href="s5.3.b.html" title="§5.3.(b) Methods of externalized roles" |
| class="sect">§5.3.(b)</a>). |
| |
| </li> |
| <li>Line 18 demonstrates how an externalized role can be |
| passed to a team level method. The signature of <code>unsubscribe</code> |
| is for this call expanded to |
| <div class="indent"> |
| void unsubscribe(Subscriber<@context> subscr) |
| |
| </div> |
| (by substituting the call target <code>context</code> for |
| <code>this</code>). This proves identical types for actual and |
| formal parameters. |
| </li> |
| </ul> |
| </div> |
| </div> |
| <table class="nav"> |
| <tr> |
| <td class="back"><a href="s1.2.1.html" rel="prev"><< §1.2.1 Modifiers for roles</a></td> |
| <td class="top"><a href="index.html" rel="contents">↑ Table of Contents ↑</a></td> |
| <td class="next"><a href="s1.2.3.html" rel="next">§1.2.3 Protected roles >></a></td> |
| </tr> |
| </table> |
| <div class="breadcrumb"><a class="nav" href="s1.html" rel="section">§1 Teams and Roles</a> > <a class="nav" href="s1.2.html" rel="section">§1.2 Role classes and objects</a></div> |
| </div> |
| <div id="footer"> |
| <hr /><a class="w3c img" href="http://jigsaw.w3.org/css-validator/check/referer" |
| shape="rect"><img src="../images/valid-css2-blue.png" alt="Valid CSS!" height="31" width="88" /></a><a class="w3c img" href="http://validator.w3.org/check?uri=referer" shape="rect"><img src="../images/valid-xhtml10-blue.png" alt="Valid XHTML 1.0 Strict" height="31" |
| width="88" /></a><address>© Stephan Herrmann, Christine Hundt, Marco Mosconi</address> |
| OT/J version 1.3 — last modified: 2010-06-08 |
| </div> |
| </body> |
| </html> |