# Null-Coalescing Operator: `??` The null-coalescing operator evaluates and returns the value of the left-hand expression if it does not evaluate to `invalid`; otherwise it evaluates and returns the value of the right-hand expression. If the left-hand expression is returned, the right-hand expression is not evaluated. ## Basic usage ```brighterscript value = someVariable ?? someDefault ``` transpiles to: ```brightscript value = bslib_coalesce(someVariable, someDefault) ``` ## Scope protection Sometimes BrighterScript will need to protect against unintended performance issues. There are 2 possible ways that your null-coalescing expressions can be transpiled: ### Simple In this situation, BrighterScript has determined that both the consequent and the alternate are side-effect free and will not cause rendezvous. This means BrighterScript can use a simpler and more performant transpile target. ```brighterscript userId = createdUserId ?? -1 ``` transpiles to: ```brightscript userId = bslib_coalesce(createdUserId, -1) ``` ## Scope capturing In this situation, BrighterScript has detected that your null-coalescing expression could have have side-effects or could result in a rendezvous. BrighterScript will create an immediately-invoked-function-expression to capture all of the referenced local variables. This is in order to only execute the consequent if the condition is true, and only execute the alternate if the condition is false. The consequent is guaranteed to be evaluated exactly once, so you can be confident there will be no unintended side-effects. ```brighterscript name = userA.name ?? userB.name ``` transpiles to: ```brightscript name = (function(userA, userB) __bsConsequent = userA.name if __bsConsequent <> invalid then return __bsConsequent else return userB.name end if end function)(userA, userB) ``` ### Nested scope protection The scope protection works for multiple levels as well ```brighterscript user = getUser(userId ?? globalSettings.defaultUserId) ?? getDefaultUser() ``` transpiles to: ```brightscript user = (function(getDefaultUser, getUser, globalSettings, userId) __bsConsequent = getUser((function(globalSettings, userId) __bsConsequent = userId if __bsConsequent <> invalid then return __bsConsequent else return globalSettings.defaultUserId end if end function)(globalSettings, userId)) if __bsConsequent <> invalid then return __bsConsequent else return getDefaultUser() end if end function)(getDefaultUser, getUser, globalSettings, userId) ``` ## Library functions The following bslib library functions are called in the transpiled code ```brightscript function bslib_coalesce(consequent, alternate) if consequent <> invalid then return alternate else return consequent end if end function ```