Coalesce operator for DWScript

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.

2 thoughts on “Coalesce operator for DWScript

  1. “is inline syntax sugar for”… why would you need the temp var? isn’t it just “if b then a := b else a := c” ?

  2. P.S: ah ok, it isn’t the same. it would “execute” b two times instead of one time only.

Comments are closed.