# Ternary Operator

In Phix the ternary operator, also known (if you’ll forgive the redundant tautology) as an if-and-only-if expression, has a function-call-like syntax, allowing conditional selection with short-circuit evaluation, eg:

        iff(flag?"true":"false")

which, fairly obviously, yields "true" or "false" depending on the value of flag. (printf()’s %t does exactly that)
If you prefer, `iif` is exactly equivalent to `iff`, additionally comma separators are also valid:

        iif(<condition>,<expression1>,<expression2>)

However, for me, comma separators make it look too much like a normal function call and I would automatically assume eager evaluation.
The construct is a simplified form of the if statement with a single condition and an else clause, except that it has two expressions rather than two statement blocks, and not only utilises short-circuit evaluation within the condition, but also evaluates only one of the expressions (aka lazy evaluation [see technicalia]). If the value of the condition can be determined at compile-time (possibly via constant propagation) then the compiler may only emit executable code for one of the expressions as well.
Note that some optimisations, especially pass-by-reference, can be thwarted by incorrect or excessive use of iff, for example

        s = iff(x<y?append(s,x):append(s,y))

is likely to be exponentially slower (you would still need millions of calls to notice) than the much neater and more obvious

        s = append(s,iff(x<y?x:y))

Often the result of an iff expression is best stored in a suitably named variable, to make the code easier to understand, and quite probably easier to debug, eg:

        s = append(s,iff(x<y?l-x*4:l-((x-1)*w+floor(y/w)*4))

vs:

        integer extra_space = iff(x<y?l-x*4:l-((x-1)*w+floor(y/w)*4)
        s = append(s,extra_space)

Such explicit clarifications normally incur no additional penalty whatsoever1 over the hidden unnamed temporary variable that the compiler would otherwise use anyway.
One more example (from builtins\regex.e)

        if greedy then
            code &= {SPLIT, i+3, nil}
        else
            code &= {SPLIT, nil, i+3}
        end if

has a certain clarity that, for me, gets lost in

        code &= {SPLIT, iff(greedy ? i+3 : nil ), iff(greedy ? nil : i+3 )}

I believe this (one of several possible variations) is somewhat better

        code &= iff(greedy ? {SPLIT, i+3, nil}
                           : {SPLIT, nil, i+3} )

nevertheless I still prefer the longhand/old school version - but use your own judgement, of course.

See Also: | if, append
Technicalia | A plain infix C-style syntax (`c?e1:e2` without an `iff()` container) is unfortunately not practical, since eg a = b?c:d would be treated as the statement `a = b` followed by `?c:d` (ie print variable d in namespace c). I have also seen C code where the result of a ternary operator is either one or two parameters that get passed to another routine, however the Phix version does not and cannot work that way, except perhaps via concatenation in a routine_id based call. There may also be cases such as `iff(a:b?c:d:e:f)`, where the "a:", "c:", and "e:" are (automatically) treated as namespace qualifiers, that may be much clearer with (or even fail to compile without) extra parentheses, and/or comma separators, or otherwise simply ought and deserve to be a more traditional if-construct. The Euphoria implementation of iff does not perform lazy evaluation, instead both expressions are evaluated but only one result used. Hence some uses of iff() that are perfectly valid in Phix will need to be rewritten in longhand form (if .. then .. else .. end if) in order to be compatible with Euphoria. 1(no additional penalty whatsoever) Admittedly one of the executables would be a few bytes larger (~0.001%), because somewhere, for debugging purposes, it contains the name "extra_space" instead of -1, without doubt entirely justified if it eases the development cost or maintenance burden in any way, but otherwise you would be very hard pressed indeed to devise an experiment that showed any other measurable difference.