Template:Short description Template:Redirect
In computer programming, the ternary conditional operator is a ternary operator that is part of the syntax for basic conditional expressions in several programming languages. It is commonly referred to as the conditional operator, conditional expression, ternary if, or inline if (abbreviated iif). An expression <syntaxhighlight lang="text" class="" style="" inline="1">if a then b else c</syntaxhighlight> or <syntaxhighlight lang="text" class="" style="" inline="1">a ? b : c</syntaxhighlight> evaluates to <syntaxhighlight lang="text" class="" style="" inline="1">b</syntaxhighlight> if the value of <syntaxhighlight lang="text" class="" style="" inline="1">a</syntaxhighlight> is true, and otherwise to <syntaxhighlight lang="text" class="" style="" inline="1">c</syntaxhighlight>. One can read it aloud as "if a then b otherwise c". The form <syntaxhighlight lang="text" class="" style="" inline="1">a ? b : c</syntaxhighlight> is the most common, but alternative syntaxes do exist; for example, Raku uses the syntax <syntaxhighlight lang="text" class="" style="" inline="1">a ?? b !! c</syntaxhighlight> to avoid confusion with the infix operators <syntaxhighlight lang="text" class="" style="" inline="1">?</syntaxhighlight> and <syntaxhighlight lang="text" class="" style="" inline="1">!</syntaxhighlight>, whereas in Visual Basic .NET, it instead takes the form <syntaxhighlight lang="text" class="" style="" inline="1">If(a, b, c)</syntaxhighlight>.
It originally comes from CPL, in which equivalent syntax for e1 ? e2 : e3
was e1 → e2, e3
.<ref>Template:Cite journal</ref><ref>Template:Cite book</ref>
Although many ternary operators are possible, the conditional operator is so common, and other ternary operators so rare, that the conditional operator is commonly referred to as the ternary operator.
VariationsEdit
The detailed semantics of "the" ternary operator as well as its syntax differs significantly from language to language.
A top level distinction from one language to another is whether the expressions permit side effects (as in most procedural languages) and whether the language provides short-circuit evaluation semantics, whereby only the selected expression is evaluated (most standard operators in most languages evaluate all arguments).
If the language supports expressions with side effects but does not specify short-circuit evaluation, then a further distinction exists about which expression evaluates first—if the language guarantees any specific order (bear in mind that the conditional also counts as an expression).
Furthermore, if no order is guaranteed, a distinction exists about whether the result is then classified as indeterminate (the value obtained from some order) or undefined (any value at all at the whim of the compiler in the face of side effects, or even a crash).
If the language does not permit side-effects in expressions (common in functional languages), then the order of evaluation has no value semantics—though it may yet bear on whether an infinite recursion terminates, or have other performance implications (in a functional language with match expressions, short-circuit evaluation is inherent, and natural uses for the ternary operator arise less often, so this point is of limited concern).
For these reasons, in some languages the statement form <syntaxhighlight lang="text" class="" style="" inline="1">variable = condition ? expr1 : expr2;</syntaxhighlight> can have subtly different semantics than the block conditional form <syntaxhighlight lang="text" class="" style="" inline="1">if (condition) { variable = expr1; } else { variable = expr2; }</syntaxhighlight> (in the C language—the syntax of the example given—these are in fact equivalent).
The associativity of nested ternary operators can also differ from language to language. In almost all languages, the ternary operator is right associative so that <syntaxhighlight lang="text" class="" style="" inline="1">a == 1 ? "one" : a == 2 ? "two" : "many"</syntaxhighlight> evaluates intuitively as <syntaxhighlight lang="text" class="" style="" inline="1">a == 1 ? "one" : (a == 2 ? "two" : "many")</syntaxhighlight>, but PHP in particular is notoriously left-associative,<ref>{{#invoke:citation/CS1|citation |CitationClass=web }}</ref> and evaluates as follows: <syntaxhighlight lang="text" class="" style="" inline="1">(a == 1 ? "one" : a == 2) ? "two" : "many"</syntaxhighlight>, which is rarely what any programmer expects. (The given examples assume that the ternary operator has low operator precedence, which is true in all C-family languages, and many others.)
Equivalence to mapEdit
The ternary operator can also be viewed as a binary map operation.
In R—and other languages with literal expression tuples—one can simulate the ternary operator with something like the R expression <syntaxhighlight lang="r" class="" style="" inline="1">c(expr1,expr2)[1+condition]</syntaxhighlight> (this idiom is slightly more natural in languages with 0-origin subscripts). Nested ternaries can be simulated as <syntaxhighlight lang="r" class="" style="" inline="1">c(expr1,expr2,expr3)[which.first((c(cond1,cond2,TRUE))]</syntaxhighlight> where the function <syntaxhighlight lang="text" class="" style="" inline="1">which.first</syntaxhighlight> returns the index of the first true value in the condition vector. Note that both of these map equivalents are binary operators, revealing that the ternary operator is ternary in syntax, rather than semantics. These constructions can be regarded as a weak form of currying based on data concatenation rather than function composition.
If the language provides a mechanism of futures or promises, then short-circuit evaluation can sometimes also be simulated in the context of a binary map operation.
Conditional assignmentEdit
Originally from ALGOL 60 the conditional assignment of ALGOL is:
variable := if condition then expression_1 else expression_2;
<syntaxhighlight lang="text" class="" style="" inline="1">?:</syntaxhighlight> is used as follows:
condition ? value_if_true : value_if_false
The condition is evaluated true or false as a Boolean expression. On the basis of the evaluation of the Boolean condition, the entire expression returns value_if_true if condition is true, but value_if_false otherwise. Usually the two sub-expressions value_if_true and value_if_false must have the same type, which determines the type of the whole expression. The importance of this type-checking lies in the operator's most common use—in conditional assignment statements. In this usage it appears as an expression on the right side of an assignment statement, as follows:
variable = condition ? value_if_true : value_if_false;
The ?: operator is similar to the way conditional expressions (if-then-else constructs) work in functional programming languages, like Scheme, ML, Haskell, and XQuery, since if-then-else forms an expression instead of a statement in those languages.
UsageEdit
The conditional operator's most common usage is to create a terse, simple conditional assignment. For example, if we wish to implement some C code to change a shop's normal opening hours from 9 o'clock to 12 o'clock on Sundays, we may use
<syntaxhighlight lang="c"> int opening_time = (day == SUNDAY) ? 12 : 9; </syntaxhighlight>
instead of the more verbose
<syntaxhighlight lang="c"> int opening_time;
if (day == SUNDAY)
opening_time = 12;
else
opening_time = 9;
</syntaxhighlight>
The two forms are nearly equivalent. Keep in mind that the <syntaxhighlight lang="text" class="" style="" inline="1">?:</syntaxhighlight> is an expression and if-then-else is a statement. Note that neither the true nor false portions can be omitted from the conditional operator without an error report upon parsing. This contrasts with if-then-else statements, where the else clause can be omitted.
Most of the languages emphasizing functional programming don't need such an operator as their regular conditional expression(s) is an expression in the first place e.g. the Scheme expression <syntaxhighlight lang="scheme" class="" style="" inline="1">(if (> a b) a b)</syntaxhighlight> is equivalent in semantics to the C expression <syntaxhighlight lang="c" class="" style="" inline="1">(a > b) ? a : b</syntaxhighlight>. This is also the case in many imperative languages, starting with ALGOL where it is possible to write <syntaxhighlight lang="text" class="" style="" inline="1">result := if a > b then a else b</syntaxhighlight>, or Smalltalk (<syntaxhighlight lang="smalltalk" class="" style="" inline="1">result := (a > b) ifTrue: [ a ] ifFalse: [ b ]</syntaxhighlight>) or Ruby (<syntaxhighlight lang="ruby" class="" style="" inline="1">result = if a > b then a else b end</syntaxhighlight>, although <syntaxhighlight lang="ruby" class="" style="" inline="1">result = a > b ? a : b</syntaxhighlight> works as well).
Note that some languages may evaluate both the true- and false-expressions, even though only one or the other will be assigned to the variable. This means that if the true- or false-expression contain a function call, that function may be called and executed (causing any related side-effects due to the function's execution), regardless of whether or not its result will be used. Programmers should consult their programming language specifications or test the ternary operator to determine whether or not the language will evaluate both expressions in this way. If it does, and this is not the desired behaviour, then an if-then-else statement should be used.
ActionScript 3Edit
<syntaxhighlight lang="actionscript3"> condition ? value_if_true : value_if_false </syntaxhighlight>
AdaEdit
The 2012 edition of Ada has introduced conditional expressions (using <syntaxhighlight lang="text" class="" style="" inline="1">if</syntaxhighlight> and <syntaxhighlight lang="text" class="" style="" inline="1">case</syntaxhighlight>), as part of an enlarged set of expressions including quantified expressions and expression functions. The Rationale for Ada 2012<ref>{{#invoke:citation/CS1|citation |CitationClass=web }}</ref> states motives for Ada not having had them before, as well as motives for now adding them, such as to support "contracts" (also new).
<syntaxhighlight lang="ada"> Pay_per_Hour := (if Day = Sunday
then 12.50 else 10.00);
</syntaxhighlight>
When the value of an if_expression is itself of Boolean type, then the <syntaxhighlight lang="text" class="" style="" inline="1">else</syntaxhighlight> part may be omitted, the value being True. Multiple conditions may chained using <syntaxhighlight lang="text" class="" style="" inline="1">elsif</syntaxhighlight>.
ALGOL 60Edit
ALGOL 60 introduced conditional expressions (thus ternary conditionals) to imperative programming languages.
if <boolean expression> then <expression> else <expression>
Rather than a conditional statement:
<syntaxhighlight lang="pascal"> integer opening_time;
if day = Sunday then
opening_time := 12;
else
opening_time := 9;
</syntaxhighlight>
the programmer could use the conditional expression to write more succinctly:
<syntaxhighlight lang="pascal"> integer opening_time;
opening_time := if day = Sunday then 12 else 9; </syntaxhighlight>
ALGOL 68Edit
Both ALGOL 68's choice clauses (if and the case clauses) provide the coder with a choice of either the "bold" syntax or the "brief" form.
- Single if choice clause:
if condition then statements [ else statements ] fi
- "brief" form:
( condition | statements | statements )
- "brief" form:
- Chained if choice clause:
if condition1 then statements elif condition2 then statements [ else statements ] fi
- "brief" form:
( condition1 | statements |: condition2 | statements | statements )
- "brief" form:
APLEdit
With the following syntax, both expressions are evaluated (with <syntaxhighlight lang="text" class="" style="" inline="1">value_if_false</syntaxhighlight> evaluated first, then <syntaxhighlight lang="text" class="" style="" inline="1">condition</syntaxhighlight>, then <syntaxhighlight lang="text" class="" style="" inline="1">value_if_false</syntaxhighlight>):
<syntaxhighlight lang="apl"> result ← value_if_true ⊣⍣ condition ⊢ value_if_false </syntaxhighlight>
This alternative syntax provides short-circuit evaluation:
<syntaxhighlight lang="apl"> result ← { condition : expression_if_true ⋄ expression_if_false } ⍬ </syntaxhighlight>
AWKEdit
<syntaxhighlight lang="awk"> result = condition ? value_if_true : value_if_false </syntaxhighlight>
BashEdit
A true ternary operator only exists for arithmetic expressions:
<syntaxhighlight lang="bash"> ((result = condition ? value_if_true : value_if_false)) </syntaxhighlight>
For strings there only exist workarounds, like e.g.:
<syntaxhighlight lang="bash"> result=$("$a" = "$b" && echo "value_if_true" || echo "value_if_false") </syntaxhighlight>
Where <syntaxhighlight lang="text" class="" style="" inline="1">"$a" = "$b"</syntaxhighlight> can be any condition <syntaxhighlight lang="text" class="" style="" inline="1">… </syntaxhighlight> construct can evaluate. Instead of the <syntaxhighlight lang="text" class="" style="" inline="1">… </syntaxhighlight> there can be any other bash command. When it exits with success, the first echo command is executed, otherwise the second one is executed.
CEdit
A traditional if-else construct in C is written:
<syntaxhighlight lang="c"> if (a > b) {
result = x;
} else {
result = y;
} </syntaxhighlight>
This can be rewritten as the following statement:
<syntaxhighlight lang="c"> result = a > b ? x : y; </syntaxhighlight>
As in the if-else construct only one of the expressions 'x' and 'y' is evaluated. This is significant if the evaluation of 'x' or 'y' has side effects.<ref name="ISO/IEC 9899:1999">ISO.IEC 9899:1999 (E) 6.5.15.4</ref> The behaviour is undefined if an attempt is made to use the result of the conditional operator as an lvalue.<ref name="ISO/IEC 9899:1999"/>
A GNU extension to C allows omitting the second operand, and using implicitly the first operand as the second also:
<syntaxhighlight lang="c"> a = x ? : y; </syntaxhighlight>
The expression is equivalent to
<syntaxhighlight lang="c"> a = x ? x : y; </syntaxhighlight>
except that expressions a and x are evaluated only once. The difference is significant if evaluating the expression has side effects. This shorthand form is sometimes known as the Elvis operator in other languages.
C#Edit
In C#, if condition is true, first expression is evaluated and becomes the result; if false, the second expression is evaluated and becomes the result. As with Java only one of two expressions is ever evaluated.
<syntaxhighlight lang="c"> // condition ? first_expression : second_expression;
static double sinc(double x) {
return x != 0.0 ? Math.Sin(x) / x : 1.0;
} </syntaxhighlight>
C++Edit
Unlike in C, the precedence of the <syntaxhighlight lang="text" class="" style="" inline="1">?:</syntaxhighlight> operator in C++ is the same as that of the assignment operator (<syntaxhighlight lang="text" class="" style="" inline="1">=</syntaxhighlight> or <syntaxhighlight lang="text" class="" style="" inline="1">OP=</syntaxhighlight>), and it can return an lvalue.<ref>{{#invoke:citation/CS1|citation |CitationClass=web }}</ref> This means that expressions like <syntaxhighlight lang="text" class="" style="" inline="1">q ? a : b = c</syntaxhighlight> and <syntaxhighlight lang="text" class="" style="" inline="1">(q ? a : b) = c</syntaxhighlight> are both legal and are parsed differently, the former being equivalent to <syntaxhighlight lang="text" class="" style="" inline="1">q ? a : (b = c)</syntaxhighlight>.
In C++ there are conditional assignment situations where use of the if-else statement is impossible, since this language explicitly distinguishes between initialization and assignment. In such case it is always possible to use a function call, but this can be cumbersome and inelegant. For example, to pass conditionally different values as an argument for a constructor of a field or a base class, it is impossible to use a plain if-else statement; in this case we can use a conditional assignment expression, or a function call. Bear in mind also that some types allow initialization, but do not allow assignment, or even that the assignment operator and the constructor do totally different things. This last is true for reference types, for example:
<syntaxhighlight lang="cpp" highlight="16">
- include <iostream>
- include <fstream>
- include <string>
int main(int argc, char *argv[]) {
std::string name; std::ofstream fout;
if (argc > 1 && argv[1]) { name = argv[1]; fout.open(name.c_str(), std::ios::out | std::ios::app); }
std::ostream &sout = name.empty() ? std::cout : fout;
sout << "Hello, world!\n";
return 0;
} </syntaxhighlight>
In this case, using an if-else statement in place of the <syntaxhighlight lang="text" class="" style="" inline="1">?:</syntaxhighlight> operator forces the target of the assignment to be declared outside of the branches as a pointer, which can be freely rebound to different objects.
<syntaxhighlight lang="cpp" highlight="16"> std::ostream* sout = &fout; if (name.empty()) {
sout = &std::cout;
}
- sout << "Hello, world!\n";
</syntaxhighlight>
In this simple example, the <syntaxhighlight lang="text" class="" style="" inline="1">sout</syntaxhighlight> pointer can be initialized to a default value, mitigating the risk of leaving pointers uninitialized or null. Nevertheless, there are cases when no good default exists or creating a default value is expensive. More generally speaking, keeping track of a nullable pointer increases cognitive load. Therefore, only conditional assignment to a reference through the <syntaxhighlight lang="text" class="" style="" inline="1">?:</syntaxhighlight> operator conveys the semantics of Initializing a variable from only one of two choices based on a predicate appropriately.
Furthermore, the conditional operator can yield an lvalue, i.e. a value to which another value can be assigned. Consider the following example:
<syntaxhighlight lang="cpp" line highlight="8">
- include <iostream>
int main(int argc, char *argv[]) {
int a = 0; int b = 0;
(argc > 1 ? a : b) = 1;
std::cout << "a: " << a << " b: " << b << '\n';
return 0;
} </syntaxhighlight>
In this example, if the boolean expression <syntaxhighlight lang="text" class="" style="" inline="1">argc > 1</syntaxhighlight> yields the value <syntaxhighlight lang="text" class="" style="" inline="1">true</syntaxhighlight> on line 8, the value <syntaxhighlight lang="text" class="" style="" inline="1">1</syntaxhighlight> is assigned to the variable <syntaxhighlight lang="text" class="" style="" inline="1">a</syntaxhighlight>, otherwise the value <syntaxhighlight lang="text" class="" style="" inline="1">1</syntaxhighlight> is assigned to the variable <syntaxhighlight lang="text" class="" style="" inline="1">b</syntaxhighlight>.
CFMLEdit
Example of the <syntaxhighlight lang="text" class="" style="" inline="1">?:</syntaxhighlight> operator in CFML:
<syntaxhighlight lang="cfc"> result = randRange(0,1) ? "heads" : "tails"; </syntaxhighlight>
Roughly 50% of the time the <syntaxhighlight lang="text" class="" style="" inline="1">randRange()</syntaxhighlight> expression will return 1 (true) or 0 (false); meaning result will take the value "heads" or "tails" respectively.
Lucee, Railo, and ColdFusion 11-specificEdit
Lucee, Railo, and ColdFusion 11 also implement the Elvis operator, <syntaxhighlight lang="text" class="" style="" inline="1">?:</syntaxhighlight> which will return the value of the expression if it is not-null, otherwise the specified default.
Syntax:
<syntaxhighlight lang="CFC"> result = expression ?: value_if_expression_is_null </syntaxhighlight>
Example:
<syntaxhighlight lang="CFC"> result = f() ?: "default";
// where... function f(){
if (randRange(0,1)){ // either 0 or 1 (false / true) return "value"; }
}
writeOutput(result); </syntaxhighlight>
The function <syntaxhighlight lang="text" class="" style="" inline="1">f()</syntaxhighlight> will return <syntaxhighlight lang="text" class="" style="" inline="1">value</syntaxhighlight> roughly 50% of the time, otherwise will not return anything. If <syntaxhighlight lang="text" class="" style="" inline="1">f()</syntaxhighlight> returns "value", <syntaxhighlight lang="text" class="" style="" inline="1">result</syntaxhighlight> will take that value, otherwise will take the value "default".
CoffeeScriptEdit
Example of using this operator in CoffeeScript:
<syntaxhighlight lang="coffeescript"> if 1 is 2 then "true value" else "false value" </syntaxhighlight>
Returns "false value".
Common LispEdit
Assignment using a conditional expression in Common Lisp:
<syntaxhighlight lang="lisp"> (setq result (if (> a b) x y)) </syntaxhighlight>
Alternative form:
<syntaxhighlight lang="lisp"> (if (> a b)
(setq result x) (setq result y))
</syntaxhighlight>
CrystalEdit
Example of using this operator in Crystal:
<syntaxhighlight lang="crystal"> 1 == 2 ? "true value" : "false value" </syntaxhighlight>
Returns <syntaxhighlight lang="text" class="" style="" inline="1">"false value"</syntaxhighlight>.
The Crystal compiler transforms conditional operators to <syntaxhighlight lang="text" class="" style="" inline="1">if</syntaxhighlight> expressions, so the above is semantically identical to:
<syntaxhighlight lang="crystal"> if 1 == 2
"true value"
else
"false value"
end </syntaxhighlight>
DartEdit
The Dart programming language's syntax belongs to the C family, primarily inspired by languages like Java, C# and JavaScript, which means it has inherited the traditional <syntaxhighlight lang="text" class="" style="" inline="1">?:</syntaxhighlight> syntax for its conditional expression.
Example:
<syntaxhighlight lang="Dart"> return x.isEven ? x ~/ 2 : x * 3 + 1; </syntaxhighlight>
Like other conditions in Dart, the expression before the <syntaxhighlight lang="text" class="" style="" inline="1">?</syntaxhighlight> must evaluate to a Boolean value.
The Dart syntax uses both <syntaxhighlight lang="text" class="" style="" inline="1">?</syntaxhighlight> and <syntaxhighlight lang="text" class="" style="" inline="1">:</syntaxhighlight> in various other ways, which causes ambiguities in the language grammar. An expression like:
<syntaxhighlight lang="Dart"> { x as T ? [1] : [2] } </syntaxhighlight>
could be parsed as either a "set literal" containing one of two lists or as a "map literal" {((x as T?)[1]) : [2]}
. The language always chooses the conditional expression in such situations.
Dart also has a second ternary operator, the <syntaxhighlight lang="text" class="" style="" inline="1">[]=</syntaxhighlight> operator commonly used for setting values in lists or maps, which makes the term "the ternary operator" ambiguous in a Dart context.
DelphiEdit
In Delphi the <syntaxhighlight lang="text" class="" style="" inline="1">IfThen</syntaxhighlight> function can be used to achieve the same as <syntaxhighlight lang="text" class="" style="" inline="1">?:</syntaxhighlight>. If the <syntaxhighlight lang="text" class="" style="" inline="1">System.Math</syntaxhighlight> library is used, the <syntaxhighlight lang="text" class="" style="" inline="1">IfThen</syntaxhighlight> function returns a numeric value such as an Integer, Double or Extended. If the <syntaxhighlight lang="text" class="" style="" inline="1">System.StrUtils</syntaxhighlight> library is used, this function can also return a string value.
Using <syntaxhighlight lang="text" class="" style="" inline="1">System.Math</syntaxhighlight>
<syntaxhighlight lang="Delphi"> function IfThen(AValue: Boolean; const ATrue: Integer; const AFalse: Integer): Integer; function IfThen(AValue: Boolean; const ATrue: Int64; const AFalse: Int64): Int64; function IfThen(AValue: Boolean; const ATrue: UInt64; const AFalse: UInt64): UInt64; function IfThen(AValue: Boolean; const ATrue: Single; const AFalse: Single): Single; function IfThen(AValue: Boolean; const ATrue: Double; const AFalse: Double): Double; function IfThen(AValue: Boolean; const ATrue: Extended; const AFalse: Extended): Extended; </syntaxhighlight>
Using the <syntaxhighlight lang="text" class="" style="" inline="1">System.StrUtils</syntaxhighlight> library
<syntaxhighlight lang="Delphi"> function IfThen(AValue: Boolean; const ATrue: string; AFalse: string = ): string; </syntaxhighlight>
Usage example:
<syntaxhighlight lang="Delphi"> function GetOpeningTime(Weekday: Integer): Integer; begin
{ This function will return the opening time for the given weekday: 12 for Sundays, 9 for other days } Result := IfThen((Weekday = 1) or (Weekday = 7), 12, 9);
end; </syntaxhighlight>
Unlike a true ternary operator however, both of the results are evaluated prior to performing the comparison. For example, if one of the results is a call to a function which inserts a row into a database table, that function will be called whether or not the condition to return that specific result is met.
EiffelEdit
The original Eiffel pure OO language from 1986 did not have conditional expressions. Extensions to Eiffel to integrate the style and benefits of functional in the form of agents (closely associated with functional lambdas) were proposed and implemented in 2014.
if <boolean expression> then <expression> else <expression>
<syntaxhighlight lang="eiffel"> opening_time: INTEGER
opening_time := if day = Sunday then 12 else 9 </syntaxhighlight>
F#Edit
In F# the built-in syntax for if-then-else is already an expression that always must return a value.
<syntaxhighlight lang="fsharp"> let num = if x = 10 then 42 else 24 </syntaxhighlight>
F# has a special case where you can omit the else branch if the return value is of type unit. This way you can do side-effects, without using an else branch.
<syntaxhighlight lang="fsharp"> if x = 10 then
printfn "It is 10"
</syntaxhighlight>
But even in this case, the if expression would return unit. You don't need to write the else branch, because the compiler will assume the unit type on else.
FORTHEdit
Since FORTH is a stack-oriented language, and any expression can leave a value on the stack, all <syntaxhighlight lang="text" class="" style="" inline="1">IF</syntaxhighlight>/<syntaxhighlight lang="text" class="" style="" inline="1">ELSE</syntaxhighlight>/<syntaxhighlight lang="text" class="" style="" inline="1">THEN</syntaxhighlight> sequences can generate values:
<syntaxhighlight lang="forth">
- test ( n -- n ) 1 AND IF 22 ELSE 42 THEN ;
</syntaxhighlight>
This word takes 1 parameter on the stack, and if that number is odd, leaves 22. If it's even, 42 is left on the stack.
FortranEdit
As part of the Fortran-90 Standard, the ternary operator was added to Fortran as the intrinsic function <syntaxhighlight lang="text" class="" style="" inline="1">merge</syntaxhighlight>:
<syntaxhighlight lang="fortran"> variable = merge(x,y,a>b) </syntaxhighlight>
Note that both x and y are evaluated before the results of one or the other are returned from the function. Here, x is returned if the condition holds true and y otherwise.
Fortran-2023 has added conditional expressions which evaluate one or the other of the expressions based on the conditional expression:
<syntaxhighlight lang="fortran"> variable = ( a > b ? x : y ) </syntaxhighlight>
FreeMarkerEdit
This built-in exists since FreeMarker 2.3.20.
Used like booleanExp?then(whenTrue, whenFalse)
, fills the same role as the ternary operator in C-like languages.
<syntaxhighlight lang="text"> <#assign x = 10> <#assign y = 20> <#-- Prints the maximum of x and y: --> ${(x > y)?then(x, y)} </syntaxhighlight>
GoEdit
There is no ternary if in Go, so use of the full if statement is always required.<ref name="go-ternary"/>
HaskellEdit
The built-in if-then-else syntax is inline: the expression
<syntaxhighlight lang="haskell"> if predicate then expr1 else expr2 </syntaxhighlight>
has type
<syntaxhighlight lang="haskell"> Bool -> a -> a -> a </syntaxhighlight>
The base library also provides the function <syntaxhighlight lang="text" class="" style="" inline="1">Data.Bool.bool</syntaxhighlight>:
<syntaxhighlight lang="haskell"> bool :: a -> a -> Bool -> a </syntaxhighlight>
In both cases, no special treatment is needed to ensure that only the selected expression is evaluated, since Haskell is non-strict by default. This also means an operator can be defined that, when used in combination with the <syntaxhighlight lang="text" class="" style="" inline="1">$</syntaxhighlight> operator, functions exactly like <syntaxhighlight lang="text" class="" style="" inline="1">?:</syntaxhighlight> in most languages:
<syntaxhighlight lang="haskell"> (?) :: Bool -> a -> a -> a (?) pred x y = if pred then x else y infix 1 ?
-- example (vehicle will evaluate to "airplane"): arg = 'A' vehicle = arg == 'B' ? "boat" $
arg == 'A' ? "airplane" $ arg == 'T' ? "train" $ "car"
</syntaxhighlight>
However, it is more idiomatic to use pattern guards
<syntaxhighlight lang="haskell"> -- example (vehicle will evaluate to "airplane"): arg = 'A' vehicle | arg == 'B' = "boat"
| arg == 'A' = "airplane" | arg == 'T' = "train" | otherwise = "car"
</syntaxhighlight>
JavaEdit
In Java this expression evaluates to:
<syntaxhighlight lang="java"> // If foo is selected, assign selected foo to bar. If not, assign baz to bar. Object bar = foo.isSelected() ? foo : baz; </syntaxhighlight>
Note that Java, in a manner similar to C#, only evaluates the used expression and will not evaluate the unused expression.<ref name="java">Java 7 Specification: 15.25 Conditional Operator ? : </ref>
JuliaEdit
In Julia, "Note that the spaces around <syntaxhighlight lang="text" class="" style="" inline="1">?</syntaxhighlight> and <syntaxhighlight lang="text" class="" style="" inline="1">:</syntaxhighlight> are mandatory: an expression like <syntaxhighlight lang="text" class="" style="" inline="1">a?b:c</syntaxhighlight> is not a valid ternary expression (but a newline is acceptable after both the <syntaxhighlight lang="text" class="" style="" inline="1">?</syntaxhighlight> and the <syntaxhighlight lang="text" class="" style="" inline="1">:</syntaxhighlight>)."<ref>{{#invoke:citation/CS1|citation |CitationClass=web }}</ref>
JavaScriptEdit
The conditional operator in JavaScript is similar to that of C++ and Java, except for the fact the middle expression cannot be a comma expression. Also, as in C++, but unlike in C or Perl, it will not bind tighter than an assignment to its right—<syntaxhighlight lang="text" class="" style="" inline="1">q ? a : b = c</syntaxhighlight> is equivalent to <syntaxhighlight lang="text" class="" style="" inline="1">q ? a : (b = c)</syntaxhighlight> instead of <syntaxhighlight lang="text" class="" style="" inline="1">(q ? a : b) = c</syntaxhighlight>.<ref>{{#invoke:citation/CS1|citation |CitationClass=web }}</ref>
<syntaxhighlight lang="javascript"> var timeout = settings === null ? 1000 : settings.timeout; </syntaxhighlight>
Just like C# and Java, the expression will only be evaluated if, and only if, the expression is the matching one for the condition given; the other expression will not be evaluated.
LispEdit
As the first functional programming language, Lisp naturally has conditional expressions since there are no statements and thus not conditional statements. The form is:
<syntaxhighlight lang="LISP">(if test-expression then-expression else-expression)</syntaxhighlight>
Hence:
<syntaxhighlight lang="LISP">(if (= day 'Sunday) 12 9)</syntaxhighlight>
KotlinEdit
Kotlin does not include the traditional <syntaxhighlight lang="text" class="" style="" inline="1">?:</syntaxhighlight> ternary operator, however, <syntaxhighlight lang="text" class="" style="" inline="1">if</syntaxhighlight>s can be used as expressions that can be assigned,<ref>{{#invoke:citation/CS1|citation |CitationClass=web }}</ref> achieving the same results. Note that, as the complexity of one's conditional statement grows, the programmer might consider replacing their <syntaxhighlight lang="text" class="" style="" inline="1">if</syntaxhighlight>-<syntaxhighlight lang="text" class="" style="" inline="1">else</syntaxhighlight> expression with a <syntaxhighlight lang="text" class="" style="" inline="1">when</syntaxhighlight> expression.
<syntaxhighlight lang="kotlin"> val max = if (a > b) a else b </syntaxhighlight>
LuaEdit
Lua does not have a traditional conditional operator. However, the short-circuiting behaviour of its <syntaxhighlight lang="text" class="" style="" inline="1">and</syntaxhighlight> and <syntaxhighlight lang="text" class="" style="" inline="1">or</syntaxhighlight> operators allows the emulation of this behaviour:
<syntaxhighlight lang="lua"> -- equivalent to var = cond ? a : b; var = cond and a or b </syntaxhighlight>
This will succeed unless <syntaxhighlight lang="text" class="" style="" inline="1">a</syntaxhighlight> is logically false (i.e. <syntaxhighlight lang="lua" class="" style="" inline="1">false</syntaxhighlight> or <syntaxhighlight lang="lua" class="" style="" inline="1">nil</syntaxhighlight>); in this case, the expression will always result in <syntaxhighlight lang="text" class="" style="" inline="1">b</syntaxhighlight>. This can result in some surprising behaviour if ignored.
There are also other variants that can be used, but they're generally more verbose:
<syntaxhighlight lang="lua"> -- parentheses around the table literal are required var = (
{ [true] = a, [false] = b }
)[not not cond] </syntaxhighlight>
Luau, a dialect of Lua, has ternary expressions that look like if statements, but unlike them, they have no <syntaxhighlight lang="lua" class="" style="" inline="1">end</syntaxhighlight> keyword, and the <syntaxhighlight lang="lua" class="" style="" inline="1">else</syntaxhighlight> clause is required. One may optionally add <syntaxhighlight lang="lua" class="" style="" inline="1">elseif</syntaxhighlight> clauses. It's designed to replace the <syntaxhighlight lang="lua" class="" style="" inline="1">cond and a or b</syntaxhighlight> idiom and is expected to work properly in all cases.<ref>{{#invoke:citation/CS1|citation |CitationClass=web }}</ref>
<syntaxhighlight lang="lua"> -- in Luau var = if cond then a else b
-- with elseif clause sign = if var < 0 then -1 elseif var == 0 then 0 else 1 </syntaxhighlight>
Objective-CEdit
condition ? value_if_true : value_if_false
<syntaxhighlight lang="objective-c"> int min = (1 < 2) ? 1 : 2; </syntaxhighlight>
This will set the variable <syntaxhighlight lang="text" class="" style="" inline="1">min</syntaxhighlight> to <syntaxhighlight lang="text" class="" style="" inline="1">1</syntaxhighlight> because the condition <syntaxhighlight lang="text" class="" style="" inline="1">(1 < 2)</syntaxhighlight> is <syntaxhighlight lang="text" class="" style="" inline="1">true</syntaxhighlight>.
PascalEdit
Pascal was both a simplification and extension of ALGOL 60 (mainly for handling user-defined types). One simplification was to remove the conditional expression since the same could be achieved with the less succinct conditional statement form.
PerlEdit
A traditional if-else construct in Perl is written:
<syntaxhighlight lang="perl"> if ($a > $b) {
$result = $x;
} else {
$result = $y;
} </syntaxhighlight>
Rewritten to use the conditional operator:
<syntaxhighlight lang="perl"> $result = $a > $b ? $x : $y; </syntaxhighlight>
The precedence of the conditional operator in Perl is the same as in C, not as in C++. This is conveniently of higher precedence than a comma operator but lower than the precedence of most operators used in expressions within the ternary operator, so the use of parentheses is rarely required.<ref name="perl5op">Template:Cite book</ref>
Its associativity matches that of C and C++, not that of PHP. Unlike C but like C++, Perl allows the use of the conditional expression as an L-value;<ref name="perldoc_perlop">{{#invoke:citation/CS1|citation |CitationClass=web }}</ref> for example:
<syntaxhighlight lang="perl"> $a > $b ? $x : $y = $result; </syntaxhighlight>
will assign <syntaxhighlight lang="text" class="" style="" inline="1">$result</syntaxhighlight> to either <syntaxhighlight lang="text" class="" style="" inline="1">$x</syntaxhighlight> or <syntaxhighlight lang="text" class="" style="" inline="1">$y</syntaxhighlight> depending on the logical expression's boolean result.
The respective precedence rules and associativities of the operators used guarantee that the version absent any parentheses is equivalent to this explicitly parenthesized version:
<syntaxhighlight lang="perl"> (($a > $b) ? $x : $y) = $result; </syntaxhighlight>
This is equivalent to the if-else version:
<syntaxhighlight lang="perl"> if ($a > $b) {
$x = $result;
} else {
$y = $result;
} </syntaxhighlight>
PHPEdit
A simple PHP implementation is this:
<syntaxhighlight lang="php"> $abs = $value >= 0 ? $value : -$value; </syntaxhighlight>
Unlike most other programming languages, the conditional operator in PHP is left associative rather than right associative. Thus, given a value of T for arg, the PHP code in the following example would yield the value horse instead of train as one might expect:<ref>{{#invoke:citation/CS1|citation |CitationClass=web }}</ref>
<syntaxhighlight lang="php"> <?php $arg = "T"; $vehicle = ( ( $arg == 'B' ) ? 'bus' :
( $arg == 'A' ) ? 'airplane' : ( $arg == 'T' ) ? 'train' : ( $arg == 'C' ) ? 'car' : ( $arg == 'H' ) ? 'horse' : 'feet' );
echo $vehicle; </syntaxhighlight>
The reason is that nesting two conditional operators produces an oversized condition with the last two options as its branches: <syntaxhighlight lang="text" class="" style="" inline="1">c1 ? o1 : c2 ? o2 : o3</syntaxhighlight> is really <syntaxhighlight lang="text" class="" style="" inline="1">((c1 ? o1 : c2) ? o2 : o3)</syntaxhighlight>. This is acknowledged<ref>{{#invoke:citation/CS1|citation |CitationClass=web }}</ref> and will probably not change.<ref>{{#invoke:citation/CS1|citation |CitationClass=web }}</ref> To avoid this, nested parenthesis are needed, as in this example:
<syntaxhighlight lang="php"> <?php $arg = "T"; $vehicle = $arg == "B" ? "bus" :
($arg == "A" ? "airplane" : ($arg == "T" ? "train" : ($arg == "C" ? "car" : ($arg == "H" ? "horse" : "feet"))));
echo $vehicle; </syntaxhighlight>
This will produce the result of train being printed to the output, analogous to a right associative conditional operator.
PowershellEdit
In versions before Powershell 7 ternary operators are not supported <ref>{{#invoke:citation/CS1|citation |CitationClass=web }}</ref> however conditional syntax does support single line assignment:
<syntaxhighlight lang="powershell"> $result = if $a -eq $b {"was true" } else {"was false"} </syntaxhighlight>
In Powershell 7+ traditional ternary operators are supported and follow the C# syntax:<ref>{{#invoke:citation/CS1|citation |CitationClass=web }}</ref> <syntaxhighlight lang="powershell"> $result = $a -eq $b ? "was true" : "was false" </syntaxhighlight>
PythonEdit
Though it had been delayed for several years by disagreements over syntax, an operator for a conditional expression in Python was approved as Python Enhancement Proposal 308 and was added to the 2.5 release in September 2006. Python's conditional operator differs from the common <syntaxhighlight lang="text" class="" style="" inline="1">?:</syntaxhighlight> operator in the order of its operands. The general form is:<ref>{{#invoke:citation/CS1|citation |CitationClass=web }}</ref>
<syntaxhighlight lang="python"> result = x if a > b else y </syntaxhighlight>
This form invites considering <syntaxhighlight lang="text" class="" style="" inline="1">x</syntaxhighlight> as the normal value and <syntaxhighlight lang="text" class="" style="" inline="1">y</syntaxhighlight> as an exceptional case.
Prior to Python 2.5 there were a number of ways to approximate a conditional operator (for example by indexing into a two element array), all of which have drawbacks as compared to the built-in operator.
REdit
The traditional if-else construct in R (which is an implementation of S) is:
<syntaxhighlight lang="r"> if (a < b) {
x <- "true"
} else {
x <- "false"
} </syntaxhighlight>
If there is only one statement in each block, braces can be omitted, like in C:
<syntaxhighlight lang="r"> if (a < b)
x <- "true"
else
x <- "false"
</syntaxhighlight>
The code above can be written in the following non-standard condensed way:
<syntaxhighlight lang="r"> x <- if (a < b) "true" else "false" </syntaxhighlight>
There exists also the function <syntaxhighlight lang="text" class="" style="" inline="1">ifelse</syntaxhighlight> that allows rewriting the expression above as:
<syntaxhighlight lang="r"> x <- ifelse(a < b, "true", "false") </syntaxhighlight>
The <syntaxhighlight lang="text" class="" style="" inline="1">ifelse</syntaxhighlight> function is automatically vectorized. For instance:
<syntaxhighlight lang="rconsole"> > ifelse(c (0, 2) < 1, "true", "false") [1] "true" "false" </syntaxhighlight>
RakuEdit
Raku uses a doubled <syntaxhighlight lang="text" class="" style="" inline="1">??</syntaxhighlight> symbol instead of single <syntaxhighlight lang="text" class="" style="" inline="1">?</syntaxhighlight> and a doubled <syntaxhighlight lang="text" class="" style="" inline="1">!!</syntaxhighlight> symbol instead of <syntaxhighlight lang="text" class="" style="" inline="1">:</syntaxhighlight><ref name="perl6op">{{#invoke:citation/CS1|citation |CitationClass=web }}</ref>
<syntaxhighlight lang="Perl"> $result = $a > $b ?? $x !! $y; </syntaxhighlight>
RubyEdit
Example of using this operator in Ruby:
<syntaxhighlight lang="ruby"> 1 == 2 ? "true value" : "false value" </syntaxhighlight>
Returns "false value".
A traditional if-else construct in Ruby is written:<ref name="pickaxe">Programming Ruby: Conditional Execution</ref>
<syntaxhighlight lang="ruby"> if a > b
result = x
else
result = y
end </syntaxhighlight>
This could also be written as:
<syntaxhighlight lang="ruby"> result = if a > b
x
else
y
end </syntaxhighlight>
These can be rewritten as the following statement:
<syntaxhighlight lang="ruby"> result = a > b ? x : y </syntaxhighlight>
RustEdit
Being an expression-oriented programming language, Rust's existing if expr1 else expr2
syntax can behave as the traditional <syntaxhighlight lang="text" class="" style="" inline="1">?:</syntaxhighlight> ternary operator does. Earlier versions of the language did have the <syntaxhighlight lang="text" class="" style="" inline="1">?:</syntaxhighlight> operator but it was removed<ref>{{#invoke:citation/CS1|citation
|CitationClass=web
}}</ref> due to duplication with <syntaxhighlight lang="text" class="" style="" inline="1">if</syntaxhighlight>.<ref>{{#invoke:citation/CS1|citation
|CitationClass=web
}}</ref>
Note the lack of semi-colons in the code below compared to a more declarative <syntaxhighlight lang="text" class="" style="" inline="1">if</syntaxhighlight>...<syntaxhighlight lang="text" class="" style="" inline="1">else</syntaxhighlight> block, and the semi-colon at the end of the assignment to <syntaxhighlight lang="text" class="" style="" inline="1">y</syntaxhighlight>.
<syntaxhighlight lang="rust"> let x = 5;
let y = if x == 5 {
10
} else {
15
}; </syntaxhighlight>
This could also be written as:
<syntaxhighlight lang="rust"> let y = if x == 5 { 10 } else { 15 }; </syntaxhighlight>
Note that curly braces are mandatory in Rust conditional expressions.
You could also use a <syntaxhighlight lang="text" class="" style="" inline="1">match</syntaxhighlight> expression:
<syntaxhighlight lang="rust"> let y = match x {
5 => 10, _ => 15,
}; </syntaxhighlight>
SchemeEdit
Same as in Common Lisp. Every expression has a value. Thus the builtin <syntaxhighlight lang="text" class="" style="" inline="1">if</syntaxhighlight> can be used:
<syntaxhighlight lang="scheme"> (let* ((x 5)
(y (if (= x 5) 10 15))) ...)
</syntaxhighlight>
SmalltalkEdit
Every expression (message send) has a value. Thus <syntaxhighlight lang="text" class="" style="" inline="1">ifTrue:ifFalse:</syntaxhighlight> can be used:
<syntaxhighlight lang="scheme"> |x y|
x := 5. y := (x == 5) ifTrue:[10] ifFalse:[15]. </syntaxhighlight>
SQLEdit
The SQL <syntaxhighlight lang="text" class="" style="" inline="1">CASE</syntaxhighlight> expression is a generalization of the ternary operator. Instead of one conditional and two results, n conditionals and n+1 results can be specified.
With one conditional it is equivalent (although more verbose) to the ternary operator:
<syntaxhighlight lang="sql"> SELECT (CASE WHEN a > b THEN x ELSE y END) AS CONDITIONAL_EXAMPLE
FROM tab;
</syntaxhighlight>
This can be expanded to several conditionals:
<syntaxhighlight lang="sql"> SELECT (CASE WHEN a > b THEN x WHEN a < b THEN y ELSE z END) AS CONDITIONAL_EXAMPLE
FROM tab;
</syntaxhighlight>
MySQLEdit
In addition to the standard <syntaxhighlight lang="text" class="" style="" inline="1">CASE</syntaxhighlight> expression, MySQL provides an <syntaxhighlight lang="text" class="" style="" inline="1">IF</syntaxhighlight> function as an extension:
<syntaxhighlight lang="MySQL"> IF(cond, a, b); </syntaxhighlight>
SQL ServerEdit
In addition to the standard <syntaxhighlight lang="text" class="" style="" inline="1">CASE</syntaxhighlight> expression, SQL Server (from 2012) provides an <syntaxhighlight lang="text" class="" style="" inline="1">IIF</syntaxhighlight> function:
<syntaxhighlight lang="T-SQL"> IIF(condition, true_value, false_value) </syntaxhighlight>
Oracle SQLEdit
In addition to the standard <syntaxhighlight lang="text" class="" style="" inline="1">CASE</syntaxhighlight> expression, Oracle has a variadic functional counterpart which operates similarly to a switch statement and can be used to emulate the conditional operator when testing for equality.
<syntaxhighlight lang="sql"> -- General syntax takes case-result pairs, comparing against an expression, followed by a fall-back result: DECODE(expression, case1, result1,
... caseN, resultN, resultElse)
-- We can emulate the conditional operator by just selecting one case: DECODE(expression, condition, true, false) </syntaxhighlight>
The <syntaxhighlight lang="text" class="" style="" inline="1">DECODE</syntaxhighlight> function is, today, deprecated in favour of the standard <syntaxhighlight lang="text" class="" style="" inline="1">CASE</syntaxhighlight> expression. This can be used in both Oracle SQL queries as well as PL/SQL blocks, whereas <syntaxhighlight lang="text" class="" style="" inline="1">decode</syntaxhighlight> can only be used in the former.
SwiftEdit
The ternary conditional operator of Swift is written in the usual way of the C tradition, and is used within expressions.
<syntaxhighlight lang="swift"> let result = a > b ? a : b </syntaxhighlight>
TclEdit
In Tcl, this operator is available in expr
expressions only:
<syntaxhighlight lang="tcl"> set x 5 set y [expr {$x == 5 ? 10 : 15}] </syntaxhighlight>
Outside of expr
, if
can be used for a similar purpose, as it also returns a value:
<syntaxhighlight lang="tcl">
package require math
set x 5 set y [if {$x == 5} {
::math::random $x
} else {
::math::fibonacci $x
}] </syntaxhighlight>
TestStandEdit
In a National Instruments TestStand expression, if condition is true, the first expression is evaluated and becomes the output of the conditional operation; if false, the second expression is evaluated and becomes the result. Only one of two expressions is ever evaluated.
<syntaxhighlight lang="c"> condition ? first_expression : second_expression </syntaxhighlight>
For example:
<syntaxhighlight lang="c"> RunState.Root.Parameters.TestSocket.Index == 3 ? Locals.UUTIndex = 3 : Locals.UUTIndex = 0 </syntaxhighlight>
Sets the <syntaxhighlight lang="text" class="" style="" inline="1">UUTIndex</syntaxhighlight> local variable to 3 if <syntaxhighlight lang="text" class="" style="" inline="1">TestSocket.Index</syntaxhighlight> is 3, otherwise it sets <syntaxhighlight lang="text" class="" style="" inline="1">UUTIndex</syntaxhighlight> to 0.
Similar to other languages, first_expression and second_expression do not need to be autonomous expressions, allowing the operator to be used for variable assignment:
<syntaxhighlight lang="c"> Locals.UUTIndex = ( RunState.Root.Parameters.TestSocket.Index == 3 ? 3 : 0 ) </syntaxhighlight>
V (Vlang)Edit
V uses if expressions instead of a ternary conditional operator:<ref>{{#invoke:citation/CS1|citation |CitationClass=web }}</ref> <syntaxhighlight lang="c"> num := 777 var := if num % 2 == 0 { "even" } else { "odd" } println(var) </syntaxhighlight>
VerilogEdit
Verilog is technically a hardware description language, not a programming language though the semantics of both are very similar. It uses the <syntaxhighlight lang="text" class="" style="" inline="1">?:</syntaxhighlight> syntax for the ternary operator.
<syntaxhighlight lang="verilog"> // using blocking assignment wire out; assign out = sel ? a : b; </syntaxhighlight>
This is equivalent to the more verbose Verilog code:
<syntaxhighlight lang="verilog"> // using blocking assignment wire out; if (sel === 1) // sel is 1, not 0, x or z
assign out = a;
else if (sel === 0) // sel is 0, x or z (1 checked above)
assign out = b;
else // sel is x or z (0 and 1 checked above)
assign out = [comment]; // a and b are compared bit by bit, and return for each bit // an x if bits are different, and the bit value if the same
</syntaxhighlight>
Visual BasicEdit
Visual Basic doesn't use <syntaxhighlight lang="text" class="" style="" inline="1">?:</syntaxhighlight> per se, but has a very similar implementation of this shorthand <syntaxhighlight lang="text" class="" style="" inline="1">if...else</syntaxhighlight> statement. Using the first example provided in this article, it can do:
<syntaxhighlight lang="vbnet"> ' variable = IIf(condition, value_if_true, value_if_false) Dim opening_time As Integer = IIf((day = SUNDAY), 12, 9) </syntaxhighlight>
In the above example, <syntaxhighlight lang="text" class="" style="" inline="1">IIf</syntaxhighlight> is a ternary function, but not a ternary operator. As a function, the values of all three portions are evaluated before the function call occurs. This imposed limitations, and in Visual Basic .Net 9.0, released with Visual Studio 2008, an actual conditional operator was introduced, using the <syntaxhighlight lang="text" class="" style="" inline="1">If</syntaxhighlight> keyword instead of <syntaxhighlight lang="text" class="" style="" inline="1">IIf</syntaxhighlight>. This allows the following example code to work:
<syntaxhighlight lang="vbnet"> Dim name As String = If(person Is Nothing, "", person.Name) </syntaxhighlight>
Using <syntaxhighlight lang="text" class="" style="" inline="1">IIf</syntaxhighlight>, <syntaxhighlight lang="text" class="" style="" inline="1">person.Name</syntaxhighlight> would be evaluated even if person is <syntaxhighlight lang="text" class="" style="" inline="1">null</syntaxhighlight> (Nothing), causing an exception. With a true short-circuiting conditional operator, <syntaxhighlight lang="text" class="" style="" inline="1">person.Name</syntaxhighlight> is not evaluated unless person is not <syntaxhighlight lang="text" class="" style="" inline="1">null</syntaxhighlight>.
Visual Basic Version 9 has added the operator <syntaxhighlight lang="text" class="" style="" inline="1">If()</syntaxhighlight> in addition to the existing <syntaxhighlight lang="text" class="" style="" inline="1">IIf()</syntaxhighlight> function that existed previously. As a true operator, it does not have the side effects and potential inefficiencies of the <syntaxhighlight lang="text" class="" style="" inline="1">IIf()</syntaxhighlight> function.
The syntaxes of the tokens are similar: <syntaxhighlight lang="text" class="" style="" inline="1">If([condition], op1, op2)</syntaxhighlight> vs <syntaxhighlight lang="text" class="" style="" inline="1">IIf(condition, op1, op2)</syntaxhighlight>. As mentioned above, the function call has significant disadvantages, because the sub-expressions must all be evaluated, according to Visual Basic's evaluation strategy for function calls and the result will always be of type variant (VB) or object (VB.NET). The <syntaxhighlight lang="text" class="" style="" inline="1">If()</syntaxhighlight>operator however does not suffer from these problems as it supports conditional evaluation and determines the type of the expression based on the types of its operands.
ZigEdit
Zig uses if-else expressions instead of a ternary conditional operator:<ref>{{#invoke:citation/CS1|citation |CitationClass=web }}</ref> <syntaxhighlight lang="zig"> const result = if (a != b) 47 else 3089; </syntaxhighlight>
Result typeEdit
Clearly the type of the result of the <syntaxhighlight lang="text" class="" style="" inline="1">?:</syntaxhighlight> operator must be in some sense the type unification of the types of its second and third operands. In C this is accomplished for numeric types by arithmetic promotion; since C does not have a type hierarchy for pointer types, pointer operands may only be used if they are of the same type (ignoring type qualifiers) or one is void or NULL. It is undefined behaviour to mix pointer and integral or incompatible pointer types; thus
<syntaxhighlight lang="c"> number = spell_out_numbers ? "forty-two" : 42; </syntaxhighlight>
will result in a compile-time error in most compilers.
?: in style guidelinesEdit
Conditional operators are widely used and can be useful in certain circumstances to avoid the use of an <syntaxhighlight lang="text" class="" style="" inline="1">if</syntaxhighlight> statement, either because the extra verbiage would be too lengthy or because the syntactic context does not permit a statement. For example:
#define MAX(a, b) (((a)>(b)) ? (a) : (b))
or
<syntaxhighlight lang="cpp">
for (i = 0; i < MAX_PATTERNS; i++) c_patterns[i].ShowWindow(m_data.fOn[i] ? SW_SHOW : SW_HIDE);
</syntaxhighlight>
(The latter example uses the Microsoft Foundation Classes Framework for Win32.)
InitializationEdit
An important use of the conditional operator is in allowing a single initialization statement, rather than multiple initialization statements. In many cases this also allows single assignment and for an identifier to be a constant.
The simplest benefit is avoiding duplicating the variable name, as in Python:
<syntaxhighlight lang="python"> x = 'foo' if b else 'bar' </syntaxhighlight>
instead of:
<syntaxhighlight lang="python"> if b:
x = 'foo'
else:
x = 'bar'
</syntaxhighlight>
More importantly, in languages with block scope, such as C++, the blocks of an if/else statement create new scopes, and thus variables must be declared before the if/else statement, as:
<syntaxhighlight lang="cpp"> std::string s; if (b)
s = "foo";
else
s = "bar";
</syntaxhighlight>
Use of the conditional operator simplifies this:
<syntaxhighlight lang="cpp"> std::string s = b ? "foo" : "bar"; </syntaxhighlight>
Furthermore, since initialization is now part of the declaration, rather than a separate statement, the identifier can be a constant (formally, of <syntaxhighlight lang="text" class="" style="" inline="1">const</syntaxhighlight> type):
<syntaxhighlight lang="cpp"> const std::string s = b ? "foo" : "bar"; </syntaxhighlight>
Case selectorsEdit
When properly formatted, the conditional operator can be used to write simple and coherent case selectors. For example:
<syntaxhighlight lang="c"> vehicle = arg == 'B' ? bus :
arg == 'A' ? airplane : arg == 'T' ? train : arg == 'C' ? car : arg == 'H' ? horse : feet;
</syntaxhighlight>
Appropriate use of the conditional operator in a variable assignment context reduces the probability of a bug from a faulty assignment as the assigned variable is stated just once as opposed to multiple times.
Programming languages without the conditional operatorEdit
The following are examples of notable general-purpose programming languages that don't provide a conditional operator:
- CoffeeScript
- Go programming language<ref name="go-ternary">{{#invoke:citation/CS1|citation
|CitationClass=web }}</ref> (although provided by 3rd-party libraries<ref>{{#invoke:citation/CS1|citation |CitationClass=web }}</ref>)
- MATLAB
- Pascal although Object Pascal / Delphi do have a function <syntaxhighlight lang="text" class="" style="" inline="1">IfThen</syntaxhighlight> to do the same (with caveats)
- Rust The <syntaxhighlight lang="text" class="" style="" inline="1">if..else</syntaxhighlight> construct is an expression and can be used to get the same functionality.<ref>{{#invoke:citation/CS1|citation
|CitationClass=web }}</ref>
- Scala
- Template:Ill
- PowerShell (in old versions) an elegant workaround is to use
(<value for true>,<value for false>)[!(<condition>)]
<ref>{{#invoke:citation/CS1|citation
|CitationClass=web }}</ref>
See alsoEdit
- Conditioned disjunction, equivalent ternary logical connective.
- Elvis operator, <syntaxhighlight lang="text" class="" style="" inline="1">?:</syntaxhighlight>, or sometimes <syntaxhighlight lang="text" class="" style="" inline="1">?.</syntaxhighlight>, as a shorthand binary operator
- IIf, inline if function
- McCarthy Formalism
- Multiplexer
- Null coalescing operator, <syntaxhighlight lang="text" class="" style="" inline="1">??</syntaxhighlight> operator
- Safe navigation operator, often
?.