diff --git a/typechecker/Ceylon.g b/typechecker/Ceylon.g index 89e23846c51..be1d8a8b303 100644 --- a/typechecker/Ceylon.g +++ b/typechecker/Ceylon.g @@ -344,6 +344,21 @@ objectDeclaration returns [ObjectDefinition declaration] ) ; +objectExpression returns [ObjectExpression term] + : OBJECT_DEFINITION + { $term = new ObjectExpression($OBJECT_DEFINITION); } + ( + extendedType + { $term.setExtendedType($extendedType.extendedType); } + )? + ( + satisfiedTypes + { $term.setSatisfiedTypes($satisfiedTypes.satisfiedTypes); } + )? + classBody + { $term.setClassBody($classBody.classBody); } + ; + voidOrInferredMethodDeclaration returns [AnyMethod declaration] @init { MethodDefinition def=null; MethodDeclaration dec=null; } @@ -1105,7 +1120,7 @@ declarationStart | ASSIGN | INTERFACE_DEFINITION | CLASS_DEFINITION - | OBJECT_DEFINITION + | OBJECT_DEFINITION (LIDENTIFIER|UIDENTIFIER) //to disambiguate object expressions | ALIAS | variadicType LIDENTIFIER | DYNAMIC (LIDENTIFIER|UIDENTIFIER) @@ -1148,7 +1163,10 @@ unambiguousType ; statement returns [Statement statement] - : directiveStatement + : /*(IF_CLAUSE conditions THEN_CLAUSE) => + expressionOrSpecificationStatement + { $statement = $expressionOrSpecificationStatement.statement; } + |*/ directiveStatement { $statement = $directiveStatement.directive; } | controlStatement { $statement = $controlStatement.controlStatement; } @@ -1165,8 +1183,12 @@ expressionOrSpecificationStatement returns [Statement statement] es.setExpression($expression.expression); if ($expression.expression.getTerm() instanceof AssignOp) { AssignOp a = (AssignOp) $expression.expression.getTerm(); - if (a.getLeftTerm() instanceof BaseMemberExpression || - a.getLeftTerm() instanceof ParameterizedExpression) { + Term lt = a.getLeftTerm(); + if (lt instanceof BaseMemberExpression || + lt instanceof ParameterizedExpression || + lt instanceof QualifiedMemberExpression && + ((QualifiedMemberExpression) lt).getPrimary() instanceof This && + ((QualifiedMemberExpression) lt).getMemberOperator() instanceof MemberOp) { Expression e = new Expression(null); e.setTerm(a.getRightTerm()); SpecifierExpression se = new SpecifierExpression(null); @@ -1618,6 +1640,11 @@ sequencedArgument returns [SequencedArgument sequencedArgument] { sequencedArgument = new SequencedArgument(null); sequencedArgument.getCompilerAnnotations().addAll($compilerAnnotations.annotations); } ( + (FOR_CLAUSE | IF_CLAUSE conditions ~THEN_CLAUSE)=> + c1=comprehension + { if ($c1.comprehension!=null) + $sequencedArgument.addPositionalArgument($c1.comprehension); } + | pa1=positionalArgument { if ($pa1.positionalArgument!=null) $sequencedArgument.addPositionalArgument($pa1.positionalArgument); } @@ -1625,29 +1652,26 @@ sequencedArgument returns [SequencedArgument sequencedArgument] sa1=spreadArgument { if ($sa1.positionalArgument!=null) $sequencedArgument.addPositionalArgument($sa1.positionalArgument); } - | - c1=comprehension - { if ($c1.comprehension!=null) - $sequencedArgument.addPositionalArgument($c1.comprehension); } ) ( c=COMMA { $sequencedArgument.setEndToken($c); } ( + (FOR_CLAUSE | IF_CLAUSE conditions ~THEN_CLAUSE)=> + c2=comprehension + { if ($c2.comprehension!=null) { + $sequencedArgument.addPositionalArgument($c2.comprehension); + sequencedArgument.setEndToken(null); } } + | pa2=positionalArgument { if ($pa2.positionalArgument!=null) { $sequencedArgument.addPositionalArgument($pa2.positionalArgument); sequencedArgument.setEndToken(null); } } - | + | sa2=spreadArgument { if ($sa2.positionalArgument!=null) { $sequencedArgument.addPositionalArgument($sa2.positionalArgument); sequencedArgument.setEndToken(null); } } - | - c2=comprehension - { if ($c2.comprehension!=null) { - $sequencedArgument.addPositionalArgument($c2.comprehension); - sequencedArgument.setEndToken(null); } } | { displayRecognitionError(getTokenNames(), new MismatchedTokenException(LIDENTIFIER, input)); } @@ -1953,8 +1977,14 @@ functionOrExpression returns [Expression expression] f=anonymousFunction { $expression = new Expression(null); $expression.setTerm($f.function); } + | ce=conditionalExpression + { $expression = new Expression(null); + $expression.setTerm($ce.term); } | e=expression { $expression = $e.expression; } + | oe=objectExpression + { $expression = new Expression(null); + $expression.setTerm($oe.term); } | l=let { $expression = new Expression(null); $expression.setTerm($l.let); } @@ -1988,6 +2018,102 @@ let returns [LetExpression let] lc.setExpression(e); } ; +conditionalExpression returns [Term term] + : ifExpression + { $term = $ifExpression.term; } + | switchExpression + { $term = $switchExpression.term; } + ; + +switchExpression returns [SwitchExpression term] + : switchHeader + { $term = new SwitchExpression(null); + $term.setSwitchClause($switchHeader.clause); } + caseExpressions + { $term.setSwitchCaseList($caseExpressions.switchCaseList); + //TODO: huge copy/paste job from switchCaseElse + Expression ex = $switchHeader.clause.getExpression(); + if (ex!=null && ex.getTerm() instanceof BaseMemberExpression) { + Identifier id = ((BaseMemberExpression) ex.getTerm()).getIdentifier(); + for (CaseClause cc: $caseExpressions.switchCaseList.getCaseClauses()) { + CaseItem item = cc.getCaseItem(); + if (item instanceof IsCase) { + IsCase ic = (IsCase) item; + Variable v = new Variable(null); + v.setType(new SyntheticVariable(null)); + v.setIdentifier(id); + SpecifierExpression se = new SpecifierExpression(null); + Expression e = new Expression(null); + BaseMemberExpression bme = new BaseMemberExpression(null); + bme.setIdentifier(id); + bme.setTypeArguments( new InferredTypeArguments(null) ); + e.setTerm(bme); + se.setExpression(e); + v.setSpecifierExpression(se); + ic.setVariable(v); + } + } + } + } + ; + +caseExpressions returns [SwitchCaseList switchCaseList] + : { $switchCaseList = new SwitchCaseList(null); } + ( + caseExpression + { $switchCaseList.addCaseClause($caseExpression.clause); } + )+ + ( + defaultCaseExpression + { $switchCaseList.setElseClause($defaultCaseExpression.clause); } + )? + ; + +caseExpression returns [CaseClause clause] + : CASE_CLAUSE + { $clause = new CaseClause($CASE_CLAUSE); } + caseItemList + { $clause.setCaseItem($caseItemList.item); } + disjunctionExpression + { Expression e = new Expression(null); + e.setTerm($disjunctionExpression.term); + $clause.setExpression(e); } + ; + +defaultCaseExpression returns [ElseClause clause] + : ELSE_CLAUSE + { $clause = new ElseClause($ELSE_CLAUSE); } + disjunctionExpression + { Expression e = new Expression(null); + e.setTerm($disjunctionExpression.term); + $clause.setExpression(e); } + ; + +ifExpression returns [IfExpression term] + : IF_CLAUSE + { $term = new IfExpression(null); + IfClause ic = new IfClause($IF_CLAUSE); + ElseClause ec = new ElseClause(null); + $term.setIfClause(ic); + $term.setElseClause(ec); } + conditions + { $term.getIfClause().setConditionList($conditions.conditionList); } + ( + THEN_CLAUSE + de1=disjunctionExpression + { Expression e = new Expression($THEN_CLAUSE); + e.setTerm($de1.term); + $term.getIfClause().setExpression(e); } + )? + ( + ELSE_CLAUSE + de2=disjunctionExpression + { Expression e = new Expression($ELSE_CLAUSE); + e.setTerm($de2.term); + $term.getElseClause().setExpression(e); } + )? + ; + anonymousFunction returns [FunctionArgument function] @init { $function = new FunctionArgument(null); $function.setType(new FunctionModifier(null)); } @@ -2027,7 +2153,8 @@ comprehension returns [Comprehension comprehension] comprehensionClause returns [ComprehensionClause comprehensionClause] : forComprehensionClause { $comprehensionClause = $forComprehensionClause.comprehensionClause; } - | ifComprehensionClause + | (IF_CLAUSE conditions ~THEN_CLAUSE) => + ifComprehensionClause { $comprehensionClause = $ifComprehensionClause.comprehensionClause; } | expressionComprehensionClause { $comprehensionClause = $expressionComprehensionClause.comprehensionClause; } @@ -2105,11 +2232,7 @@ thenElseExpression returns [Term term] // to distinguish between "if (...) then" and // the control structure "if (...) { ... }" /*| - ( - IF_CLAUSE LPAREN ( existsCondition | nonemptyCondition | isCondition ) RPAREN - | - TYPE_CONSTRAINT LPAREN specifiedConditionVariable RPAREN - )+ + IF_CLAUSE conditions THEN_CLAUSE disjunctionExpression (ELSE_CLAUSE disjunctionExpression)?*/ ; @@ -2609,10 +2732,24 @@ defaultedType returns [Type type] { $type=$variadicType.type; } ; +spreadType returns [Type type] + @init { SpreadType spt = null; } + : PRODUCT_OP + { spt = new SpreadType($PRODUCT_OP); + $type=spt; } + ( + sp=type + { spt.setType($sp.type); } + )? + ; + tupleType returns [TupleType type] : LBRACKET { $type = new TupleType($LBRACKET); } ( + spt=spreadType + { $type.addElementType($spt.type); } + | t1=defaultedType { $type.addElementType($t1.type); } ( @@ -2763,6 +2900,9 @@ abbreviatedType returns [StaticType type] bt.setReturnType($type); $type=bt; } ( + spt=spreadType + { bt.addArgumentType($spt.type); } + | t1=defaultedType { if ($t1.type!=null) bt.addArgumentType($t1.type); } @@ -3128,6 +3268,13 @@ caseBlock returns [CaseClause clause] { $clause.setBlock($block.block); } ; +defaultCaseBlock returns [ElseClause clause] + : ELSE_CLAUSE + { $clause = new ElseClause($ELSE_CLAUSE); } + block + { $clause.setBlock($block.block); } + ; + caseItemList returns [CaseItem item] : LPAREN //TODO: we really should not throw away this token! ( @@ -3139,13 +3286,6 @@ caseItemList returns [CaseItem item] $item.setEndToken($RPAREN); } ; -defaultCaseBlock returns [ElseClause clause] - : ELSE_CLAUSE - { $clause = new ElseClause($ELSE_CLAUSE); } - block - { $clause.setBlock($block.block); } - ; - caseItem returns [CaseItem item] : (IS_OP)=>isCaseCondition { $item=$isCaseCondition.item; } @@ -3758,6 +3898,14 @@ BACKTICK : '`' ; +ABSTRACTED_TYPE + : 'abstracts' + ; + +ALIAS + : 'alias' + ; + ASSEMBLY : 'assembly' ; @@ -3766,18 +3914,10 @@ ASSERT : 'assert' ; -ABSTRACTED_TYPE - : 'abstracts' - ; - ASSIGN : 'assign' ; -ALIAS - : 'alias' - ; - BREAK : 'break' ; @@ -3822,6 +3962,10 @@ FOR_CLAUSE : 'for' ; +FUNCTION_MODIFIER + : 'function' + ; + TYPE_CONSTRAINT : 'given' ; @@ -3830,24 +3974,20 @@ IF_CLAUSE : 'if' ; -SATISFIES - : 'satisfies' - ; - IMPORT : 'import' ; -INTERFACE_DEFINITION - : 'interface' +IN_OP + : 'in' ; -VALUE_MODIFIER - : 'value' +INTERFACE_DEFINITION + : 'interface' ; -FUNCTION_MODIFIER - : 'function' +IS_OP + : 'is' ; LET @@ -3862,18 +4002,38 @@ NEW : 'new' ; -PACKAGE - : 'package' - ; - NONEMPTY : 'nonempty' ; +OBJECT_DEFINITION + : 'object' + ; + +CASE_TYPES + : 'of' + ; + +OUT + : 'out' + ; + +OUTER + : 'outer' + ; + +PACKAGE + : 'package' + ; + RETURN : 'return' ; +SATISFIES + : 'satisfies' + ; + SUPER : 'super' ; @@ -3890,22 +4050,6 @@ THIS : 'this' ; -OUTER - : 'outer' - ; - -OBJECT_DEFINITION - : 'object' - ; - -CASE_TYPES - : 'of' - ; - -OUT - : 'out' - ; - THROW : 'throw' ; @@ -3914,6 +4058,10 @@ TRY_CLAUSE : 'try' ; +VALUE_MODIFIER + : 'value' + ; + VOID_MODIFIER : 'void' ; @@ -4083,14 +4231,6 @@ COMPARE_OP : '<=>' ; -IN_OP - : 'in' - ; - -IS_OP - : 'is' - ; - POWER_OP : '^' ; diff --git a/typechecker/Ceylon.nodes b/typechecker/Ceylon.nodes index 82c6df9f08d..8b4d2888831 100644 --- a/typechecker/Ceylon.nodes +++ b/typechecker/Ceylon.nodes @@ -360,6 +360,9 @@ ^(DEFAULTED_TYPE:TYPE TYPE) +^(SPREAD_TYPE:TYPE + TYPE) + "A control directive." ^(abstract DIRECTIVE:EXECUTABLE_STATEMENT) ^(RETURN:DIRECTIVE EXPRESSION? @@ -420,9 +423,11 @@ ELSE_CLAUSE?) ^(IF_CLAUSE:CONTROL_CLAUSE CONDITION_LIST - BLOCK?) + BLOCK? + EXPRESSION?) ^(ELSE_CLAUSE:CONTROL_CLAUSE - BLOCK?) + BLOCK? + EXPRESSION?) ^(SWITCH_STATEMENT:CONTROL_STATEMENT SWITCH_CLAUSE @@ -434,7 +439,8 @@ ELSE_CLAUSE?) ^(CASE_CLAUSE:CONTROL_CLAUSE CASE_ITEM - BLOCK?) + BLOCK? + EXPRESSION?) ^(CASE_ITEM) ^(MATCH_CASE:CASE_ITEM @@ -649,7 +655,9 @@ ^(abstract STATIC_MEMBER_OR_TYPE_EXPRESSION:MEMBER_OR_TYPE_EXPRESSION IDENTIFIER - TYPE_ARGUMENTS?) + TYPE_ARGUMENTS? + ProducedTypedReference targetParameter; + ProducedType parameterType;) ^(abstract BASE_MEMBER_OR_TYPE_EXPRESSION:STATIC_MEMBER_OR_TYPE_EXPRESSION) @@ -733,6 +741,23 @@ BLOCK? Method declarationModel;) +"An anonymous function." +^(OBJECT_EXPRESSION:TERM + EXTENDED_TYPE? + SATISFIED_TYPES? + CLASS_BODY + Class anonymousClass;) + +"An if/then/else conditional expression." +^(IF_EXPRESSION:TERM + IF_CLAUSE + ELSE_CLAUSE) + +"A switch/case/else conditional expression." +^(SWITCH_EXPRESSION:TERM + SWITCH_CLAUSE + SWITCH_CASE_LIST) + "A named argument." ^(abstract NAMED_ARGUMENT:STATEMENT_OR_ARGUMENT IDENTIFIER? diff --git a/typechecker/en/modules/declarations.xml b/typechecker/en/modules/declarations.xml index 29f2328b9fc..93d2f5c1056 100644 --- a/typechecker/en/modules/declarations.xml +++ b/typechecker/en/modules/declarations.xml @@ -1134,7 +1134,7 @@ TypeConstraints? class Graph() { OpenList<Node> nodes = ArrayList<Node>(); class Node() { - nodes.add(this); //compiler error (this reference in initializer) + nodes.add(this); //error: self reference in initializer } } @@ -1142,7 +1142,7 @@ TypeConstraints? class Node() {} Node createNode() { Node node = Node(); - nodes.add(node); //compiler error (forward reference in initializer) + nodes.add(node); //error: forward reference in initializer return node; } OpenList<Node> nodes = ArrayList<Node>(); diff --git a/typechecker/en/modules/expressions.xml b/typechecker/en/modules/expressions.xml index 45b47cbc5b4..3921ff0cd80 100644 --- a/typechecker/en/modules/expressions.xml +++ b/typechecker/en/modules/expressions.xml @@ -589,15 +589,24 @@ Digit{1,2} ":" Digit{2} ( ":" Digit{2} ( ":" Digit{3} )? )? the realization of the referenced function or class. If a callable reference expression refers to a generic declaration, - either: + it must either: - it must be immediately followed by an argument list, - allowing the compiler to infer the type arguments, or + have an explicit type argument list, + + + be immediately followed by an argument list, allowing the + compiler to infer the type arguments, as defined in + , or - it must have an explicit type argument list. + occur as a listed argument, as defined in + in a positional argument + list, or as a specified argument, anonymous argument, or + listed argument, as defined in , + in a named argument list, and its type arguments must be + inferable as defined below. @@ -621,6 +630,27 @@ Digit{1,2} ":" Digit{2} ( ":" Digit{2} ( ":" Digit{3} )? )? reference. This would also allow static references like Person.@name. + If a callable reference f with no explicit type + argument list occurs as the argument to a callable parameter p + of a function or class in a direct invocation expression, as defined below in + , then the type arguments of f + are inferred according to the rules defined in + as if the types of the parameters of p were the types of + listed arguments of f in a positional argument list, unless + the invoked function or class is generic, and the invocation expression does + not itself specify explicit type arguments, in which case any parameter whose + type involves a type argument of the invoked function or class is ignored. + + If a callable reference f with no explicit type + argument list occurs as the argument to a value parameter p + of type Callable<Return,Args> in a direct or indirect + invocation expression, then the type arguments of f are + inferred according to the rules defined in + as if Args were the type of a positional argument list, unless + the invocation is a direct invocation expression, and the invoked function or + class is generic, and Args involves type parameters of the + invoked function or class. +
@@ -652,6 +682,32 @@ Digit{1,2} ":" Digit{2} ( ":" Digit{2} ( ":" Digit{3} )? )? A static expression must reference a statically typed declaration with no missing types, even within a dynamic block. + If the qualifying type in a static expression refers to a generic declaration, then + either: + + + + it must have an explicit type argument list, or + + + the static expression must occur as a listed argument, as defined in + in a positional argument list, or as a + specified argument, anonymous argument, or listed argument, as defined in + , in a named argument list, and its type + arguments must be inferable as defined below. + + + + If a static expression T.m for a generic type T + with no explicit type argument list occurs as the argument to a parameter p + of type Callable<Return,Arg> in a direct or indirect invocation + expression, then the type arguments of T are inferred according to the + rules defined in as if Arg + were the type of a positional argument list, and [T] were the type of + a parameter list, unless the invocation is a direct invocation expression, and the invoked + function or class is generic, and Arg involves type parameters of the + invoked function or class. +
@@ -2274,7 +2330,7 @@ Digit{1,2} ":" Digit{2} ( ":" Digit{2} ( ":" Digit{3} )? )? lhs[index] lookup - lhs.item(index) + lhs.get(index) Correspondence<X,Y> X Y? diff --git a/typechecker/en/modules/statementblocks.xml b/typechecker/en/modules/statementblocks.xml index a78aad3a51f..ad6b0b966e0 100644 --- a/typechecker/en/modules/statementblocks.xml +++ b/typechecker/en/modules/statementblocks.xml @@ -602,7 +602,7 @@ Integer f(Integer n) => n+package.n; This code is not legal, since the body of a function is an ordinary block: Float->Float xy() { - Float x => y; //compiler error: y is not referenceable + Float x => y; //error: y is not referenceable Float y => x; return x->y; } @@ -611,7 +611,7 @@ Integer f(Integer n) => n+package.n; section of the class body: class Point() { - Float x => y; //compiler error: y is not referenceable + Float x => y; //error: y is not referenceable Float y => x; Float->Float xy = x->y; } @@ -663,7 +663,7 @@ Integer f(Integer n) => n+package.n; The following code is not legal: interface Point { - value x => y; //compiler error: type of y is not inferrable + value x => y; //error: type of y is not inferrable value y => x; } @@ -1057,11 +1057,12 @@ Integer f(Integer n) => n+package.n; The persistent value of a forward-declared reference or the implementation of a forward-declared function may be specified by a value specification statement. The value specification statement consists of an unqualified - value reference and an ordinary = specifier. The value reference - must refer to a declaration which sequentially occurs earlier in the body in which - the specification statement occurs. + value reference, or a qualified value reference where the receiver expression is + `this`, and an ordinary = specifier. The value reference must + refer to a declaration which sequentially occurs earlier in the body in which the + specification statement occurs. - ValueSpecification: MemberName Specifier ";" + ValueSpecification: ("this" ".")? MemberName Specifier ";" The type of the specified expression must be assignable to the type of the reference, or to the callable type of the function. @@ -1100,11 +1101,13 @@ else { - an unqualified value reference and a lazy + an unqualified value reference, or a qualified value reference + where the receiver expression is `this`, and a lazy => specifier, or - a unqualified callable reference, one or more parameter lists, + a unqualified callable reference, or a qualified value reference + where the receiver expression is `this`, one or more parameter lists, and a lazy specifier. @@ -1120,7 +1123,7 @@ else { R. Then the type of the parameterized reference is R. - ParameterizedReference: MemberName Parameters+ + ParameterizedReference: ("this" ".")? MemberName Parameters+ Thus, the specification statement consists of a parameterized reference followed by a lazy specifier. diff --git a/typechecker/en/modules/typesystem.xml b/typechecker/en/modules/typesystem.xml index 41d83b869c0..a5b3c300c55 100644 --- a/typechecker/en/modules/typesystem.xml +++ b/typechecker/en/modules/typesystem.xml @@ -57,7 +57,8 @@ An applied type, defined in , is formed by specifying arguments for the - generic type parameters of a parameterized type. + generic type parameters of a parameterized type declaration, and is called an + instantiation of the parameterized type declaration. A union type, defined in , @@ -193,7 +194,7 @@ and - packages have their own dedicated namespace. + packages and modules have their own dedicated namespace. @@ -206,8 +207,8 @@ uppercase letter may be forced into the namespace of methods and attributes by prefixing the identifier \i. A keyword may be used as an identifier by prefixing the keyword with either \i or - \I. This allows interoperation with languages like Java - which do not enforce these naming conventions. + \I. This allows interoperation with other languages like + Java and JavaScript which do not enforce these naming conventions.
@@ -267,8 +268,8 @@ or toplevel value. A value schema, function schema, or parameter list with a missing type or types - may be defined. A value schema, function schema, or parameter list with a missing type - is called partially typed. + may be defined. Any such schema, or parameter list with a missing type is called + partially typed. Two signatures are considered identical if they have exactly the same types, at exactly the same positions, and missing types at exactly the same positions. @@ -292,7 +293,12 @@ two member classes with the same name. - + + Note: the Ceylon compiler itself is able to represent type schemas + with overloaded members and reason about overloading, and does so when compiling + code that calls native Java types. However, this behavior is outside the scope of + this specification. +
@@ -331,7 +337,7 @@ - Every interface type is a subtype of the class Object + Also, every interface type is a subtype of the class Object defined in ceylon.language. If X is a subtype of Y, then: @@ -374,6 +380,9 @@ X and Y, and an instance of either type is an instance of the union type. + Note: the type expression X|Y is pronounced + “x or y”. + The union type constructor | is associative, so the union of three types, X, Y, and Z, may be written X|Y|Z. @@ -470,6 +479,9 @@ and any object which is an instance of both types is an instance of the intersection type. + Note: the type expression X&Y is pronounced + “x and y”. + The intersection type constructor & is associative, so the intersection of three types, X, Y, and Z, may be written X&Y&Z. @@ -707,12 +719,11 @@ PrimaryType: AtomicType | OptionalType | SequenceType | CallableType AtomicType: QualifiedType | EmptyType | TupleType | IterableType - First, there are postfix-style abbreviations for optional types, - sequence types, and callable types. + First, there are postfix-style abbreviations for optional types + and sequence types. OptionalType: PrimaryType "?" SequenceType: PrimaryType "[" "]" - CallableType: PrimaryType "(" TypeList? ")" @@ -721,11 +732,28 @@ X[] means Sequential<X> - for any type X, and + for any type X, + + + Note: the type expression X? is pronounced + as “maybe x”, and X[] as + “sequence of x”. + + Next, there are type abbreviations for callable types + which represent the types of a functions. + + CallableType: PrimaryType "(" TypeList? ")" + + X(Y,Z) means Callable<X,[Y,Z]> - where Y,Z is a list of types of any length. + where Y,Z is a list of types of any length, and + + + X(*Y) means Callable<X,Y> + for any type X, and any subtype Y of + Sequential<Anything>. @@ -741,11 +769,6 @@ IterableType: "{" UnionType ("*"|"+") "}" - {X*} means Iterable<X,Null> for any type X, and @@ -756,6 +779,10 @@ + Note: the type expression {X*} is pronounced + as “stream of x”, and {X+} as + “nonempty stream of x”. + Next, abbreviations for sequence types and tuple types may be written using brackets. @@ -951,8 +978,8 @@ Float|Integer num = one; the types they alias. Thus, circular type alias definitions, as in the following example, are illegal: - List; -alias Y => List;]]> + List; //error: circular type alias definition +alias Y => List; //error: circular type alias definition]]> Replacement of type aliases with the types they alias occurs at compile time, so type aliases are not reified types, as specified in @@ -1068,6 +1095,7 @@ alias Y => List;]]> The type arguments may not be inferred from the initializer arguments. + extends Singleton<String>("") extends Person(name, org) A member class annotated actual may use the qualifier @@ -1119,9 +1147,9 @@ alias Y => List;]]> satisfied type is a parameterized type, the satisfies clause must specify type arguments. - satisfies Sequence<Element> & Collection<Element> + satisfies Correspondence<Integer,Element> & Collection<Element> - A satisfies clause may not contain two types produced from + A satisfies clause may not contain two instantiations of the same type declaration.
@@ -1215,7 +1243,7 @@ alias Y => List;]]> Note: however, a type is not considered automatically assignable to the union of its cases, or to its self type. Instead, the type must be explicitly narrowed to the union of its cases, - or to its self type, using either the of operator or the + nor to its self type, using either the of operator or the switch construct. This narrowing type conversion can be statically checked—if X covers Y then Y of X is guaranteed to succeed at runtime. @@ -1307,7 +1335,7 @@ Item item = comp of Item; - two types produced from the same type declaration, or + two instantiations of the same type declaration, or two value references to a single toplevel anonymous class. @@ -1383,10 +1411,10 @@ interface Function satisfies Expression { ... } interface StringLiteral - satisfies Expression { ... } + satisfies Expression { ... } //error String is not exactly Nothing interface NumberLiteral - satisfies Expression { ... }]]> + satisfies Expression { ... } //error Integer|Float is not exactly Nothing]]> Note: these rules could be relaxed to allow the definition of generic enumerated types where the list of cases of an instantiation of a @@ -1434,10 +1462,16 @@ interface NumberLiteral disjoint, - X is an union type A|B and + X is a union type A|B and both Y and A are disjoint and Y and B are disjoint, + + X is an enumerated type with cases + A1|A2|... and for every case Ai + of X, Y and Ai + are disjoint, + X is an intersection type A&B and either Y and A are disjoint or @@ -1456,6 +1490,10 @@ interface NumberLiteral Y are disjoint if: + X is an invariant subtype of Sequence<A>, Y is an invariant subtype of Sequence<B>, @@ -1475,9 +1513,10 @@ interface NumberLiteral - Note: the soundness of these rules is guaranteed by the implementations of the - sealed types Sequence, Sequential, and - Tuple in the module ceylon.language. + Note: the soundness of these rules is guaranteed by the + implementations of the sealed types Sequence, + Sequential, and Tuple in the module + ceylon.language. @@ -1486,7 +1525,7 @@ interface NumberLiteral
Generic type parameters - Function, class, and interface schemas may be parameterized by one or more + A function, class, or interface schema may be parameterized by one or more generic type parameters. A parameterized type schema defines a type constructor, a function that produces a type given a tuple of compatible type arguments. A parameterized class or function schema defines a function that produces the @@ -1532,9 +1571,9 @@ interface NumberLiteral the body of the Entry class. The following identifier names usually refer to a type parameter: Element, Other, This, Value, Key, - Item, Argument, Args and - Result. Avoid, where reasonable, using these names for interfaces - and classes. + Item, Absent, Argument, + Args and Result. Avoid, where reasonable, using + these names for interfaces and classes.
Type parameters and variance @@ -1542,11 +1581,11 @@ interface NumberLiteral A type parameter allows a declaration to be abstracted over a constrained set of types. - TypeParameter: Variance? TypeName ("=" Type) + TypeParameter: Variance TypeName ("=" Type) Every type parameter has a name and a variance. - Variance: "out" | "in" + Variance: ("out" | "in")? @@ -1868,16 +1907,14 @@ interface NumberLiteral Note: in Ceylon 1.0, a type parameter with multiple upper bounds may not have an upper bound which is another type parameter. - ]]> - - ]]> + & Comparable]]> A type parameter is a subtype of its upper bounds. (shared Value value) - extends Object + extends Object() given Value satisfies Object { shared actual Boolean equals(Object that) { if (is Holder that) { @@ -1971,7 +2008,8 @@ interface NumberLiteral A list of type arguments produces a new type schema from a parameterized type schema, or a new function schema from a from a parameterized function schema. In the case of a type schema, this new schema is - the schema of an applied type. + the schema of an applied type, and is called an instantiation of the parameterized + type schema. A type argument list is a list of types. @@ -1982,7 +2020,7 @@ interface NumberLiteral <Key, List<Item>> <String, Person?> - <String[], [{Object*}]> + <String[](Integer), [{Object*}]> Type arguments are assigned to type parameters according to the positions they occur in the list. @@ -2035,10 +2073,11 @@ interface NumberLiteral A type argument to a type parameter T with an - enumerated type bound must be a subtype of one of the enumerated types - of T, or it must be a type parameter A - with an enumerated type bound where every enumerated type of - A is also an enumerated type of T. + enumerated bound must be a subtype of one of the enumerated types of the + bound on T, or it must be a type parameter A + with an enumerated bound where every enumerated type of the bound on + A is a subtype of one of the enumerated types of the + bound on T.