Nullable Expressions
All four Elements languages allow the use of Nullable Types in standard Arithmetic and Logical Expressions and will automatically propagate nullability to their result type. So if one element of an expression is nullable, that information will bubble up through the expression tree and the result will be nullable, too.
When using the Swift language, nullables need to be of the implicitly wrapped type (i.e.declared with !
) to be used directly, or they can be unwrapped inline with ?
.
Consider the following example:
var x: Int32 := 5;
var y: nullable Int32 := 10;
var z: nullable Int32;
var a := x + y + z;
Int32 x = 5;
Int32? y = 10;
Int32? z;
var a = x + y + z;
let x: Int32 = 5
let y: Int32! = 10
let z: Int32?
let a = x + y + z?;
Both y
and z
are of nullable type. That means that the subexpression x + y
will be promoted to be an Int32
as well, it's value will be 15
. Next, this value is then multiplied by z
, which is not only nullable but in fact nil
. Regardless of z
’s value, the end result will be a nullable type again, and because z
is nil
, the end result, 15 + nil
, is nil
.
So this code declares a
as a nullable Int32
(solely based on the input types of the expression) and at runtime a
will evaluate to nil
.
Determining the Type of a Nullable Expression
To determine the type of an expression, the following rules are applied:
 The nullability characteristic of the operands is ignored, determining the result base type in the usual way.
 If any one of the operands is nullable, the result type will be nullable as well.
Consider the following example:
var x: Int32 := 5;
var y: nullable Single := 5.0;
var a := x + y; // 10, a will be a nullable Single
In step one, the base types of x
and y
(Int32
and Single
) are considered to determine that the resulting expression will also be of type Single
. Then, because one of the parameters (z
) is nullable, the entire result is promoted to a nullable Single
.
Equality of Nullable Types
The above applies to all operators with only a single important exception: equality comparisons (=
and ≠
/ <>
/ !=
) always result in a notnullable Boolean to preserve the established logic of comparing referencebased values. (Other comparison operators, i.e. <
, ≤
>
and ≥
, will produce a nullable boolean as result if one of the operands is nullable, according to the above rules.)
For Example:
var x: Int32 := 5;
var y: nullable Int32 := 5;
var z: nullable Int32;
var a := x = y; // true, a will be a regular Boolean
var b := x = z; // false, b will be a regular Boolean
Determining the Result of a Nullable Expression
When evaluating expressions at runtime, the result will be nil
, if one or both of the operands is nil
; otherwise the result is the determined just as it would be for nonnullable expressions by applying the operator(s) to the respective values. It is worth noting that a single nil
in a complex or nested expression will "bubble up" and turn the entire expression nil
.
Examples (assuming the righthand operator is a nullable Int32 type):
var x: Int32 := 5;
var y: nullable Int32 := 10;
var z: nullable Int32;
var a := x + z; // = nil
var b := x + y; // = 15;
var b := (x + z) * y; // = nil;
Notes
 The above rules are specific to nullable types, but do not necessarily apply to custom class based types that implement their own operators. For example, the
+
concatenation operator on Strings will preserve the original string when appending anil
string via+
. if
,while
anduntil
statements will accept nullable booleans, and treatnil
asfalse
.
Result Tables
The following tables provide a matrix for how nil
and Boolean values
interact.
Equality
The following rules apply to the equality (=
and ≠
/<>
/!=
)
operators:
 nil = nil =>
true
 nil = nonnil =>
false
 nonnil = nil =>
false
 nonnil = nonnil => compare value
NonEquality
 nil ≠ nil =>
false
 nil ≠ nonnil =>
true
 nonnil ≠ nil =>
true
 nonnil ≠ nonnil => actual values are compared
Booleans
Truth table for the not
/ !
boolean operator
 (not
true
) =>false
 (not
false
) =>true
 (not
nil
) =>nil
Truth table for the and
/ &&
boolean operator
true
andtrue
=>true
true
andfalse
=>false
true
andnil
=>nil
false
andtrue
=>false
— via Boolean ShortCircuitfalse
andfalse
=>false
— via Boolean ShortCircuitfalse
andnil
=>false
— via Boolean ShortCircuitnil
andtrue
=>nil
nil
andfalse
=>false
nil
andnil
=>nil
Truth table for the or
/ 
boolean operator
true
ortrue
=>true
— via Boolean ShortCircuittrue
orfalse
=>true
— via [Boolean ShortCircuittrue
ornil
=>true
— via [Boolean ShortCircuitfalse
ortrue
=>true
false
orfalse
=>false
false
ornil
=>nil
nil
ortrue
=>true
nil
orfalse
=>nil
nil
ornil
=>nil
Truth table for the xor
/ ^
boolean operator
true
xortrue
=>false
true
xorfalse
=>true
true
xornil
=>nil
false
xortrue
=>true
false
xorfalse
=>false
false
xornil
=>nil
nil
xortrue
=>nil
— via Boolean ShortCircuitnil
xorfalse
=>nil
— via Boolean ShortCircuitnil
xornil
=>nil
— via Boolean ShortCircuit
Note: There is no XOR operator in SQL, which is where the nullable truth tables are based on, however, "A xor B" can be expressed as "not (A and B) and (A or B)" and the above truth table derived from that.
Truth table for the Oxygene implies
boolean operator
true
impliestrue
=>true
true
impliesfalse
=>false
true
impliesnil
=>nil
false
impliestrue
=>true
— via Boolean ShortCircuitfalse
impliesfalse
=>true
— via Boolean ShortCircuitfalse
impliesnil
=>true
— via Boolean ShortCircuitnil
impliestrue
=>nil
nil
impliesfalse
=>nil
nil
impliesnil
=>nil
Boolean ShortCircuit
Boolean ShortCircuit evaluation is possible for the following operators if the left operand has a specific value:

and
/&&
:false
=>false

or
/
:true
=>true

xor
/^
:nil
=>nil
(Note that xor
/^
does not ever shortcircuit for nonnullable expressions.)