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.