luaconditional-operatorboolean-logicboolean-operations

How does the `(…) and (…) or (…)` idiom mimic a ternary operator in Lua?


This statement mimics a ternary operator in the Lua programing language:

local result = condition and true_value or false_value

But how does it work? Why does it give true_value if the condition is true?


Solution

  • how does it work? Why does it give true_value if the condition is true?

    Lua has a few concepts that are necessary to understand to give a complete answer here.

    Logical operators

    It's first important to understand how and and or work - which may seem obvious but for completeness, from the official docs:

    The operator and returns its first argument if it is false; otherwise, it returns its second argument

    And also:

    The operator or returns its first argument if it is not false; otherwise, it returns its second argument

    Operator precedence

    Also from the docs, operator precedence:

    and has a higher precedence than or

    That means that this code from the question:

    local result = condition and true_value or false_value
    

    Can be read as:

    local result = (condition and true_value) or false_value
    

    These two code examples are functionally identical.

    Booleans and truthiness

    If you're new to lua, booleans can be surprising.

    false and nil as false and anything else as true

    Why do I point this out? because the concept of truthiness is quite different in lua, all of these evaluate to true:

    Scenarios

    Let's look at a few scenarios to drill things home.

    condition is True

    > condition=true
    > true_value="true value"
    > false_value="false value"
    
    > result = (condition and true_value) or false_value
    > result
    true value
    

    In this case:

    condition is False

    > condition=false
    > true_value="true value"
    > false_value="false value"
    
    > result = (condition and true_value) or false_value
    > result
    false value
    

    In this case:

    Gotcha scenarios

    There are many scenarios that can trip folks up unfamiliar with lua.

    condition is truthy

    If condition is not a boolean, it's going to be cast to a boolean to evaluate the and. so e.g.:

    > condition=0
    > true_value="true value"
    > false_value="false value"
    
    > result = (condition and true_value) or false_value
    > result
    true value
    

    In this case:

    In many other languages you may expect to get false_value here, but not with Lua.

    true_value is false

    If true_value is false or nil this is the typical scenario that trips folks up:

    > condition=true
    > true_value=false
    > false_value="false value"
    
    > result = (condition and true_value) or false_value
    > result
    false value
    

    In this case:

    This can be particularly confusing if there are functions in use, here's a fabricated example:

    > user_provided_valid_input=true
    > result = (user_provided_valid_input and doThing()) or tell_user_their_input_was_bad()
    

    If doThing returns nil (e.g. doesn't have a return value) or false (e.g. encounters an error) then tell_user_their_input_was_bad() will be called.

    Summary

    The code in the question is equivalent to:

    intermediate = condition and true_value
    result       = intermediate or false_value