<commit_before><chapter id="typesystem">
    <title>Type system overview</title>
    
    <para>Every value in a Ceylon program is an instance of a type that can be expressed 
    within the Ceylon language as a <emphasis>class</emphasis>. The language does not 
    define any primitive or compound types that cannot, in principle, be expressed within 
    the language itself.</para>
    
    <para>A class is a recipe for producing new values, and defines the operations and
    attributes of the resulting values. Each class declaration defines a type. However, 
    not all types are classes. It is often advantageous to write generic code that 
    abstracts the concrete class of a value. This technique is called 
    <emphasis>polymorphism</emphasis>. Ceylon supports two different kinds of polymorphism:</para>
    
    <itemizedlist>
        <listitem>
            <para><emphasis>subtype polymorphism</emphasis>, where a subtype <literal>B</literal>
            inherits a supertype <literal>A</literal>, and</para>
        </listitem>
        <listitem>
            <para><emphasis>parametric polymorphism</emphasis>, where a type definition 
            <literal>A&lt;T&gt;</literal> is parameterized by a <emphasis>generic type 
            parameter</emphasis> <literal>T</literal>.</para>
        </listitem>
    </itemizedlist>
    
    <para>Ceylon, like Java and many other object-oriented languages, supports a single
    inheritance model for classes. A class may directly inherit at most one other class, 
    and all classes eventually inherit, directly or indirectly, the class 
    <literal>ceylon.language.Void</literal>, which acts as the root of the class hierarchy.</para>
    
    <para>A truly hierarchical type system is much too restrictive for more abstract 
    programming tasks. Therefore, in addition to classes, Ceylon recognizes the following 
    kinds of type:</para>
    
    <itemizedlist>
        <listitem>
            <para>An <emphasis>interface</emphasis> declares a set of operations and
            attributes that must be provided by every class that <emphasis>implements</emphasis>
            the interface. A class may implement many interfaces.</para>
        </listitem>
        <listitem>
            <para>A <emphasis>union</emphasis> is a type whose value may be a value of 
            any one of an enumerated list of classes. <emphasis>Note: Union types are 
            a feature proposed for inclusion in a future version of the language.</emphasis></para>
        </listitem>
        <listitem>
            <para>A <emphasis>generic type parameter</emphasis> is considered a type
            within the declaration that it parameterizes. In fact, it is an abstraction
            over many types: it generalizes the declaration to all types which could be 
            substituted for the parameter.</para>
        </listitem>
        <listitem>
            <para>A <emphasis>produced type</emphasis> is formed by specifying arguments
            for the generic type parameters of a parameterized type.</para>
        </listitem>
    </itemizedlist>
    
    <para>The Ceylon type system is much more complete than most other object oriented
    languages. In Ceylon, it's possible to answer questions that might at first sound
    almost nonsensical if you're used to languages with more traditional type systems. 
    For example:</para>
    
    <itemizedlist>
        <listitem>
            <para>What is the return type of a <literal>void</literal> method?</para>
        </listitem>
        <listitem>
            <para>What is the type of an local that may or may not hold a value of 
            type <literal>T</literal>?</para>
        </listitem>
        <listitem>
            <para>What is the type that represents methods that accept two <literal>Float</literal>
            values?</para>
        </listitem>
        <listitem>
            <para>What is the type of an expression that may be evaluated to produce
            a <literal>String</literal>?</para>
        </listitem>
        <listitem>
            <para>What is the type of a sequence of natural numbers of length <literal>n+1</literal>?</para>
        </listitem>
        <listitem>
            <para>What is the type that represents subclasses of <literal>Renderer</literal> 
            which must be provided at instantiation time with a function that accepts an 
            object and produces a <literal>String</literal>?</para>
        </listitem>
    </itemizedlist>
    
    <para>The answers, as we shall discover, are: <literal>Void</literal>, 
    <literal>Optional&lt;T&gt;</literal>, <literal>Method&lt;Object, Void, Float, Float&gt;</literal>,
    <literal>Gettable&lt;String&gt;</literal>, <literal>BoundedSequence&lt;n+1&gt;</literal>, 
    and <literal>Class&lt;Renderer, Callable&lt;String,Object&gt;&gt;</literal>.</para>
    
    <!--itemizedlist>
        <listitem>
            <para><literal>Void</literal>, </para>
        </listitem>
        <listitem>
            <para><literal>Optional&lt;T&gt;</literal></para>
        </listitem>
        <listitem>
            <para><literal>Method&lt;Void, Float, Float&gt;</literal>, and</para>
        </listitem>
        <listitem>
            <para><literal>Gettable&lt;String&gt;</literal>.</para>
        </listitem>
    </itemizedlist-->
    

    <section id="identifiernaming">
        <title>Identifier naming</title>

        <para>The Ceylon compiler enforces identifier naming conventions. Types must
        be named with an initial uppercase. Members, parameters and locals must be 
        named with an initial lowercase or underscore. A package name element is an
        all-lowercase identifier.</para>
        
        <programlisting>PackageName := PIdentifier</programlisting>
        <programlisting>TypeName := UIdentifier</programlisting>
        <programlisting>MemberName := LIdentifier</programlisting>
        <programlisting>ParameterName := LIdentifier</programlisting>
        
        <para>An underscore <literal>_</literal> is considered a lowercase letter.</para>
        
        <para>Ceylon defines three identifier namespaces:</para>
        
        <itemizedlist>
            <listitem>
                <para>classes, interfaces and aliases share a single namespace,</para>
            </listitem>
            <listitem>
                <para>methods, attributes and locals share a single namespace, and</para>
            </listitem>
            <listitem>
                <para>packages have their own dedicated namespace.</para>
            </listitem>
        </itemizedlist>
        
        <para>The Ceylon parser is able to unambiguously identify which namespace an 
        identifier belongs to.</para>
        
    </section>
      
    <section id="type">
        <title>Types</title>
    
        <para>A <emphasis>type</emphasis> or <emphasis>type schema</emphasis> is name 
        (an initial uppercase identifier) and an optional list of type parameters, with 
        a set of:</para>
        
        <itemizedlist>
            <listitem>
                <para>attribute schemas,</para>
            </listitem>
            <listitem>
                <para>method schemas, and</para>
            </listitem>
            <listitem>
                <para>class schemas.</para>
            </listitem>
        </itemizedlist>
        
        <para>The attribute, method, and class schemas are called the 
        <emphasis>members</emphasis> of the type.</para>
        
        <para>Speaking formally:</para>
        
        <itemizedlist>
            <listitem>
                <para>An <emphasis>attribute schema</emphasis> is a name (an initial 
                lowercase identifier) with a type and mutability.</para>
            </listitem>
            <listitem>
                <para>A <emphasis>method schema</emphasis> is a name (an initial lowercase 
                identifier) and an optional list of type parameters, with a type (often 
                called the <emphasis>return type</emphasis>) and a list of one or more 
                formal parameter lists.</para>
            </listitem>
            <listitem>
                <para>A <emphasis>class schema</emphasis> is a type schema with a formal 
                parameter list.</para>
            </listitem>
            <listitem>
                <para>A <emphasis>formal parameter list</emphasis> is a list of names 
                (initial lowercase identifiers) with types. The 
                <emphasis>signature</emphasis> of a formal parameter list is formed by 
                discarding the names, leaving the list of types.</para>
            </listitem>
        </itemizedlist>
        
        <para>Speaking slightly less formally, we usually refer to an attribute, method, or 
        member class of a type, meaning an attribute schema, method schema or class schema
        that is a member of the type.</para>
        
        <section id="memberdistinctness">
            <title>Member distinctness</title>
        
        <para>The <emphasis>erased signature</emphasis> of a method or class is formed by:</para>
        
        <itemizedlist>
            <listitem>
                <para>taking the signature of the formal parameter list of the member class, 
                or of the first formal parameter list of the method, and</para>
            </listitem>
            <listitem>
                <para>replacing each occurrence of any type alias in the signature with the
                aliased type, and</para>
            </listitem>
            <listitem>
                <para>replacing each occurrence of <literal>Optional&lt;T&gt;</literal> in 
                the signature with <literal>T</literal>, and</para>
            </listitem>
            <listitem>
                <para>replacing each occurrence of any type parameter in the signature with 
                the first declared upper bound of the type parameter, or <literal>ceylon.language.Void</literal> 
                if there is no declared upper bound, and</para>
            </listitem>
            <listitem>
                <para>replacing the type of any sequenced type parameter in the signature with 
                <literal>ceylon.language.Void...</literal>, and then</para>
            </listitem>
            <listitem>
                <para>discarding the type arguments of each element of the list, leaving just 
                the name of a class or interface.</para>
            </listitem>
        </itemizedlist>
        
        <comment><para>Note: I really, really hate this stuff. Is there any way we can do 
        better than Java here?</para></comment>
        
        <para>Two erased signatures are considered <emphasis>distinct</emphasis> if they 
        have different lengths, or if at some position within the lists, the two types are 
        non-identical.</para>
        
        <comment><para>TODO: non-identical, or non-assignable?</para></comment>
        
        <comment><para>TODO: what about sequenced parameters? what does Java do?</para></comment>
            
        <para>A type may not have:</para>
        
        <itemizedlist>
            <listitem>
                <para>two attributes with the same name,</para>
            </listitem>
            <listitem>
                <para>a method and an attribute with the same name,</para>
            </listitem>
            <listitem>
                <para>two methods with the same name and non-distinct erased signatures, 
                or</para>
            </listitem>
            <listitem>
                <para>two member classes with the same name and non-distinct erased signatures.</para>
            </listitem>
        </itemizedlist>
        
        </section>
        
        <section id="subtyping">
            <title>Subtyping</title>
        
        <para>A type may be a <emphasis>subtype</emphasis> of another type. Subtyping obeys 
        the following rules:</para>
        
        <itemizedlist>
            <listitem>
                <para>Identity: <literal>X</literal> is a subtype of <literal>X</literal>.</para>
            </listitem>
            <listitem>
                <para>Transitivity: if <literal>X</literal> is a subtype of <literal>Y</literal>
                and <literal>Y</literal> is a subtype of <literal>Z</literal> then
                <literal>X</literal> is a subtype of <literal>Z</literal>.</para>
            </listitem>
            <listitem>
                <para>Interfaces and unions are objects: all interfaces and unions are subtypes 
                of <literal>ceylon.language.Object</literal>. Conversely, only a subtype of 
                <literal>ceylon.language.Object</literal> may satisfy an interface or be an
                enumerated subtype of a union.</para>
            </listitem>
            <listitem>
                <para>Single root: all types are subtypes of <literal>ceylon.language.Void</literal>.</para>
            </listitem>
        </itemizedlist>
        
        
        </section>
        
        <section id="assignability">
            <title>Assignability</title>
        
        <para>In a certain compilation unit, a type may be <emphasis>assignable</emphasis> 
        to another type. If, in some compilation unit, <literal>X</literal> is assignable 
        to <literal>Y</literal>, then:</para>
        
        <itemizedlist>
            <listitem>
                <para>For each non-<literal>mutable</literal> attribute of <literal>Y</literal>, 
                <literal>X</literal> has an attribute with the same name, whose type is 
                assignable to the type of the attribute of <literal>Y</literal>.</para>
            </listitem>
            <listitem>
                <para>For each <literal>mutable</literal> attribute of <literal>Y</literal>, 
                <literal>X</literal> has a <literal>mutable</literal> attribute with the 
                same name and the same type.</para>
            </listitem>
            <listitem>
                <para>For each method of <literal>Y</literal>, <literal>X</literal>
                has a method with the same name, with the same number of formal parameter 
                lists, with the same signatures, and whose return type is assignable to the 
                return type of the method of <literal>Y</literal>.</para>
            </listitem>
            <listitem>
                <para>For each member class of <literal>Y</literal>, <literal>X</literal>
                has a member class of the same name, with a formal parameter list with 
                the same signature, that is assignable to the member class of 
                <literal>Y</literal>.</para>
            </listitem>
        </itemizedlist>
        
        <para>Assignability obeys the following rules:</para>
        
        <itemizedlist>
            <listitem>
                <para>Identity: <literal>X</literal> is assignable to <literal>X</literal>.</para>
            </listitem>
            <listitem>
                <para>Subtyping: if <literal>Y</literal> is a subtype of <literal>X</literal> 
                then <literal>Y</literal> is assignable to <literal>X</literal>.</para>
            </listitem>
            <listitem>
                <para>Transitivity: if <literal>X</literal> is assignable to <literal>Y</literal>
                and <literal>Y</literal> is assignable to <literal>Z</literal> then
                <literal>X</literal> is assignable to <literal>Z</literal>.</para>
            </listitem>
            <listitem>
                <para>Lazy evaluation: the type <literal>Gettable&lt;T&gt;</literal> is 
                assignable to <literal>T</literal> for every type <literal>T</literal>.</para>
            </listitem>
            <!--
            <listitem>
                <para>Nullsafety: the type <literal>Optional&lt;T&gt;</literal> is 
                not assignable to <literal>Object</literal>. Nor is its subtype
                <literal>Nothing</literal>.</para>
            </listitem>
            -->
        </itemizedlist>
        
        <para>A type <literal>X</literal> may be assignable to a type <literal>Y</literal>
        even if <literal>X</literal> is not a subtype of <literal>Y</literal> if there is 
        an enabled extension which introduces <literal>Y</literal> to <literal>X</literal>.</para>
        
        </section>
        
        <section id="typeofaprogramelement">
            <title>Type of a program element</title>
        
        <para>Method, attribute and formal parameter declarations must declare a type.</para>
        
        <para>Types are identified by the name of the type (a class, interface, alias or 
        type parameter), together with a list of type arguments if the type definition 
        specifies type parameters.</para>
        
        <programlisting>Type := ( TypeNameWithArguments ("." TypeNameWithArguments)* | "subtype" ) Abbreviation*</programlisting>
        
        <para>If a type has type parameters or a sequenced type parameter, a type argument 
        list must be specified. If a type has no type parameters, and no sequenced type 
        parameter, no type argument list may be specified.</para>        
        
         <para>Unlike Java, the name of a type may not be qualified by the package name.</para>

        <para>Certain declarations which usually require an explicit type may omit the type, 
        forcing the compiler to infer it, by specifying the keyword <literal>local</literal>
        where the type usually appears.</para>
        
        <programlisting>InferableType := Type | "local"</programlisting>
        
        <para>Type inference is only allowed for block local declarations. The keyword
        <literal>local</literal> may not be combined with a visibility modifier annotation.</para>
        
        </section>
        
        <section id="typenameabbreviations">
            <title>Type name abbreviations</title>
            
        <para>The following type name abbreviations are supported:</para>
        
        <itemizedlist>
            <listitem>
                <para><literal>X?</literal> means <literal>Optional&lt;X&gt;</literal> for
                any type <literal>X</literal>,</para>
            </listitem>
            <listitem>
                <para><literal>X[]</literal> means <literal>Sequence&lt;X&gt;</literal> for
                any type <literal>X</literal>, and</para>
            </listitem>
            <listitem>
                <para><literal>X[n]</literal> means <literal>BoundedSequence&lt;X,#n&gt;</literal> 
                for any type <literal>X</literal> and dimension <literal>n</literal>.</para>
            </listitem>
        </itemizedlist>
        
        <programlisting>Abbreviation := "?" | "[" dimension? "]"</programlisting>
        
        <para>Abbreviations may be combined:</para>
        
        <programlisting>String?[3] words = { "hello", "world", null };
