Support for ?? (double question mark) as the coalesce operator has been added to DWScript.
The coalesce operator is a binary operator, which looks at its left operand, and if not “falsey”, returns it, otherwise returns its right operand.
At its simplest the syntax is:
a := b ?? c;
is inline syntax sugar for
var temp := b; if temp then a := temp else a := c;
The left operand is evaluated only once, and the right operand is evaluated only when necessary.
You can of course chain the coalesce operators:
a := b ?? c ?? d;
At the moment DWS does not support nullable types (outside Variant), so the coalesce operator behavior was based on JavaScript’s double-pipe operator, to which it will map directly in SmartPascal.
A “falsey” value corresponds to Null, Unassigned/Undefined, as well as type default values, ie. :
- boolean false
- zero (0 and 0.0)
- empty string
- nil
This leaves open the door for C#-like behavior when/if DWS gets nullable types, while extending the coalesce operator so it can be used in more cases, and especially it can be a convenient way to handle optional values with dynamic defaults. The alternative ways are to use if/then/else and function overloads, but these can get quickly out of hand when you have many optional values.
Another difference with C# is the precedence, the C# coalesce operator has low precedence, which broke many expectations and led to many bugs (and actually most of the literature about C# coalesce operator seems to be complaints about its precedence). In DWS the coalesce operator has high precedence. For instance
v := x ?? 1 + y ?? 2;
is understood as
v := (x ?? 1) + (y ?? 2);
and not as
v := x ?? (1 + y) ?? 2;
besides breaking expectations, there seems to be little point in having a low-priority coalesce operator: you will typically want to apply coalescing before using a value, rather than once everything has gone all the way to undefined or null land.
“is inline syntax sugar for”… why would you need the temp var? isn’t it just “if b then a := b else a := c” ?
P.S: ah ok, it isn’t the same. it would “execute” b two times instead of one time only.