Null coalescing operator
The null coalescing operator, typically denoted by the double question mark (??), is a binary operator in various programming languages that evaluates to its left-hand operand if that operand is not null (or, in some implementations, not nullish, meaning neither null nor undefined); otherwise, it evaluates to its right-hand operand, providing a concise mechanism for assigning default values and avoiding null reference exceptions.[1][2][3]
Introduced in C# 2.0 as part of the .NET Framework 2.0 release in November 2005, the operator works with both reference types and nullable value types, allowing expressions like string name = userName ?? "Anonymous"; to return userName if non-null or "Anonymous" as a fallback.[4][1] This feature complemented the simultaneous introduction of nullable value types (T?), enhancing null safety in code.[4] Later enhancements in C# 8.0 (2019) added the null-coalescing assignment operator (??=), which assigns the right operand to the left only if the left is null.[1]
The operator gained prominence in PHP with version 7.0 in December 2015, where it serves as syntactic sugar for the common pattern of checking isset() with a ternary operator, as in $username = $_GET['user'] ?? 'Anonymous';, returning the left value if it exists and is not [NULL](/page/Null), or the right otherwise.[5][6] PHP 7.4 (2019) extended this with the null-coalescing assignment (??=), streamlining updates to variables.[7]
In JavaScript, the nullish coalescing operator (??) was standardized in ECMAScript 2020 (ES2020) and became widely supported in browsers by mid-2020; it specifically targets null or undefined (nullish values), distinguishing it from the logical OR operator (||) by not treating other falsy values like empty strings or zero as triggers for the fallback.[2] For example, const value = maybeNull ?? defaultValue; assigns defaultValue only if maybeNull is nullish.[2] ECMAScript 2021 introduced the nullish coalescing assignment (??=), enabling assignments like foo ??= bar; to set foo to bar if foo is nullish.[8]
Similar operators appear in other languages, such as Swift's nil-coalescing operator (??) for optionals since Swift 1.0 (2014), and Rust's unwrap_or method or pattern matching for handling Option types, though not identically named. These implementations collectively address a common need for safer null handling, reducing boilerplate code and improving readability across object-oriented, functional, and scripting paradigms.[1][6][2]
Definition and Purpose
Core Concept
The null coalescing operator is a binary operator, typically represented by the symbols ??, that returns the value of its left-hand operand if that operand is not null (or an equivalent null-like value, such as undefined in JavaScript or nil in other languages); otherwise, it returns the value of its right-hand operand.[1][2] This operator provides a concise syntactic construct for handling potentially absent values in expressions, evaluating the right operand only when necessary to avoid unnecessary computations.[1]
Unlike broader conditional operators, such as the logical OR (||), the null coalescing operator specifically checks for null-like states and does not treat other falsy values—such as zero, empty strings, or false—as triggers for fallback to the right operand.[2] For example, 0 ?? "default" evaluates to 0, preserving the intended meaning of numeric or boolean values that happen to be falsy.[2] This precision ensures that the operator supports accurate null handling without unintended side effects from type coercion or falsy logic.
At its core, the null coalescing operator mitigates null pointer exceptions and related runtime errors by enabling developers to embed safe default values directly in code, reducing reliance on explicit conditional statements like if checks.[1] The name "coalescing" derives from the concept of values merging or fusing into a single non-null result, selecting the first available valid operand in a chain.[9] This foundational design promotes cleaner, more readable code while enhancing robustness against null-related failures common in object-oriented and dynamic programming paradigms.[1]
Use Cases
The null coalescing operator is commonly employed for default value assignment, where it assigns a fallback value to a variable or expression if the primary source evaluates to null, thereby streamlining code that would otherwise require explicit null checks. For instance, when processing user input that may be absent, a developer might set a variable to the input if available or to a predefined default otherwise, reducing boilerplate and enhancing readability. This pattern is particularly valuable in scenarios involving optional parameters or uninitialized variables, as seen in languages like C#, PHP, and JavaScript.[1][10][2]
Chaining multiple null coalescing operations enables layered fallback mechanisms, allowing code to select the first non-null value from a sequence of potential sources, such as a series of configuration options or nested object properties. This right-associative behavior supports concise expressions for hierarchical defaults, like retrieving a value from a primary source, then a secondary cache, and finally a hardcoded constant, without nested conditionals. Such chains promote cleaner handling of multi-level data dependencies.[1][10]
In configuration handling, the operator facilitates safe retrieval of settings from sources like environment variables, configuration files, or databases, providing built-in defaults to avoid runtime failures when values are missing or unset. For example, it can extract a database connection string from an environment variable or revert to a development default, ensuring applications remain robust across deployment environments without extensive validation logic. This approach is widely adopted in web development frameworks for its efficiency in managing optional settings.[2][10]
For API response processing, the null coalescing operator aids in safely extracting data from potentially null objects, such as parsed JSON payloads or remote service outputs, by supplying defaults for absent fields. This prevents cascading null propagation in data pipelines, for instance, when displaying user details from an API that might omit optional attributes, allowing seamless rendering of fallback content like placeholder text or empty states.[1][2]
By encapsulating null checks into a single operator, it significantly reduces the risk of null reference exceptions in expressions, enabling one-liner constructs that replace verbose if-else blocks and minimize common sources of bugs in null-prone codebases. This error reduction is especially beneficial in large-scale applications where null handling is frequent, contributing to more maintainable and less error-prone code.[1][10][2]
Syntax and Behavior
The null coalescing operator is a binary operator commonly represented by the double question mark (??), with the general syntactic form leftOperand ?? rightOperand. This structure evaluates the left operand first and returns the right operand only if the left is null, serving as a concise way to provide default values in expressions.[1][3][2]
The left operand can be of any type that may evaluate to a null or nullish state, depending on the language implementation, while the right operand supplies the fallback value. For instance, in a variable assignment, it might appear as result = nullableValue ?? defaultValue;, where the operator integrates seamlessly into larger code constructs.[1][3][2]
This operator is employed in various expression contexts, such as assignments, function returns, or embedded within conditional logic, but it cannot stand alone as a statement. Regarding operator precedence, ?? typically binds more tightly than assignment operators (like =) but less tightly than equality operators (like ==), requiring parentheses in mixed expressions for clarity.[11]
An extension in some implementations is the null-coalescing assignment operator (??=), which updates the left operand with the right operand's value only if the left is null, as in variable ??= defaultValue;. This variant streamlines code for initializing or updating variables with defaults.[12]
Evaluation Rules
The null coalescing operator evaluates its left operand first. If the left operand is not null, it is returned immediately, and the right operand is not evaluated at all—this short-circuiting behavior optimizes performance by avoiding unnecessary computations, particularly when the right operand involves expensive operations or side effects.[1][10][2]
In this context, "null" specifically refers to null-like states such as [null](/page/Null) for reference types, [undefined](/page/Undefined) in dynamic languages, or unset variables, but excludes other falsy values like false, 0, empty strings, or [NaN](/page/NaN). This distinction ensures that valid but falsy data is preserved rather than replaced by the right operand. For instance, if the left operand is the boolean false, the operator returns false without considering the right operand.[2][10][1]
The operator always returns the value of the non-null operand. If the operands are of compatible types, the result's type is typically a union or the common supertype of both, allowing flexible usage in type-safe languages. Side effects in the right operand, such as function calls or property accesses, are only triggered if the left operand is null, which can prevent errors or resource waste—for example, in an expression like getUserName() ?? "[Anonymous](/page/Anonymous)", a potentially expensive function call on the left is always evaluated, but if considering the right, it would be skipped if the left is non-null.
The null coalescing operator is right-associative, meaning expressions like a ?? b ?? c are parsed as a ?? (b ?? c), enabling chained defaults from left to right. It generally has the same or lower precedence than the logical OR (||) operator but lower than equality (==) or comparison operators, requiring parentheses in mixed expressions to avoid ambiguity—such as (x == null) ?? y to ensure correct grouping. This precedence allows integration with other operators while maintaining clarity in compound expressions.[1][15][16]
Historical Development
Origins in C#
The null coalescing operator (??) was first introduced in C# 2.0, which was released in November 2005 alongside the .NET Framework 2.0. This operator provided a binary mechanism to return the left-hand operand if it was non-null, or the right-hand operand otherwise, specifically targeting reference types and the newly introduced nullable value types. Its inclusion marked a significant step in addressing common null-handling patterns that previously required verbose conditional logic.[4][17]
Led by Anders Hejlsberg, the chief architect of C# since its inception, and his development team at Microsoft, the operator was designed to simplify the assignment of default values to nullable types and references, reducing the reliance on explicit null checks and improving code readability and safety. This motivation stemmed from the need to streamline expressions involving potential null values, a challenge amplified by the simultaneous introduction of nullable value types (e.g., int?) in C# 2.0, which allowed value types to represent undefined states. By enabling concise defaults—such as expression1 ?? expression2—the operator mitigated risks associated with null reference exceptions in everyday programming scenarios.[4][17]
The operator's initial syntax was defined as a right-associative binary operator with precedence below conditional AND (&&) and above the conditional operator (?:), applicable only to nullable or reference types without support for overloading. It was formally specified in the third edition of the ECMA-334 C# language standard, published in June 2005, which outlined its evaluation rules: the right operand is evaluated only if the left is null, and the result type is determined via implicit conversions between operands. From its debut, the operator saw rapid integration within the .NET 2.0 ecosystem, fostering safer application development.[17]
Spread to Other Languages
Following the introduction of the null coalescing operator in C# with .NET Framework 2.0 in 2005, the concept of providing a concise syntax for handling null values spread to several other programming languages, often inspired by the need for improved null safety in dynamic or object-oriented environments.
PHP adopted the null coalescing operator (??) in version 7.0, released on December 3, 2015, as syntactic sugar to replace common isset() checks combined with ternary operators, returning the left operand if it exists and is not null, otherwise the right operand. PHP 7.4, released in November 2019, introduced the null-coalescing assignment (??=).[6][18] Kotlin, which emphasized null safety from its inception, introduced the Elvis operator (?:) in its initial preview release in July 2011, functioning similarly by returning the left expression if non-null or the right as a default, though it builds on ternary-like syntax for broader null-aware operations.[19] PowerShell version 3.0, released in September 2012, incorporated null coalescing behavior through conditional logic enhancements like the -or operator for handling $null values in pipelines, aiding scripting null safety without a dedicated binary operator until PowerShell 7.0 in 2020.
Swift integrated the nil coalescing operator (??) upon its public launch with version 1.0 in September 2014, unwrapping optionals if they contain a value or providing a default, directly borrowing from C#-style null safety to streamline optional chaining in its type-safe ecosystem.[20] Rust, emphasizing ownership and safety without null pointers, provided equivalent functionality via the unwrap_or method on Option types starting with its 1.0 stable release in May 2015, returning the contained value if Some or a default if None, though as a method rather than an operator to fit its functional paradigm.[21]
More recently, JavaScript formalized the nullish coalescing operator (??) in ECMAScript 2020 (ES2020), approved at TC39 stage 4 in October 2019 and shipped in major browsers like Chrome 80 and Firefox 72 starting in early 2020, distinguishing null or undefined from falsy values like empty strings for precise defaulting.[2] This adoption reflected growing demand for null-safe expressions in web development, with the proposal originating in 2017 to address limitations of the logical OR (||) operator.[22] ECMAScript 2021 introduced the nullish coalescing assignment (??=).[8]
Evolving trends include extensions like the null-coalescing assignment operator (??=) in C# 8.0, released in September 2019, which assigns the right operand to the left only if the left is null, reducing boilerplate in mutable contexts.[1]
With Logical OR
The logical OR operator (||) evaluates to its right-hand operand when the left-hand operand is falsy, where falsy values encompass not only null but also other values such as false, 0, or an empty string "", depending on the language's type coercion rules.[2][3]
In contrast, the null coalescing operator (??) specifically checks for null (or undefined in some languages) and preserves non-null falsy values as valid results. For instance, "" ?? "default" evaluates to "", whereas "" || "default" evaluates to "default", demonstrating how || can inadvertently override intended falsy inputs.[2]
This distinction highlights a key pitfall of relying on || for null safety: it may apply unintended defaults to legitimate falsy values, such as a boolean false indicating a deliberate choice or a numeric 0 representing a valid quantity, leading to logical errors in applications where such values carry semantic meaning.[2][3]
The logical OR operator remains suitable for scenarios requiring broad truthy checks, such as simple conditional fallbacks where any falsy input warrants a replacement, but it falls short for null-specific safeguards that respect the nuances of falsy distinctions.[2]
A common example arises in configuration handling, where an absent value (null) should default to a preset, but a present empty string "" is a valid user-supplied option indicating no preference, avoiding overrides that could alter intended behavior.[2]
With Elvis and Ternary Operators
The ternary conditional operator, with the syntax condition ? trueValue : falseValue, enables concise if-then-else expressions in many programming languages, including C# and PHP.[23][3] However, when applied to simple null checks, such as determining a default value if a variable is null, it often requires explicit conditionals like value != null ? value : defaultValue, which can introduce verbosity and potential errors if the null check is overlooked.[24]
The Elvis operator, typically denoted as ?:, serves as a shorthand for the ternary operator in languages such as Groovy and PHP, where expr ?: default expands to expr ? expr : default and evaluates the left operand for truthiness rather than strict nullity.[25][3] In Groovy, for instance, it returns the left operand if it is not falsy under Groovy's truth semantics (e.g., non-null, non-empty, non-zero), otherwise the default; this reduces code duplication compared to the full ternary but may treat empty strings or zero as falsy, unlike null coalescing.[26] Similarly, in PHP, the Elvis operator checks if the left operand is truthy, potentially issuing notices for undefined variables unless guarded.[3] In contrast, Kotlin's Elvis operator ?: specifically checks for null and returns the left operand if non-null, aligning more closely with null coalescing behavior while still deriving from ternary shorthand.[19]
Key differences arise in their evaluation logic: the null coalescing operator focuses exclusively on null (or undefined in some contexts) without requiring a condition or truthiness evaluation, making it safer and more direct for default assignments.[1][6] The Elvis and ternary operators, however, support arbitrary conditions, allowing broader logic but risking null reference exceptions or unexpected falsy evaluations without additional safeguards, such as explicit null checks.[24] For example, in PHP, $username ?: 'Guest' uses Elvis for a quick truthy default, but $username ?? 'Guest' with null coalescing ignores falsy non-null values like empty strings.[3]
Where overlap exists, such as providing fallback values, the choice depends on intent: null coalescing suits pure null defaults without side effects from truthiness, while ternary or Elvis fits scenarios needing custom or complex conditions.[24] Historically, the Elvis operator draws inspiration from the C ternary operator introduced in the 1970s and appeared in modern languages like Groovy in version 1.5 (December 2007) and PHP 5.3 (June 2009), sometimes predating dedicated null coalescing operators in those ecosystems, such as PHP's ?? in version 7.0 (December 2015).[25][6]
Implementations in Programming Languages
C#
In C#, the null coalescing operator, denoted by ??, provides a concise way to return the left-hand operand if it is not null, or the right-hand operand otherwise. The right-hand operand is only evaluated if the left-hand operand evaluates to null, enabling short-circuit evaluation. This operator supports both reference types, such as strings, and nullable value types, like int?, but cannot be used with non-nullable value types. For example:
csharp
string name = null;
string displayName = name ?? "Anonymous"; // Results in "Anonymous"
string name = null;
string displayName = name ?? "Anonymous"; // Results in "Anonymous"
The result type of the expression is determined by the operands: if both are of the same type, the result is that type; if they differ, it promotes to a common type in the inheritance hierarchy, such as unwrapping a nullable value type to its underlying non-nullable type when compatible (e.g., int? and int yield int). If no common type exists, the result is object.[1]
Chaining multiple null coalescing operators, such as a ?? b ?? c, is right-associative, meaning it groups as a ?? (b ?? c), but evaluation proceeds left-to-right with short-circuiting: it checks a first, then b if needed, and finally c. This allows for fallback cascades without nested conditionals. The operator integrates seamlessly with the null-conditional operator ?. for safe navigation, providing defaults for potentially null properties or method calls, as in obj?.Property ?? defaultValue.[1]
Introduced in C# 8.0 (released in 2019), the null coalescing assignment operator ??= assigns the right-hand operand to the left-hand operand only if the left-hand is null, simplifying null checks in scenarios like initialization or updates. The left-hand must be a variable, property, or indexer, and the right-hand is not evaluated unless necessary. This form enhances brevity in loops or repeated assignments, replacing verbose if statements. For instance:
csharp
List<int>? numbers = null;
numbers ??= new List<int>(); // Assigns new list if null
numbers.Add(5);
List<int>? numbers = null;
numbers ??= new List<int>(); // Assigns new list if null
numbers.Add(5);
[1]
PHP
In PHP, the null coalescing operator serves as a concise mechanism for handling potentially null or unset values, particularly valuable in dynamic web applications where variables from user input may be absent. Introduced in PHP 7.0, it provides syntactic sugar to replace verbose expressions like isset($variable) ? $variable : $default, enabling cleaner code for default value assignments without triggering notices for undefined variables.[6] This operator is especially useful in server-side scripting for processing form data and query parameters, reducing boilerplate while maintaining robustness against incomplete inputs.[3]
The syntax of the null coalescing operator is $left ?? $right, where it evaluates to $left if that operand exists and is not null; otherwise, it returns $right.[10] Unlike the logical OR operator (||), which treats any falsy value (such as empty strings, zero, or false) as grounds for fallback, the null coalescing operator strictly checks for null or unset states, preserving non-null but falsy values like an empty string.[10] It also avoids emitting PHP notices for accessing undefined variables or array keys, making it safer for direct use with superglobals like $_GET or $_POST. For instance, $action = $_POST['action'] ?? 'default'; assigns the submitted value if present and non-null, or 'default' otherwise, without warnings even if the key is missing.[10]
Chaining of the null coalescing operator has been supported since PHP 7.0, allowing multiple fallbacks in a single expression evaluated from left to right. An example is $result = $userInput ?? $sessionValue ?? 'default';, which returns the first non-null value encountered in the chain.[10] This feature enhances readability in scenarios involving layered data sources, such as combining user input, cached data, and hardcoded defaults.
The operator integrates seamlessly with array access, a common pattern in PHP for handling web requests. For example, $id = $_GET['id'] ?? 0; safely retrieves a query parameter as an integer default, treating missing or null keys without errors.[10] In PHP 7.4, the null coalescing assignment operator ??= was added, enabling shorthand assignments like $array['key'] ??= $defaultValue;, which sets the key only if it is unset or null, equivalent to an if (!isset($array['key'])) check.[18] This maintains backward compatibility with pre-7.0 versions through traditional isset() checks, ensuring gradual adoption in legacy codebases.[18]
JavaScript
The nullish coalescing operator (??) in JavaScript, standardized in ECMAScript 2020 (ES2020), is a logical operator that returns its right-hand side operand when the left-hand side operand is either null or undefined; otherwise, it returns the left-hand side operand.[2] This operator specifically targets "nullish" values, distinguishing them from other falsy values such as 0, '', false, or NaN, which are treated as valid by ?? but would trigger fallbacks with the logical OR operator (||). For instance:
javascript
let value = 0;
console.log(value ?? 'default'); // 0 (preserves the falsy but defined value)
console.log(value || 'default'); // 'default' (treats 0 as falsy)
let value = 0;
console.log(value ?? 'default'); // 0 (preserves the falsy but defined value)
console.log(value || 'default'); // 'default' (treats 0 as falsy)
This behavior makes ?? particularly useful for providing default values without overriding intentional falsy inputs.[2]
The proposal for the nullish coalescing operator originated within the TC39 committee, the body responsible for evolving the ECMAScript standard, and advanced to stage 4 (finished) in July 2019 before inclusion in ES2020.[22] It directly addresses longstanding issues with || in default parameter assignments and conditional logic, such as user.age || 18, which incorrectly defaults a valid age of 0 to 18. The nullish coalescing operator ?? is right-associative, enabling natural chaining like a ?? b ?? c, which evaluates as a ?? (b ?? c) and returns the first non-nullish value from left to right.[27][2]
Browser support for ?? has been stable since early 2020, with full implementation in Chrome 80+, Firefox 72+, Safari 13.1+, and Edge 80+ across desktop and mobile environments.[28] For legacy support in older browsers or Node.js versions, transpilers like Babel provide plugins to transform ?? into compatible code, while libraries such as core-js offer runtime polyfills.[29]
The operator pairs effectively with the optional chaining operator (?.), also from ES2020, to handle nested property access safely with fallbacks. An example is obj?.prop ?? 'fallback', which returns 'fallback' only if obj is null/undefined or prop is nullish, avoiding runtime errors from undefined references.[30][2] This combination enhances code readability and robustness in scenarios involving optional data structures, such as API responses or user inputs.
Other Languages
In Swift, introduced with version 1.0 in 2014, the nil-coalescing operator ?? unwraps an optional value on the left if it is non-nil, otherwise returning the default value on the right; it is used alongside optional binding like if let for safe handling of potentially missing values.[31]
Rust, since its 1.0 release in 2015, provides functional equivalents to null coalescing through methods on the Option<T> enum, such as unwrap_or(default) which returns the contained value if present or the provided default otherwise, and unwrap_or_else(|| default) for lazy evaluation of the default.[21][32]
Kotlin, first released in 2011, employs the Elvis operator ?: for nullable types, which returns the left operand if non-null or the right operand as a default (which could itself be null), effectively combining null checks with expression evaluation.[33][34]
The SQL standard, as defined in ISO/IEC 9075:1992 (SQL-92), includes the COALESCE function, which accepts multiple arguments and returns the first non-null value encountered, serving as an early multi-argument form of null coalescing that influenced later language designs.
Perl introduced the defined-or operator // in version 5.10.0 (2008), which returns the left operand if defined (including false values like zero) or the right as default, distinct from logical-or by preserving definedness checks.[35] In PowerShell version 3.0 (2012), null coalescing is achieved through conditional patterns such as if ($null -ne $var) { $var } else { $default }; the dedicated null coalescing operator ?? was introduced in PowerShell 7.0 (2019).[36]
Variations appear in template and scripting environments; for instance, Apache FreeMarker uses syntax like ${var!'default'} to insert a variable or fallback string if undefined or null.[37] In Unix shells like Bash, parameter expansion such as ${var:-default} provides a similar effect for unset or empty variables, while || handles command-level fallbacks on failure but not directly for null values.