String? firstWord = words[0];</programlisting>
        
        <comment><para>TODO: It might be difficult to support <literal>T??</literal>
        since <literal>Optional</literal> is erased.</para></comment>
        
        <comment><para>TODO: Java lets you put the <literal>[]</literal> after the variable
        name. C requires that. Should we support/require this variation? It is consistent
        with how we declare functional parameters!</para></comment>
        
        </section>
    
    </section>
        
    <section id="inheritance">
        <title>Inheritance</title>
        
        <para>Subtyping is a static relationship between classes, interfaces, and type 
        parameters, produced through the use of <emphasis>inheritance</emphasis>:</para>
        
        <itemizedlist>
            <listitem>
                <para>a class may <emphasis>extend</emphasis> another class,</para>
            </listitem>
            <listitem>
                <para>a class may <emphasis>implement</emphasis> one or more interfaces,</para>
            </listitem>
            <listitem>
                <para>an interface may <emphasis>extend</emphasis> one or more other interfaces,</para>
            </listitem>
            <listitem>
                <para>a union may <emphasis>satisfy</emphasis> one or more interfaces,</para>
            </listitem>
            <listitem>
                <para>a type parameter may <emphasis>satisfy</emphasis> a class and/or one or 
                more interfaces or type parameters, or</para>
            </listitem>
            <listitem>
                <para>a type parameter may <emphasis>abstract</emphasis> a class, interface or 
                type parameter.</para>
            </listitem>
        </itemizedlist>
        
        <comment><para>TODO: should we let an interface extend a class other than <literal>Object</literal>?</para></comment>
    
    <section id="extendedclass">
        <title>Extension</title>
    
        <para>A class may extend another class.</para>
        
        <programlisting>ExtendedType := "extends" Type PositionalArguments</programlisting>
    
        <para>The <literal>extends</literal> clause must specify exactly one superclass. 
        If the superclass is a parameterized type, the <literal>extends</literal> clause 
        must specify type arguments. The <literal>extends</literal> clause must specify 
        arguments for the initializer parameters of the superclass.</para>
        
        <programlisting>extends Person(name, org)</programlisting>
    
        <para>
        If a class does not explicitly specify a superclass using <literal>extends</literal>,
        its superclass is <literal>ceylon.language.BaseObject</literal>. <!--There is one exception 
        to this rule: the built-in class <literal>ceylon.language.Void</literal> which does not have 
        a superclass.-->
        </para>
        
        <para>
        The root class <literal>ceylon.language.Void</literal> does not have a superclass.
        </para>
        
        <para>Suppose <literal>X</literal> and <literal>Y</literal> are classes.</para>
    
        <itemizedlist>
        <listitem>
            <para>If <literal>X</literal> extends <literal>Y</literal>, then
            <literal>X</literal> is a subtype of <literal>Y</literal>.</para>
        </listitem>
        <listitem>
            <para>If <literal>X</literal> extends <literal>Y&lt;B&gt;</literal>, then
            <literal>X</literal> is a subtype of <literal>Y&lt;B&gt;</literal>.</para>
        </listitem>
        <listitem>
            <para>If <literal>X&lt;T&gt;</literal> extends <literal>Y&lt;T&gt;</literal>, 
            then <literal>X&lt;B&gt;</literal> is a subtype of <literal>Y&lt;B&gt;</literal> 
            for any type <literal>B</literal>.</para>
        </listitem>
        <listitem>
            <para>If <literal>X&lt;T&gt;</literal> extends <literal>Y</literal>, 
            then <literal>X&lt;B&gt;</literal> is a subtype of <literal>Y</literal> 
            for any type <literal>B</literal>.</para>
        </listitem>
        </itemizedlist>
        
        <para>A user-defined class must extend <literal>ceylon.language.Object</literal>
        or one of its subclasses.</para>
        
    </section>
    
    <section id="satisfiedinterfaces">
        <title>Satisfaction</title>
    
        <para>A class may implement one or more interfaces. An interface may extend one
        or more interfaces. A union may satisfy one or more interfaces. A type parameter 
        may satisfy one or more interfaces and, optionally, a class.</para>
        
        <programlisting>SatisfiedTypes = "satisfies" Type ("," Type)*</programlisting>
    
        <para>The <literal>satisfies</literal> clause may specify multiple types. If 
        a satisfied type is a parameterized type, the <literal>satisfies</literal> clause 
        must specify type arguments.</para>
        
        <programlisting>satisfies T[], Collection&lt;T&gt;</programlisting>
        
        <para>Suppose <literal>Y</literal> is an interface and <literal>X</literal> is
        a class or interface.</para>
    
        <itemizedlist>
        <listitem>
            <para>If <literal>X</literal> satisfies <literal>Y</literal>, then
            <literal>X</literal> is a subtype of <literal>Y</literal>.</para>
        </listitem>
        <listitem>
            <para>If <literal>X</literal> satisfies <literal>Y&lt;B&gt;</literal>, then
            <literal>X</literal> is a subtype of <literal>Y&lt;B&gt;</literal>.</para>
        </listitem>
        <listitem>
            <para>If <literal>X&lt;T&gt;</literal> satisfies <literal>Y&lt;T&gt;</literal>, 
            then <literal>X&lt;B&gt;</literal> is a subtype of <literal>Y&lt;B&gt;</literal> 
            for any type <literal>B</literal>.</para>
        </listitem>
        <listitem>
            <para>If <literal>X&lt;T&gt;</literal> satisfies <literal>Y</literal>, 
            then <literal>X&lt;B&gt;</literal> is a subtype of <literal>Y</literal> 
            for any type <literal>B</literal>.</para>
        </listitem>
        </itemizedlist>
        
    </section>
    
    <section id="cases">
        <title>Cases</title>
        
        <para>An interface or <literal>abstract</literal> class may optionally 
        specify an enumerated list of all its subtypes. A union must specify an 
        enumerated list of its subtypes.</para>
    
        <programlisting>CaseTypes := "of" CaseType ("," CaseType)*</programlisting>
        
        <para>The <literal>of</literal> clause may specify multiple types, called
        <emphasis>cases</emphasis>.</para>
        
        <programlisting>CaseType := MemberName | Type</programlisting>
        
        <para>An anonymous class is identified by the name specified in the 
        <literal>object</literal> declaration&mdash;an initial lowercase
        identifier. Any anonymous class that appears as a case must extend the 
        class <literal>ceylon.language.Case</literal>.</para>
        
        <programlisting>of larger, smaller, equal</programlisting>
        
        <programlisting>of Root&lt;T&gt;, Leaf&lt;T&gt;, Branch&lt;T&gt;</programlisting>
        
        <para>An explicit list of cases allows safe use of a type in a 
        <literal>switch</literal> statement. The compiler is able to validate
        that the <literal>switch</literal> contains an exhaustive list of all 
        cases of the type.</para>
        
    </section>
    
    <section id="typeclasses">
        <title>Type classes</title>
        
        <comment><para>NOTE: Type classes are a proposed feature for a future
        version of the language.</para></comment>
        
        <para>A type may optionally specify a <emphasis>type class</emphasis>, A
        type class is a user-defined metamodel object for the type. A type class 
        must be a toplevel anonymous class that extends:</para>
        
        <itemizedlist>
            <listitem>
                <para><literal>BasicInterface&lt;T&gt;</literal> where <literal>T</literal> 
                is the interface, or</para>
            </listitem>
            <listitem>
                <para><literal>BasicClass&lt;T&gt;</literal> where <literal>T</literal> 
                is the class.</para>
            </listitem>
        </itemizedlist>
        
        <programlisting>TypeClass := "is" MemberName</programlisting>
        
        <para>The <literal>is</literal> clause may specify exactly one anonymous
        class:</para>
        
        <programlisting>is monoidClass</programlisting>
        
    </section>
        
    </section>

    <section id="generictypeparameters">
        <title>Generic type parameters</title>
    
        <para>Methods, classes, interfaces, and aliases may declare one or more generic 
        type parameters.</para>
        
        <programlisting>TypeParams := "&lt;" (TypeParam ",")* (TypeParam | SequencedTypeParam) "&gt;"</programlisting>
        
        <para>A declaration with type parameters is called <emphasis>generic</emphasis> or
        <emphasis>parameterized</emphasis>.</para>
        
        <itemizedlist>
        <listitem>
            <para>A type declaration with no type parameters defines exactly one type. A 
            parameterized type declaration defines a template for producing types: one type 
            for each possible combination of type arguments that satisfy the type constraints 
            specified by the type. The types of members of the this type are determined by 
            replacing every appearance of each type parameter in the schema of the 
            parameterized type definition with its type argument.</para>
        </listitem>
        <listitem>
            <para>A method declaration with no type parameters defines exactly one operation 
            per type. A parameterized method declaration defines a template for producing
            overloaded operations: one operation for each possible combination of type arguments 
            that satisfy the type constraints specified by the method declaration.</para>
        </listitem>
        <listitem>
            <para>A class declaration with no type parameters defines exactly one instantiation 
            operation. A parameterized class declaration defines a template for producing 
            overloaded instantiation operations: one instantiation operation for each possible 
            combination of type arguments that satisfy the type constraints specified by the 
            class declaration. The type of the object produced by an instantiation operation is 
            determined by substituting the same combination of type arguments for the type 
            parameters of the parameterized class.</para>
        </listitem>
        </itemizedlist>
        
        <para>There are two kinds of type parameter:</para>
        
        <itemizedlist>
        <listitem>
            <para>an <emphasis>ordinary type parameter</emphasis> parameterizes the type by some
            other type, and</para>
        </listitem>
        <listitem>
            <para>a <emphasis>dimensional type parameter</emphasis> parameterizes the type by a
            natural number.</para>
        </listitem>
        </itemizedlist>
        
        <programlisting>TypeParam := OrdinaryTypeParam | "#" DimensionalTypeParam</programlisting>
        
        <section id="ordinarytypeparameters">
            <title>Ordinary type parameters and variance</title>
        
        <para>An ordinary type parameter allows a declaration to be abstracted over a constrained 
        set of types.</para>
        
        <para>Each ordinary type parameter has a name and a specified <emphasis>variance</emphasis>.</para>
        
        <programlisting>OrdinaryTypeParam := Variance TypeName</programlisting>
        
        <para>Within the body of the declaration it parameterizes, an ordinary type parameter is 
        itself a type. The type parameter is a subtype of every upper bound of the type parameter. 
        However, a class, interface, or alias may not extend or implement a type parameter.</para>
        
        <para>A <emphasis>covariant</emphasis> type parameter is indicated using <literal>out</literal>.
        A <emphasis>contravariant</emphasis> type parameter is indicated using <literal>in</literal>.</para>
        
        <programlisting>Variance :=  ("out" | "in")?</programlisting>
        
        <para>A type parameter declared neither <literal>out</literal> nor <literal>in</literal> 
        is called <emphasis>nonvariant</emphasis>.</para>
        
        <programlisting>Map&lt;K, V&gt;</programlisting>
        
        <programlisting>Sender&lt;in M&gt;</programlisting>
        
        <programlisting>Container&lt;out T&gt;</programlisting>
        
        <programlisting>BinaryFunction&lt;in X, in Y, out R&gt;</programlisting>
        
        <comment><para>TODO: Would <literal>produces</literal> and <literal>consumes</literal> 
        be better?</para></comment>
        
        <para>A covariant type parameter may only appear in covariant positions of the type 
        definition. A contravariant type parameter may only appear in contravariant positions 
        of the type definition. Nonvariant type parameters may appear in any position.</para>
        
        <itemizedlist>
            <listitem>
                <para>The return type of a method is a covariant position.</para>
            </listitem>
            <listitem>
                <para>A formal parameter type of a method is a contravariant position.</para>
            </listitem>
            <listitem>
                <para>A type parameter of a method is a contravariant position.</para>
            </listitem>
            <listitem>
                <para>A formal parameter type of a member class initializer is a contravariant 
                position.</para>
            </listitem>
            <listitem>
                <para>A type parameter of a member class is a contravariant position.</para>
            </listitem>
            <listitem>
                <para>The type of a non-<literal>mutable</literal> attribute is a covariant 
                position.</para>
            </listitem>
            <listitem>
                <para>The type of a <literal>mutable</literal> attribute is a nonvariant 
                position.</para>
            </listitem>
            <listitem>
                <para>An upper bound of a type parameter in a contravariant position is a 
                contravariant position.</para>
            </listitem>
            <listitem>
                <para>An upper bound of a type parameter in a covariant position is a covariant 
                position.</para>
            </listitem>
            <listitem>
                <para>A lower bound of a type parameter in a contravariant position is a 
                covariant position.</para>
            </listitem>
            <listitem>
                <para>A type parameter in a covariant position cannot have a lower bound. 
                <comment>TODO: is this correct?</comment></para>
            </listitem>
            <listitem>
                <para>A covariant type argument of a satisfied or extended type is a covariant 
                position.</para>
            </listitem>
            <listitem>
                <para>A contravariant type argument of a satisfied or extended type is a 
                contravariant position.</para>
            </listitem>
            <listitem>
                <para>A covariant type argument of a type in a covariant position is a covariant 
                position.</para>
            </listitem>
            <listitem>
                <para>A contravariant type argument of a type in a covariant position is a 
                contravariant position.</para>
            </listitem>
            <listitem>
                <para>A covariant type argument of a type in a contravariant position is a 
                contravariant position.</para>
            </listitem>
            <listitem>
                <para>A contravariant type argument of a type in a contravariant position is a 
                covariant position.</para>
            </listitem>
            <listitem>
                <para>A nonvariant type argument of a type is a nonvariant position.</para>
            </listitem>
            <listitem>
                <para>A formal parameter of a callable parameter in a contravariant position is 
                covariant.</para>
            </listitem>
            <listitem>
                <para>A formal parameter of a callable parameter in a covariant position is 
                contravariant.</para>
            </listitem>
            <listitem>
                <para>The return type of a callable parameter in a contravariant position is 
                contravariant.</para>
            </listitem>
            <listitem>
                <para>The return type of a callable parameter in a covariant position is
                covariant.</para>
            </listitem>
        </itemizedlist>
        
        <para>These rules apply to members declared by the type, and to members inherited from 
        supertypes.</para>
        
        </section>
        
        <section id="dimensionaltypeparameters">
            <title>Dimensional type parameters</title>
            
            <comment><para>NOTE: dimensional type parameters are a proposed feature
            for a future version of the language.</para></comment>
        
        <para>A dimensional type parameter allows a declaration to be abstracted over 
        the natural numbers.</para>
        
        <para>A dimensional type parameter is distinguished by a <literal>#</literal>
        prefix, and must be an initial lowercase identifier.</para>
        
        <programlisting>DimensionalTypeParam := MemberName</programlisting>
        
        <para>Within the body of the declaration it parameterized, a dimensional type 
        parameter is a local of type <literal>Natural</literal>.</para>
        
        <programlisting>Vector&lt;#n&gt;</programlisting>
        <programlisting>Matrix&lt;#h,#w&gt;</programlisting>
        
        </section>
        
        <section id="thesubtypekeyword">
            <title>The <literal>subtype</literal> keyword</title>
        
        <para>Every Ceylon class or interface has an implicit type parameter that never
        needs to be declared. This special type parameter, referred to using the keyword 
        <literal>subtype</literal>, represents the concrete type of the current instance 
        (the instance that is being invoked). It is considered a covariant type parameter
        of the type, and may only appear in covariant positions of the type definition.
        It is upper bounded by the type (and is therefore assignable to the type).</para>
        
        <programlisting>public interface Wrapper&lt;out X&gt; {}</programlisting>
        
        <programlisting>public abstract class Wrappable() {
   public Wrapper&lt;subtype&gt; wrap() {
       return Wrapper(this)
   }
}</programlisting>
        
        <programlisting>public class Special() extends Wrappable() {}</programlisting>

        <programlisting>Special special = Special();
