Conditions and condition lists
Ceylon allows one or more conditions, which together form a condition list,
in the if
, while
, and assert
statements and in if
comprehension clauses.
Note: This page is not describing the is
,
exists
, and nonempty
operators, which are considered a part of the expression grammar.
Usage
A condition list may occur in an if
, while
, or
assert
statements, or in an if
clause of a
comprehension.
Description
A condition list is satisfied if and only if every condition in the list is
satisfied. The difference between a commaseparated condition list and a single
Boolean
condition constructed using the &&
operator
is that a condition list may narrow the type of a reference, or introduce a new
reference.
Integer m(Object x) {
if (is Integer x, x < 10) {
// x is of type Integer here
return x + 1;
}
return 0;
}
Note: In the following discussion we will use if
in the code examples.
Keep in mind that condition lists may also occur in a while
or assert
statement.
Boolean conditions
A boolean condition is an expression of type Boolean
. It is satisfied
if the expression evaluates to true
.
is
conditions
A condition of form is Y x
is satisfied if the reference x
evaluates
to an instance of the type Y
. Within the associated block, x
will have
the type X&Y
, where X
is the previous type of x
.
In other words, if (is Y x)
similar to Java's if (x instanceof Y)
,
immediately followed by a typecast, (Y) x
.
Integer plusOneIfInteger(Object x) {
if (is Integer x) {
// x is of type Integer here
return = x+1;
}
return 0;
}
It's even possible to introduce a new local reference in the condition, in which case it is the new local reference which has the narrowed type:
Integer plusOneIfInteger(Object x) {
if (is Integer i=x) {
// x still of type Object here
// but i is an Integer
return i+1;
}
return 0;
}
For a variable
reference or getter you are required to use this form.
On a platform that supports concurrency this protects you from another
thread changing the value while the block protected by the if
is being
executed (and potentially violating the guarantees of the type system).
It is acceptable to specify a generic type in an is
condition, for
example, if (is List<Integer> list)
to distinguish a List<Integer>
from a List<String>
.
Note: Do not confuse the is
condition of form is Type t
with
an is
operator of form t is Type
.
exists
conditions
A condition of form exists x
means is Object x
, and is satisfied
if the reference x
refers to a nonnull
value. Within the associated
block, x
will have the nonoptional type X&Object
, where X
is the
previous type of x
.
In other words, if (exists x)
is similar to Java's if (x != null)
.
Integer plusOneIfExists(Integer? x) {
if (exists x) {
// x is of type Integer here
return x+1;
}
return 0;
}
It's possible to introduce a new local reference in the condition, in which case it is the new local reference that has the narrowed type:
Integer plusOneIfExists(Integer? x) {
if (exists i=x) {
// x still of type Integer? here
return i+1;
}
return 0;
}
Note: Do not confuse the exists
condition of form exists t
with an exists
operator of form t exists
.
exists
conditions with destructuring
In if
and while
statement
you can perform destructuring in an exists
condition:
[Float, Float]? point = nothing;
if (exists [x, y] = point) {
plotPoint(x,y);
}
[Float, Float]? nextPoint() => nothing;
while (exists [x, y] = nextPoint()) {
plotPoint(x,y);
}
nonempty
conditions
A condition of form nonempty xs
means is [X+] xs
, where X
is the
element type of the sequence reference x
, and is satisfied if the x
refers to a nonempty sequence. Within the associated block, x
will
have the nonempty type [X+]
.
Integer firstPlusOne(Integer[] xs) {
if (nonempty xs) {
// xs of type [Integer+] here
return xs.first+1;
}
return 0;
}
It's possible to introduce a new local reference in the condition, in which case it is the new local reference which has the narrowed type:
Integer firstPlusOne(Integer[] xs) {
if (nonempty ys=xs) {
// xs still of type Integer[] here
return ys.first+1;
}
return 0;
}
nonempty
conditions with destructuring
In if
and while
statement
you can perform destructuring in a nonempty
condition
if (nonempty [name, *rest] = process.arguments) {
print("Hello ``name``!");
}
Note: Do not confuse the nonempty
condition of form nonempty xs
with a nonempty
operator of form xs nonempty
.
See also

if
statement, 
while
statement, assert
statement comprehensions
 destructuring
 Control structure conditions in the Ceylon language spec