but there are two binary operators: "?" and ":"
Let's consider an example:
a = 4; // `a` has type `int` and value 4
b = a < 0 ? -1 : 1; // `b` has type `int` and value 1Actually, the expression a ? b : c in this example consists of two nested binary operators. They can be written separately as well:
x = a < 0 ? -1;
b = x : 1;The type of variable x will be optional<int>, or in Argentum syntax: ?int. Let's delve into the semantics of these two lines more closely:
x = a < 0 ? -1; // `x` will be -1 if `a` < 0 or "nothing" for all other cases.
b = x : 1; // assign the value of `x` to `b`, but if it's "nothing", then assign 1.It can be said that the operator ? produces an optional, and : consumes it. When used together, they function like the old good ternary operator:
b = (a < 0 ? -1) : 1;When the result of an expression is not needed, the operator ? works like an if:
a < 0 ? log("it's negative");And the pair of operators ?: works like an if...else:
a & 1 == 0
? log("it's even")
: log("it's odd");So, Argentum split the ternary operator into two binary ones. What did this achieve?
- Short conditional expressions without an 'else' part that return values. The language became more orthogonal.
- Nothing got complicated—no new syntactic constructs were added.
- Two constructors for optional values appeared:
- Instead of (C++)
optional<decltype(x)> maybeX{x}
we can writemaybeX = true ? x - Instead of
optional<decltype(x)> maybeX{nullopt}
we can writemaybeX = false ? x
- Instead of (C++)
- Unpacking with default value also became simpler:
Instead ofauto a = maybeX ? *maybeX : 42
we can writea = maybeX : 42 - In case of data absence, it's not necessary to use a default value; we can call a handler for the problematic situation or trigger panic:
x : terminate() - It's often, when returning an optional result from a function,
we write:return condition ? result : nullopt
In Argentum, this will be:condition ? result - We can not only combine the
?and:operators but also combine the:operators among themselves. For example:user = currentUser : getUserFromProfile() : getDefaultUser() : panic("no user");This short expression attempts to get a user object from multiple places and triggers application exit if nothing succeeds.