Wrapper&lt;Special&gt; wrapper = special.wrap();</programlisting>

        <para>The only expression assignable to the type <literal>subtype</literal> is
        the special value <literal>this</literal>, except inside the body of a method or
        attribute annotated <literal>fixed</literal>, where the class that declares the
        method or attribute is assignable to <literal>subtype</literal>.</para>
        
        <comment><para>TODO: Should we let you declare type constraints on 
        <literal>subtype</literal>?</para></comment>
        
        <comment><para>TODO: We should probably let you use <literal>subtype</literal>
        is an expression, especially if we end up deciding to support type classes, in
        which case <literal>x.subtype</literal> will be the only way to get the type
        class polymorphically.</para></comment>
        
        </section>
        
        <section id="sequencedtypeparameters">
            <title>Sequenced type parameters</title>
        
        <para>A <emphasis>sequenced type parameter</emphasis> allows a declaration to be 
        abstracted over a variable length list of arbitrary types. This allows declarations 
        with formal parameter lists to be represented by metamodel objects within the 
        language.</para>
        
        <para>A sequenced type parameter is identified by an elipsis <literal>...</literal>,
        indicating that it accepts a list of zero or more type arguments.</para>
        
        <programlisting>SequencedTypeParam := TypeName "..."</programlisting>
        
        <para>Sequenced type parameters are always non-variant.</para>
        
        <para>Inside the declaration of the parameterized type or method, a sequenced type 
        parameter may be used as a type argument to other types which accept a sequenced type 
        parameter, or it may be used as the type of the last formal parameter declared by a 
        method. It may not appear in any other position. The sequenced type parameter acts as 
        a pseudo-type. It is treated by the Ceylon compiler as if it were a type with no 
        members, to which no other type may be assigned, and which can only by assigned to 
        itself.</para>
        
        <programlisting>Type&lt;X, P...&gt;</programlisting>
        <programlisting>Method&lt;X, T, P...&gt;</programlisting>
        <programlisting>Tuple&lt;P...&gt;</programlisting>
        
        <comment><para>TODO: should we let you declare a variant sequenced type parameter?
        This is useful for modelling tuples.</para></comment>
        
        <comment><para>TODO: should we let you write things like:</para>
        <programlisting>class Foo&lt;P...&gt;(Tuple&lt;Bar&lt;P&gt;...&gt; barTup) {
    ...
    void baz(Baz&lt;P&gt;... bazs) {
        ...
    }
}</programlisting>
        <para>It's probably only really useful if we also let you do stuff like this:</para>
        <programlisting><![CDATA[List<T> zip<T,P...>(List<P>... x, T producing(P... args)) {
    return from (Natural i in 0..min(x.lastIndex...)) select (f(x[i]...))
}]]></programlisting></comment>

        </section>
        
    <section id="generictypeconstraints">
    <title>Generic type constraints</title>

        <para>A parameterized method, class, interface, or alias declaration may 
        declare constraints upon ordinary type parameters using the <literal>given</literal> 
        clause.</para>
        
        <programlisting>TypeConstraints = TypeConstraint+</programlisting>
    
        <programlisting>TypeConstraint := "given" TypeName FormalParams? TypeClass? SatisfiedTypes? AbstractedType?</programlisting>
        
        <programlisting>AbstractedType := "abstracts" Type</programlisting>
        
        <para>Note that the syntax for a type constraint is essentially the same syntax used 
        for other type declarations such as class, interface, and type alias declarations.</para>
        
        <para>There are four kinds of type constraint:</para>
        
        <itemizedlist>
            <listitem>
                <para>an upper bound, <literal>given X satisfies T</literal>, specifies that 
                the type parameter <literal>X</literal> is a subtype of a given
                type <literal>T</literal>,</para>
            </listitem>
            <listitem>
                <para>a lower bound, <literal>given X abstracts T</literal>, specifies that 
                a given type <literal>T</literal> is a subtype of the type parameter 
                <literal>X</literal>,</para>
            </listitem>
            <!--listitem>
                <para>a subtype bound, <literal>X = subtype</literal>, specifies that 
                the type parameter <literal>X</literal> represents the concrete type
                of the current instance, and</para>
            </listitem-->
            <listitem>
                <para>a type class bound, <literal>given X is T</literal>, specifies that the
                type class of the type parameter is a subtype of a given type <literal>T</literal>
                <emphasis>(note that type classes are a proposed feature for a future version
                of the language)</emphasis>,</para>
            </listitem>
            <listitem>
                <para>an initialization parameter specification, <literal>given X(...)</literal>
                specifies that the type parameter <literal>X</literal> is a class with
                the given formal parameter types.</para>
            </listitem>
        </itemizedlist>
        
        <para>An initialization parameter specification allows instantiation of the type 
        represented by the type parameter within the body of the declaration.</para>
        
        <para>A constraint may not refer to a sequenced type parameter.</para>
        
        <para>A single <literal>given</literal> clause may specify multiple constraints
        on a certain type parameter. For example, it may specify multiple upper bounds
        together with an initialization parameter specification. If multiple upper bounds
        are specified, at most one upper bound may be a class.</para>
        
        <!--
        <para>Subtype bounds are needed since the special type <literal>subtype</literal>
        cannot appear in a contravariant position. A subtype bound cannot be applied to
        a covariant or contravariant type parameter.</para>
        -->
        
        <para>A constraint affects the type arguments that can be assigned to a type
        parameter:</para>
        
        <itemizedlist>
            <listitem>
                <para>A type argument to a type parameter with an upper bound must be a type 
                which is a subtype of all upper bounds.</para>
            </listitem>
            <listitem>
                <para>A type argument to a type parameter with a lower bound must be a type 
                of which all lower bounds are subtypes.</para>
            </listitem>
        </itemizedlist>
        
        <para>Within the body of the declaration, a constraint affects the assignability of 
        a type parameter:</para>
        
        <itemizedlist>
            <listitem>
                <para>A type parameter is considered a subtype of its upper bound.</para>
            </listitem>
            <listitem>
                <para>The lower bound of a type parameter is considered a subtype of the
                type parameter.</para>
            </listitem>
            <listitem>
                <para>A metamodel reference to the type parameter is assignable to the type
                class bound.</para>
            </listitem>
        </itemizedlist>
        
        <programlisting>given X satisfies Number&lt;X&gt;
