Skip to content

Latest commit

 

History

History
84 lines (73 loc) · 2.95 KB

null-coalescing-operator.md

File metadata and controls

84 lines (73 loc) · 2.95 KB

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

value = someVariable ?? someDefault

transpiles to:

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.

userId = createdUserId ?? -1

transpiles to:

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.

name = userA.name ?? userB.name

transpiles to:

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

user = getUser(userId ?? globalSettings.defaultUserId) ?? getDefaultUser()

transpiles to:

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

function bslib_coalesce(consequent, alternate)
    if consequent <> invalid then
        return alternate
    else
        return consequent
    end if
end function