given Y(Natural count) satisfies Number&lt;Y&gt;</programlisting>
       
        <programlisting>given S satisfies Decimal[n]</programlisting>

        <programlisting>given T satisfies Ordinal, Comparable&lt;T&gt; abstracts X</programlisting>
        
        <programlisting>given N is Monoid&lt;N&gt;</programlisting>
    
        <para>Every type parameter has an implicit upper bound of type <literal>Void</literal>.</para>
        
        <!--  
        <comment><para>TODO: eventually we should support the ability to implicitly pass in an
        extension that is imported by the client code, using a type constraint of form:</para>
        <programlisting>given extension E(X x) satisfies Format</programlisting>
        <para>(We would need to define an identity extension in <literal>ceylon.language</literal>.)</para>
        <para>In the following special case, this lets us implement a Haskell-style type class 
        as an extension of the metatype:</para>
        <programlisting>given extension E(Type&lt;X&gt; tx) satisfies Monoid&lt;X&gt;</programlisting>
        <para>The extension type would be inferred at the point of invocation, using the usual
        rules for searching for extensions.</para>
        </comment>
        -->
        
        <!-- 
        <comment><para>TODO: at some stage it would be very interesting to support "assignability
        upper bounds", for example <literal>given X is String</literal>, where the client code is
        required to have an enabled extension that introduces the bound <literal>String</literal>
        to the type parameter <literal>X</literal>. Under the covers this extension would be passed
        as a <literal>Callable&lt;String,X&gt;</literal> to the initializer or method that declares 
        the constrained type parameter. Scala calls this feature "view bounds".</para></comment>
        -->
        
        <!--
        <comment><para>TODO: Should we move <literal>in</literal> and <literal>out</literal>
        down to the <literal>given</literal> clause?</para></comment>
        --><commit_msg>type constraint equivalency<commit_after><chapter id="typesystem">
    <title>Type system overview</title>
    
    <para>Every value in a Ceylon program is an instance of a type that can be expressed 
    within the Ceylon language as a <emphasis>class</emphasis>. The language does not 
    define any primitive or compound types that cannot, in principle, be expressed within 
    the language itself.</para>
    
    <para>A class is a recipe for producing new values, and defines the operations and
    attributes of the resulting values. Each class declaration defines a type. However, 
    not all types are classes. It is often advantageous to write generic code that 
    abstracts the concrete class of a value. This technique is called 
    <emphasis>polymorphism</emphasis>. Ceylon supports two different kinds of polymorphism:</para>
    
    <itemizedlist>
        <listitem>
            <para><emphasis>subtype polymorphism</emphasis>, where a subtype <literal>B</literal>
            inherits a supertype <literal>A</literal>, and</para>
        </listitem>
        <listitem>
            <para><emphasis>parametric polymorphism</emphasis>, where a type definition 
            <literal>A&lt;T&gt;</literal> is parameterized by a <emphasis>generic type 
            parameter</emphasis> <literal>T</literal>.</para>
        </listitem>
    </itemizedlist>
    
    <para>Ceylon, like Java and many other object-oriented languages, supports a single
    inheritance model for classes. A class may directly inherit at most one other class, 
    and all classes eventually inherit, directly or indirectly, the class 
    <literal>ceylon.language.Void</literal>, which acts as the root of the class hierarchy.</para>
    
    <para>A truly hierarchical type system is much too restrictive for more abstract 
    programming tasks. Therefore, in addition to classes, Ceylon recognizes the following 
    kinds of type:</para>
    
    <itemizedlist>
        <listitem>
            <para>An <emphasis>interface</emphasis> declares a set of operations and
            attributes that must be provided by every class that <emphasis>implements</emphasis>
            the interface. A class may implement many interfaces.</para>
        </listitem>
        <listitem>
            <para>A <emphasis>union</emphasis> is a type whose value may be a value of 
            any one of an enumerated list of classes. <emphasis>Note: Union types are 
            a feature proposed for inclusion in a future version of the language.</emphasis></para>
        </listitem>
        <listitem>
            <para>A <emphasis>generic type parameter</emphasis> is considered a type
            within the declaration that it parameterizes. In fact, it is an abstraction
            over many types: it generalizes the declaration to all types which could be 
            substituted for the parameter.</para>
        </listitem>
        <listitem>
            <para>A <emphasis>produced type</emphasis> is formed by specifying arguments
            for the generic type parameters of a parameterized type.</para>
        </listitem>
    </itemizedlist>
    
    <para>The Ceylon type system is much more complete than most other object oriented
    languages. In Ceylon, it's possible to answer questions that might at first sound
    almost nonsensical if you're used to languages with more traditional type systems. 
    For example:</para>
    
    <itemizedlist>
        <listitem>
            <para>What is the return type of a <literal>void</literal> method?</para>
        </listitem>
        <listitem>
            <para>What is the type of an local that may or may not hold a value of 
            type <literal>T</literal>?</para>
        </listitem>
        <listitem>
            <para>What is the type that represents methods that accept two <literal>Float</literal>
            values?</para>
        </listitem>
        <listitem>
            <para>What is the type of an expression that may be evaluated to produce
            a <literal>String</literal>?</para>
        </listitem>
        <listitem>
            <para>What is the type of a sequence of natural numbers of length <literal>n+1</literal>?</para>
        </listitem>
        <listitem>
            <para>What is the type that represents subclasses of <literal>Renderer</literal> 
            which must be provided at instantiation time with a function that accepts an 
            object and produces a <literal>String</literal>?</para>
        </listitem>
    </itemizedlist>
    
    <para>The answers, as we shall discover, are: <literal>Void</literal>, 
    <literal>Optional&lt;T&gt;</literal>, <literal>Method&lt;Object, Void, Float, Float&gt;</literal>,
    <literal>Gettable&lt;String&gt;</literal>, <literal>BoundedSequence&lt;n+1&gt;</literal>, 
    and <literal>Class&lt;Renderer, Callable&lt;String,Object&gt;&gt;</literal>.</para>
    
    <!--itemizedlist>
        <listitem>
            <para><literal>Void</literal>, </para>
        </listitem>
        <listitem>
            <para><literal>Optional&lt;T&gt;</literal></para>
        </listitem>
        <listitem>
            <para><literal>Method&lt;Void, Float, Float&gt;</literal>, and</para>
        </listitem>
        <listitem>
            <para><literal>Gettable&lt;String&gt;</literal>.</para>
        </listitem>
    </itemizedlist-->
    

    <section id="identifiernaming">
        <title>Identifier naming</title>

        <para>The Ceylon compiler enforces identifier naming conventions. Types must
        be named with an initial uppercase. Members, parameters and locals must be 
        named with an initial lowercase or underscore. A package name element is an
        all-lowercase identifier.</para>
        
        <programlisting>PackageName := PIdentifier</programlisting>
        <programlisting>TypeName := UIdentifier</programlisting>
        <programlisting>MemberName := LIdentifier</programlisting>
        <programlisting>ParameterName := LIdentifier</programlisting>
        
        <para>An underscore <literal>_</literal> is considered a lowercase letter.</para>
        
        <para>Ceylon defines three identifier namespaces:</para>
        
        <itemizedlist>
            <listitem>
                <para>classes, interfaces and aliases share a single namespace,</para>
            </listitem>
            <listitem>
                <para>methods, attributes and locals share a single namespace, and</para>
            </listitem>
            <listitem>
                <para>packages have their own dedicated namespace.</para>
            </listitem>
        </itemizedlist>
        
        <para>The Ceylon parser is able to unambiguously identify which namespace an 
        identifier belongs to.</para>
        
    </section>
      
    <section id="type">
        <title>Types</title>
    
        <para>A <emphasis>type</emphasis> or <emphasis>type schema</emphasis> is name 
        (an initial uppercase identifier) and an optional list of type parameters, with 
        a set of:</para>
        
        <itemizedlist>
            <listitem>
                <para>attribute schemas,</para>
            </listitem>
            <listitem>
                <para>method schemas, and</para>
            </listitem>
            <listitem>
                <para>class schemas.</para>
            </listitem>
        </itemizedlist>
        
        <para>The attribute, method, and class schemas are called the 
        <emphasis>members</emphasis> of the type.</para>
        
        <para>Speaking formally:</para>
        
        <itemizedlist>
            <listitem>
                <para>An <emphasis>attribute schema</emphasis> is a name (an initial 
                lowercase identifier) with a type and mutability.</para>
            </listitem>
            <listitem>
                <para>A <emphasis>method schema</emphasis> is a name (an initial lowercase 
                identifier) and an optional list of type parameters, with a type (often 
                called the <emphasis>return type</emphasis>) and a list of one or more 
                formal parameter lists.</para>
            </listitem>
            <listitem>
                <para>A <emphasis>class schema</emphasis> is a type schema with a formal 
                parameter list.</para>
            </listitem>
            <listitem>
                <para>A <emphasis>formal parameter list</emphasis> is a list of names 
                (initial lowercase identifiers) with types. The 
                <emphasis>signature</emphasis> of a formal parameter list is formed by 
                discarding the names, leaving the list of types.</para>
            </listitem>
        </itemizedlist>
        
        <para>Speaking slightly less formally, we usually refer to an attribute, method, or 
        member class of a type, meaning an attribute schema, method schema or class schema
        that is a member of the type.</para>
        
        <section id="memberdistinctness">
            <title>Member distinctness</title>
        
        <para>The <emphasis>erased signature</emphasis> of a method or class is formed by:</para>
        
        <itemizedlist>
            <listitem>
                <para>taking the signature of the formal parameter list of the member class, 
                or of the first formal parameter list of the method, and</para>
            </listitem>
            <listitem>
                <para>replacing each occurrence of any type alias in the signature with the
                aliased type, and</para>
            </listitem>
            <listitem>
                <para>replacing each occurrence of <literal>Optional&lt;T&gt;</literal> in 
                the signature with <literal>T</literal>, and</para>
            </listitem>
            <listitem>
                <para>replacing each occurrence of any type parameter in the signature with 
                the first declared upper bound of the type parameter, or <literal>ceylon.language.Void</literal> 
                if there is no declared upper bound, and</para>
            </listitem>
            <listitem>
                <para>replacing the type of any sequenced type parameter in the signature with 
                <literal>ceylon.language.Void...</literal>, and then</para>
            </listitem>
            <listitem>
                <para>discarding the type arguments of each element of the list, leaving just 
                the name of a class or interface.</para>
            </listitem>
        </itemizedlist>
        
        <comment><para>Note: I really, really hate this stuff. Is there any way we can do 
        better than Java here?</para></comment>
        
        <para>Two erased signatures are considered <emphasis>distinct</emphasis> if they 
        have different lengths, or if at some position within the lists, the two types are 
        non-identical.</para>
        
        <comment><para>TODO: non-identical, or non-assignable?</para></comment>
        
        <comment><para>TODO: what about sequenced parameters? what does Java do?</para></comment>
            
        <para>A type may not have:</para>
        
        <itemizedlist>
            <listitem>
                <para>two attributes with the same name,</para>
            </listitem>
            <listitem>
                <para>a method and an attribute with the same name,</para>
            </listitem>
            <listitem>
                <para>two methods with the same name and non-distinct erased signatures, 
                or</para>
            </listitem>
            <listitem>
                <para>two member classes with the same name and non-distinct erased signatures.</para>
            </listitem>
        </itemizedlist>
        
        </section>
        
        <section id="subtyping">
            <title>Subtyping</title>
        
        <para>A type may be a <emphasis>subtype</emphasis> of another type. Subtyping obeys 
        the following rules:</para>
        
        <itemizedlist>
            <listitem>
                <para>Identity: <literal>X</literal> is a subtype of <literal>X</literal>.</para>
            </listitem>
            <listitem>
                <para>Transitivity: if <literal>X</literal> is a subtype of <literal>Y</literal>
                and <literal>Y</literal> is a subtype of <literal>Z</literal> then
                <literal>X</literal> is a subtype of <literal>Z</literal>.</para>
            </listitem>
            <listitem>
                <para>Interfaces and unions are objects: all interfaces and unions are subtypes 
                of <literal>ceylon.language.Object</literal>. Conversely, only a subtype of 
                <literal>ceylon.language.Object</literal> may satisfy an interface or be an
                enumerated subtype of a union.</para>
            </listitem>
            <listitem>
                <para>Single root: all types are subtypes of <literal>ceylon.language.Void</literal>.</para>
            </listitem>
        </itemizedlist>
        
        
        </section>
        
        <section id="assignability">
            <title>Assignability</title>
        
        <para>In a certain compilation unit, a type may be <emphasis>assignable</emphasis> 
        to another type. If, in some compilation unit, <literal>X</literal> is assignable 
        to <literal>Y</literal>, then:</para>
        
        <itemizedlist>
            <listitem>
                <para>For each non-<literal>mutable</literal> attribute of <literal>Y</literal>, 
                <literal>X</literal> has an attribute with the same name, whose type is 
                assignable to the type of the attribute of <literal>Y</literal>.</para>
            </listitem>
            <listitem>
                <para>For each <literal>mutable</literal> attribute of <literal>Y</literal>, 
                <literal>X</literal> has a <literal>mutable</literal> attribute with the 
                same name and the same type.</para>
            </listitem>
            <listitem>
                <para>For each method of <literal>Y</literal>, <literal>X</literal>
                has a method with the same name, with the same number of formal parameter 
                lists, with the same signatures, and whose return type is assignable to the 
                return type of the method of <literal>Y</literal>.</para>
            </listitem>
            <listitem>
                <para>For each member class of <literal>Y</literal>, <literal>X</literal>
                has a member class of the same name, with a formal parameter list with 
                the same signature, that is assignable to the member class of 
                <literal>Y</literal>.</para>
            </listitem>
        </itemizedlist>
        
        <para>Assignability obeys the following rules:</para>
        
        <itemizedlist>
            <listitem>
                <para>Identity: <literal>X</literal> is assignable to <literal>X</literal>.</para>
            </listitem>
            <listitem>
                <para>Subtyping: if <literal>Y</literal> is a subtype of <literal>X</literal> 
                then <literal>Y</literal> is assignable to <literal>X</literal>.</para>
            </listitem>
            <listitem>
                <para>Transitivity: if <literal>X</literal> is assignable to <literal>Y</literal>
                and <literal>Y</literal> is assignable to <literal>Z</literal> then
                <literal>X</literal> is assignable to <literal>Z</literal>.</para>
            </listitem>
            <listitem>
                <para>Lazy evaluation: the type <literal>Gettable&lt;T&gt;</literal> is 
                assignable to <literal>T</literal> for every type <literal>T</literal>.</para>
            </listitem>
            <!--
            <listitem>
                <para>Nullsafety: the type <literal>Optional&lt;T&gt;</literal> is 
                not assignable to <literal>Object</literal>. Nor is its subtype
                <literal>Nothing</literal>.</para>
            </listitem>
            -->
        </itemizedlist>
        
        <para>A type <literal>X</literal> may be assignable to a type <literal>Y</literal>
        even if <literal>X</literal> is not a subtype of <literal>Y</literal> if there is 
        an enabled extension which introduces <literal>Y</literal> to <literal>X</literal>.</para>
        
        </section>
        
        <section id="typeofaprogramelement">
            <title>Type of a program element</title>
        
        <para>Method, attribute and formal parameter declarations must declare a type.</para>
        
        <para>Types are identified by the name of the type (a class, interface, alias or 
        type parameter), together with a list of type arguments if the type definition 
        specifies type parameters.</para>
        
        <programlisting>Type := ( TypeNameWithArguments ("." TypeNameWithArguments)* | "subtype" ) Abbreviation*</programlisting>
        
        <para>If a type has type parameters or a sequenced type parameter, a type argument 
        list must be specified. If a type has no type parameters, and no sequenced type 
        parameter, no type argument list may be specified.</para>        
        
         <para>Unlike Java, the name of a type may not be qualified by the package name.</para>

        <para>Certain declarations which usually require an explicit type may omit the type, 
        forcing the compiler to infer it, by specifying the keyword <literal>local</literal>
        where the type usually appears.</para>
        
        <programlisting>InferableType := Type | "local"</programlisting>
        
        <para>Type inference is only allowed for block local declarations. The keyword
        <literal>local</literal> may not be combined with a visibility modifier annotation.</para>
        
        </section>
        
        <section id="typenameabbreviations">
            <title>Type name abbreviations</title>
            
        <para>The following type name abbreviations are supported:</para>
        
        <itemizedlist>
            <listitem>
                <para><literal>X?</literal> means <literal>Optional&lt;X&gt;</literal> for
                any type <literal>X</literal>,</para>
            </listitem>
            <listitem>
                <para><literal>X[]</literal> means <literal>Sequence&lt;X&gt;</literal> for
                any type <literal>X</literal>, and</para>
            </listitem>
            <listitem>
                <para><literal>X[n]</literal> means <literal>BoundedSequence&lt;X,#n&gt;</literal> 
                for any type <literal>X</literal> and dimension <literal>n</literal>.</para>
            </listitem>
        </itemizedlist>
        
        <programlisting>Abbreviation := "?" | "[" dimension? "]"</programlisting>
        
        <para>Abbreviations may be combined:</para>
        
        <programlisting>String?[3] words = { "hello", "world", null };
String? firstWord = words[0];</programlisting>
        
        <comment><para>TODO: It might be difficult to support <literal>T??</literal>
        since <literal>Optional</literal> is erased.</para></comment>
        
        <comment><para>TODO: Java lets you put the <literal>[]</literal> after the variable
        name. C requires that. Should we support/require this variation? It is consistent
        with how we declare functional parameters!</para></comment>
        
        </section>
    
    </section>
        
    <section id="inheritance">
        <title>Inheritance</title>
        
        <para>Subtyping is a static relationship between classes, interfaces, and type 
        parameters, produced through the use of <emphasis>inheritance</emphasis>:</para>
        
        <itemizedlist>
            <listitem>
                <para>a class may <emphasis>extend</emphasis> another class,</para>
            </listitem>
            <listitem>
                <para>a class may <emphasis>implement</emphasis> one or more interfaces,</para>
            </listitem>
            <listitem>
                <para>an interface may <emphasis>extend</emphasis> one or more other interfaces,</para>
            </listitem>
            <listitem>
                <para>a union may <emphasis>satisfy</emphasis> one or more interfaces,</para>
            </listitem>
            <listitem>
                <para>a type parameter may <emphasis>satisfy</emphasis> a class and/or one or 
                more interfaces or type parameters, or</para>
            </listitem>
            <listitem>
                <para>a type parameter may <emphasis>abstract</emphasis> a class, interface or 
                type parameter.</para>
            </listitem>
        </itemizedlist>
        
        <comment><para>TODO: should we let an interface extend a class other than <literal>Object</literal>?</para></comment>
    
    <section id="extendedclass">
        <title>Extension</title>
    
        <para>A class may extend another class.</para>
        
        <programlisting>ExtendedType := "extends" Type PositionalArguments</programlisting>
    
        <para>The <literal>extends</literal> clause must specify exactly one superclass. 
        If the superclass is a parameterized type, the <literal>extends</literal> clause 
        must specify type arguments. The <literal>extends</literal> clause must specify 
        arguments for the initializer parameters of the superclass.</para>
        
        <programlisting>extends Person(name, org)</programlisting>
    
        <para>
        If a class does not explicitly specify a superclass using <literal>extends</literal>,
        its superclass is <literal>ceylon.language.BaseObject</literal>. <!--There is one exception 
        to this rule: the built-in class <literal>ceylon.language.Void</literal> which does not have 
        a superclass.-->
        </para>
        
        <para>
        The root class <literal>ceylon.language.Void</literal> does not have a superclass.
        </para>
        
        <para>Suppose <literal>X</literal> and <literal>Y</literal> are classes.</para>
    
        <itemizedlist>
        <listitem>
            <para>If <literal>X</literal> extends <literal>Y</literal>, then
            <literal>X</literal> is a subtype of <literal>Y</literal>.</para>
        </listitem>
        <listitem>
            <para>If <literal>X</literal> extends <literal>Y&lt;B&gt;</literal>, then
            <literal>X</literal> is a subtype of <literal>Y&lt;B&gt;</literal>.</para>
        </listitem>
        <listitem>
            <para>If <literal>X&lt;T&gt;</literal> extends <literal>Y&lt;T&gt;</literal>, 
            then <literal>X&lt;B&gt;</literal> is a subtype of <literal>Y&lt;B&gt;</literal> 
            for any type <literal>B</literal>.</para>
        </listitem>
        <listitem>
            <para>If <literal>X&lt;T&gt;</literal> extends <literal>Y</literal>, 
            then <literal>X&lt;B&gt;</literal> is a subtype of <literal>Y</literal> 
            for any type <literal>B</literal>.</para>
        </listitem>
        </itemizedlist>
        
        <para>A user-defined class must extend <literal>ceylon.language.Object</literal>
        or one of its subclasses.</para>
        
    </section>
    
    <section id="satisfiedinterfaces">
        <title>Satisfaction</title>
    
        <para>A class may implement one or more interfaces. An interface may extend one
        or more interfaces. A union may satisfy one or more interfaces. A type parameter 
        may satisfy one or more interfaces and, optionally, a class.</para>
        
        <programlisting>SatisfiedTypes = "satisfies" Type ("," Type)*</programlisting>
    
        <para>The <literal>satisfies</literal> clause may specify multiple types. If 
        a satisfied type is a parameterized type, the <literal>satisfies</literal> clause 
        must specify type arguments.</para>
        
        <programlisting>satisfies T[], Collection&lt;T&gt;</programlisting>
        
        <para>Suppose <literal>Y</literal> is an interface and <literal>X</literal> is
        a class or interface.</para>
    
        <itemizedlist>
        <listitem>
            <para>If <literal>X</literal> satisfies <literal>Y</literal>, then
            <literal>X</literal> is a subtype of <literal>Y</literal>.</para>
        </listitem>
        <listitem>
            <para>If <literal>X</literal> satisfies <literal>Y&lt;B&gt;</literal>, then
            <literal>X</literal> is a subtype of <literal>Y&lt;B&gt;</literal>.</para>
        </listitem>
        <listitem>
            <para>If <literal>X&lt;T&gt;</literal> satisfies <literal>Y&lt;T&gt;</literal>, 
            then <literal>X&lt;B&gt;</literal> is a subtype of <literal>Y&lt;B&gt;</literal> 
            for any type <literal>B</literal>.</para>
        </listitem>
        <listitem>
            <para>If <literal>X&lt;T&gt;</literal> satisfies <literal>Y</literal>, 
            then <literal>X&lt;B&gt;</literal> is a subtype of <literal>Y</literal> 
            for any type <literal>B</literal>.</para>
        </listitem>
        </itemizedlist>
        
    </section>
    
    <section id="cases">
        <title>Cases</title>
        
        <para>An interface or <literal>abstract</literal> class may optionally 
        specify an enumerated list of all its subtypes. A union must specify an 
        enumerated list of its subtypes.</para>
    
        <programlisting>CaseTypes := "of" CaseType ("," CaseType)*</programlisting>
        
        <para>The <literal>of</literal> clause may specify multiple types, called
        <emphasis>cases</emphasis>.</para>
        
        <programlisting>CaseType := MemberName | Type</programlisting>
        
        <para>An anonymous class is identified by the name specified in the 
        <literal>object</literal> declaration&mdash;an initial lowercase
        identifier. Any anonymous class that appears as a case must extend the 
        class <literal>ceylon.language.Case</literal>.</para>
        
        <programlisting>of larger, smaller, equal</programlisting>
        
        <programlisting>of Root&lt;T&gt;, Leaf&lt;T&gt;, Branch&lt;T&gt;</programlisting>
        
        <para>An explicit list of cases allows safe use of a type in a 
        <literal>switch</literal> statement. The compiler is able to validate
        that the <literal>switch</literal> contains an exhaustive list of all 
        cases of the type.</para>
        
    </section>
    
    <section id="typeclasses">
        <title>Type classes</title>
        
        <comment><para>NOTE: Type classes are a proposed feature for a future
        version of the language.</para></comment>
        
        <para>A type may optionally specify a <emphasis>type class</emphasis>, A
        type class is a user-defined metamodel object for the type. A type class 
        must be a toplevel anonymous class that extends:</para>
        
        <itemizedlist>
            <listitem>
                <para><literal>BasicInterface&lt;T&gt;</literal> where <literal>T</literal> 
                is the interface, or</para>
            </listitem>
            <listitem>
                <para><literal>BasicClass&lt;T&gt;</literal> where <literal>T</literal> 
                is the class.</para>
            </listitem>
        </itemizedlist>
        
        <programlisting>TypeClass := "is" MemberName</programlisting>
        
        <para>The <literal>is</literal> clause may specify exactly one anonymous
        class:</para>
        
        <programlisting>is monoidClass</programlisting>
        
    </section>
        
    </section>

    <section id="generictypeparameters">
        <title>Generic type parameters</title>
    
        <para>Methods, classes, interfaces, and aliases may declare one or more generic 
        type parameters.</para>
        
        <programlisting>TypeParams := "&lt;" (TypeParam ",")* (TypeParam | SequencedTypeParam) "&gt;"</programlisting>
        
        <para>A declaration with type parameters is called <emphasis>generic</emphasis> or
        <emphasis>parameterized</emphasis>.</para>
        
        <itemizedlist>
        <listitem>
            <para>A type declaration with no type parameters defines exactly one type. A 
            parameterized type declaration defines a template for producing types: one type 
            for each possible combination of type arguments that satisfy the type constraints 
            specified by the type. The types of members of the this type are determined by 
            replacing every appearance of each type parameter in the schema of the 
            parameterized type definition with its type argument.</para>
        </listitem>
        <listitem>
            <para>A method declaration with no type parameters defines exactly one operation 
            per type. A parameterized method declaration defines a template for producing
            overloaded operations: one operation for each possible combination of type arguments 
            that satisfy the type constraints specified by the method declaration.</para>
        </listitem>
        <listitem>
            <para>A class declaration with no type parameters defines exactly one instantiation 
            operation. A parameterized class declaration defines a template for producing 
            overloaded instantiation operations: one instantiation operation for each possible 
            combination of type arguments that satisfy the type constraints specified by the 
            class declaration. The type of the object produced by an instantiation operation is 
            determined by substituting the same combination of type arguments for the type 
            parameters of the parameterized class.</para>
        </listitem>
        </itemizedlist>
        
        <para>There are two kinds of type parameter:</para>
        
        <itemizedlist>
        <listitem>
            <para>an <emphasis>ordinary type parameter</emphasis> parameterizes the type by some
            other type, and</para>
        </listitem>
        <listitem>
            <para>a <emphasis>dimensional type parameter</emphasis> parameterizes the type by a
            natural number.</para>
        </listitem>
        </itemizedlist>
        
        <programlisting>TypeParam := OrdinaryTypeParam | "#" DimensionalTypeParam</programlisting>
        
        <section id="ordinarytypeparameters">
            <title>Ordinary type parameters and variance</title>
        
        <para>An ordinary type parameter allows a declaration to be abstracted over a constrained 
        set of types.</para>
        
        <para>Each ordinary type parameter has a name and a specified <emphasis>variance</emphasis>.</para>
        
        <programlisting>OrdinaryTypeParam := Variance TypeName</programlisting>
        
        <para>Within the body of the declaration it parameterizes, an ordinary type parameter is 
        itself a type. The type parameter is a subtype of every upper bound of the type parameter. 
        However, a class, interface, or alias may not extend or implement a type parameter.</para>
        
        <para>A <emphasis>covariant</emphasis> type parameter is indicated using <literal>out</literal>.
        A <emphasis>contravariant</emphasis> type parameter is indicated using <literal>in</literal>.</para>
        
        <programlisting>Variance :=  ("out" | "in")?</programlisting>
        
        <para>A type parameter declared neither <literal>out</literal> nor <literal>in</literal> 
        is called <emphasis>nonvariant</emphasis>.</para>
        
        <programlisting>Map&lt;K, V&gt;</programlisting>
        
        <programlisting>Sender&lt;in M&gt;</programlisting>
        
        <programlisting>Container&lt;out T&gt;</programlisting>
        
        <programlisting>BinaryFunction&lt;in X, in Y, out R&gt;</programlisting>
        
        <comment><para>TODO: Would <literal>produces</literal> and <literal>consumes</literal> 
        be better?</para></comment>
        
        <para>A covariant type parameter may only appear in covariant positions of the type 
        definition. A contravariant type parameter may only appear in contravariant positions 
        of the type definition. Nonvariant type parameters may appear in any position.</para>
        
        <itemizedlist>
            <listitem>
                <para>The return type of a method is a covariant position.</para>
            </listitem>
            <listitem>
                <para>A formal parameter type of a method is a contravariant position.</para>
            </listitem>
            <listitem>
                <para>A type parameter of a method is a contravariant position.</para>
            </listitem>
            <listitem>
                <para>A formal parameter type of a member class initializer is a contravariant 
                position.</para>
            </listitem>
            <listitem>
                <para>A type parameter of a member class is a contravariant position.</para>
            </listitem>
            <listitem>
                <para>The type of a non-<literal>mutable</literal> attribute is a covariant 
                position.</para>
            </listitem>
            <listitem>
                <para>The type of a <literal>mutable</literal> attribute is a nonvariant 
                position.</para>
            </listitem>
            <listitem>
                <para>An upper bound of a type parameter in a contravariant position is a 
                contravariant position.</para>
            </listitem>
            <listitem>
                <para>An upper bound of a type parameter in a covariant position is a covariant 
                position.</para>
            </listitem>
            <listitem>
                <para>A lower bound of a type parameter in a contravariant position is a 
                covariant position.</para>
            </listitem>
            <listitem>
                <para>A type parameter in a covariant position cannot have a lower bound. 
                <comment>TODO: is this correct?</comment></para>
            </listitem>
            <listitem>
                <para>A covariant type argument of a satisfied or extended type is a covariant 
                position.</para>
            </listitem>
            <listitem>
                <para>A contravariant type argument of a satisfied or extended type is a 
                contravariant position.</para>
            </listitem>
            <listitem>
                <para>A covariant type argument of a type in a covariant position is a covariant 
                position.</para>
            </listitem>
            <listitem>
                <para>A contravariant type argument of a type in a covariant position is a 
                contravariant position.</para>
            </listitem>
            <listitem>
                <para>A covariant type argument of a type in a contravariant position is a 
                contravariant position.</para>
            </listitem>
            <listitem>
                <para>A contravariant type argument of a type in a contravariant position is a 
                covariant position.</para>
            </listitem>
            <listitem>
                <para>A nonvariant type argument of a type is a nonvariant position.</para>
            </listitem>
            <listitem>
                <para>A formal parameter of a callable parameter in a contravariant position is 
                covariant.</para>
            </listitem>
            <listitem>
                <para>A formal parameter of a callable parameter in a covariant position is 
                contravariant.</para>
            </listitem>
            <listitem>
                <para>The return type of a callable parameter in a contravariant position is 
                contravariant.</para>
            </listitem>
            <listitem>
                <para>The return type of a callable parameter in a covariant position is
                covariant.</para>
            </listitem>
        </itemizedlist>
        
        <para>These rules apply to members declared by the type, and to members inherited from 
        supertypes.</para>
        
        </section>
        
        <section id="dimensionaltypeparameters">
            <title>Dimensional type parameters</title>
            
            <comment><para>NOTE: dimensional type parameters are a proposed feature
            for a future version of the language.</para></comment>
        
        <para>A dimensional type parameter allows a declaration to be abstracted over 
        the natural numbers.</para>
        
        <para>A dimensional type parameter is distinguished by a <literal>#</literal>
        prefix, and must be an initial lowercase identifier.</para>
        
        <programlisting>DimensionalTypeParam := MemberName</programlisting>
        
        <para>Within the body of the declaration it parameterized, a dimensional type 
        parameter is a local of type <literal>Natural</literal>.</para>
        
        <programlisting>Vector&lt;#n&gt;</programlisting>
        <programlisting>Matrix&lt;#h,#w&gt;</programlisting>
        
        </section>
        
        <section id="thesubtypekeyword">
            <title>The <literal>subtype</literal> keyword</title>
        
        <para>Every Ceylon class or interface has an implicit type parameter that never
        needs to be declared. This special type parameter, referred to using the keyword 
        <literal>subtype</literal>, represents the concrete type of the current instance 
        (the instance that is being invoked). It is considered a covariant type parameter
        of the type, and may only appear in covariant positions of the type definition.
        It is upper bounded by the type (and is therefore assignable to the type).</para>
        
        <programlisting>public interface Wrapper&lt;out X&gt; {}</programlisting>
        
        <programlisting>public abstract class Wrappable() {
   public Wrapper&lt;subtype&gt; wrap() {
       return Wrapper(this)
   }
}</programlisting>
        
        <programlisting>public class Special() extends Wrappable() {}</programlisting>

        <programlisting>Special special = Special();
Wrapper&lt;Special&gt; wrapper = special.wrap();</programlisting>

        <para>The only expression assignable to the type <literal>subtype</literal> is
        the special value <literal>this</literal>, except inside the body of a method or
        attribute annotated <literal>fixed</literal>, where the class that declares the
        method or attribute is assignable to <literal>subtype</literal>.</para>
        
        <comment><para>TODO: Should we let you declare type constraints on 
        <literal>subtype</literal>?</para></comment>
        
        <comment><para>TODO: We should probably let you use <literal>subtype</literal>
        is an expression, especially if we end up deciding to support type classes, in
        which case <literal>x.subtype</literal> will be the only way to get the type
        class polymorphically.</para></comment>
        
        </section>
        
        <section id="sequencedtypeparameters">
            <title>Sequenced type parameters</title>
        
        <para>A <emphasis>sequenced type parameter</emphasis> allows a declaration to be 
        abstracted over a variable length list of arbitrary types. This allows declarations 
        with formal parameter lists to be represented by metamodel objects within the 
        language.</para>
        
        <para>A sequenced type parameter is identified by an elipsis <literal>...</literal>,
        indicating that it accepts a list of zero or more type arguments.</para>
        
        <programlisting>SequencedTypeParam := TypeName "..."</programlisting>
        
        <para>Sequenced type parameters are always non-variant.</para>
        
        <para>Inside the declaration of the parameterized type or method, a sequenced type 
        parameter may be used as a type argument to other types which accept a sequenced type 
        parameter, or it may be used as the type of the last formal parameter declared by a 
        method. It may not appear in any other position. The sequenced type parameter acts as 
        a pseudo-type. It is treated by the Ceylon compiler as if it were a type with no 
        members, to which no other type may be assigned, and which can only by assigned to 
        itself.</para>
        
        <programlisting>Type&lt;X, P...&gt;</programlisting>
        <programlisting>Method&lt;X, T, P...&gt;</programlisting>
        <programlisting>Tuple&lt;P...&gt;</programlisting>
        
        <comment><para>TODO: should we let you declare a variant sequenced type parameter?
        This is useful for modelling tuples.</para></comment>
        
        <comment><para>TODO: should we let you write things like:</para>
        <programlisting>class Foo&lt;P...&gt;(Tuple&lt;Bar&lt;P&gt;...&gt; barTup) {
    ...
    void baz(Baz&lt;P&gt;... bazs) {
        ...
    }
}</programlisting>
        <para>It's probably only really useful if we also let you do stuff like this:</para>
        <programlisting><![CDATA[List<T> zip<T,P...>(List<P>... x, T producing(P... args)) {
    return from (Natural i in 0..min(x.lastIndex...)) select (f(x[i]...))
}]]></programlisting></comment>

        </section>
        
    <section id="generictypeconstraints">
    <title>Generic type constraints</title>

        <para>A parameterized method, class, interface, or alias declaration may 
        declare constraints upon ordinary type parameters using the <literal>given</literal> 
        clause.</para>
        
        <programlisting>TypeConstraints = TypeConstraint+</programlisting>
    
        <programlisting>TypeConstraint := "given" TypeName FormalParams? TypeClass? SatisfiedTypes? AbstractedType?</programlisting>
        
        <programlisting>AbstractedType := "abstracts" Type</programlisting>
        
        <para>Note that the syntax for a type constraint is essentially the same syntax used 
        for other type declarations such as class, interface, and type alias declarations.</para>
        
        <para>There are four kinds of type constraint:</para>
        
        <itemizedlist>
            <listitem>
                <para>an upper bound, <literal>given X satisfies T</literal>, specifies that 
                the type parameter <literal>X</literal> is a subtype of a given
                type <literal>T</literal>,</para>
            </listitem>
            <listitem>
                <para>a lower bound, <literal>given X abstracts T</literal>, specifies that 
                a given type <literal>T</literal> is a subtype of the type parameter 
                <literal>X</literal>,</para>
            </listitem>
            <!--listitem>
                <para>a subtype bound, <literal>X = subtype</literal>, specifies that 
                the type parameter <literal>X</literal> represents the concrete type
                of the current instance, and</para>
            </listitem-->
            <listitem>
                <para>a type class bound, <literal>given X is T</literal>, specifies that the
                type class of the type parameter is a subtype of a given type <literal>T</literal>
                <emphasis>(note that type classes are a proposed feature for a future version
                of the language)</emphasis>,</para>
            </listitem>
            <listitem>
                <para>an initialization parameter specification, <literal>given X(...)</literal>
                specifies that the type parameter <literal>X</literal> is a class with
                the given formal parameter types.</para>
            </listitem>
        </itemizedlist>
        
        <para>An initialization parameter specification allows instantiation of the type 
        represented by the type parameter within the body of the declaration.</para>
        
        <para>A constraint may not refer to a sequenced type parameter.</para>
        
        <para>A single <literal>given</literal> clause may specify multiple constraints
        on a certain type parameter. For example, it may specify multiple upper bounds
        together with an initialization parameter specification. If multiple upper bounds
        are specified, at most one upper bound may be a class.</para>
        
        <!--
        <para>Subtype bounds are needed since the special type <literal>subtype</literal>
        cannot appear in a contravariant position. A subtype bound cannot be applied to
        a covariant or contravariant type parameter.</para>
        -->
        
        <para>A constraint affects the type arguments that can be assigned to a type
        parameter:</para>
        
        <itemizedlist>
            <listitem>
                <para>A type argument to a type parameter with an upper bound must be a type 
                which is a subtype of all upper bounds.</para>
            </listitem>
            <listitem>
                <para>A type argument to a type parameter with a lower bound must be a type 
                of which all lower bounds are subtypes.</para>
            </listitem>
        </itemizedlist>
        
        <para>Within the body of the declaration, a constraint affects the assignability of 
        a type parameter:</para>
        
        <itemizedlist>
            <listitem>
                <para>A type parameter is considered a subtype of its upper bound.</para>
            </listitem>
            <listitem>
                <para>The lower bound of a type parameter is considered a subtype of the
                type parameter.</para>
            </listitem>
            <listitem>
                <para>A metamodel reference to the type parameter is assignable to the type
                class bound.</para>
            </listitem>
        </itemizedlist>
        
        <programlisting>given X satisfies Number&lt;X&gt;
given Y(Natural count) satisfies Number&lt;Y&gt;</programlisting>
       
        <programlisting>given S satisfies Decimal[n]</programlisting>

        <programlisting>given T satisfies Ordinal, Comparable&lt;T&gt; abstracts X</programlisting>
        
        <programlisting>given N is Monoid&lt;N&gt;</programlisting>
    
        <para>Every type parameter has an implicit upper bound of type <literal>Void</literal>.</para>
        
        <!--  
        <comment><para>TODO: eventually we should support the ability to implicitly pass in an
        extension that is imported by the client code, using a type constraint of form:</para>
        <programlisting>given extension E(X x) satisfies Format</programlisting>
        <para>(We would need to define an identity extension in <literal>ceylon.language</literal>.)</para>
        <para>In the following special case, this lets us implement a Haskell-style type class 
        as an extension of the metatype:</para>
        <programlisting>given extension E(Type&lt;X&gt; tx) satisfies Monoid&lt;X&gt;</programlisting>
        <para>The extension type would be inferred at the point of invocation, using the usual
        rules for searching for extensions.</para>
        </comment>
        -->
        
        <!-- 
        <comment><para>TODO: at some stage it would be very interesting to support "assignability
        upper bounds", for example <literal>given X is String</literal>, where the client code is
        required to have an enabled extension that introduces the bound <literal>String</literal>
        to the type parameter <literal>X</literal>. Under the covers this extension would be passed
        as a <literal>Callable&lt;String,X&gt;</literal> to the initializer or method that declares 
        the constrained type parameter. Scala calls this feature "view bounds".</para></comment>
        -->
        
        <!--
        <comment><para>TODO: Should we move <literal>in</literal> and <literal>out</literal>
        down to the <literal>given</literal> clause?</para></comment>
        -->
        
        <para>Note that an upper bound type constraint of form:</para>
        
        <programlisting>given X satisfies T</programlisting>
        
        <para>is equivalent to a type class bound of this form:</para>
        
        <programlisting>given X is Type&lt;T&gt;</programlisting>
        
        <para>and that an initialization parameter specification type constraint of form:</para>
        
        <programlisting>given X(A a, B b)</programlisting>
        
        <para>is equivalent to a type class bound of this form:</para>
        
        <programlisting>given X is ConcreteClass&lt;X,A,B&gt;</programlisting>
{'fraction_non_alphanumeric': 0.09317495263939378, 'fraction_numerical': 0.00010240131073677743, 'mean_word_length': 2.124492081266997, 'pattern_counts': {'":': 0, '<': 2721, '<?xml version=': 0, '>': 2721, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6019314', 'n_tokens_mistral': 25312, 'n_tokens_neox': 23748, 'n_words': 8522}