reflex icon indicating copy to clipboard operation
reflex copied to clipboard

Cond component uses Javascript truthfulness semantics

Open jonaengs opened this issue 2 years ago β€’ 0 comments

Describe the bug In Python, empty lists are falsy, meaning they evaluate to False when coerced into a boolean value. In Javascript on the other hand, empty arrays are truthy (source). Pynecone's Cond component uses Javascript semantics, not Python's when when evaluating the Cond conditional expression.

This behavior is not immediately clear, and it is not mentioned in the documentation of the Cond component.

Examples:

def index() -> pc.Component:
    # One would expect the two list expressions to be practically equivalent, 
    # but in fact they have the opposite result.
    return pc.list(
        pc.cond([], pc.text("empty arr is truthy"), pc.text("empty arr is falsy")),
        pc.text("empty arr is truthy") if [] else pc.text("empty arr is falsy"),
    )
class State(pc.State):
    arr = []
    arr_member = ""
        
    def unsafe_compute(self):
        # Should only be called when we know arr[0] exists
        self.arr_member = self.arr[0]

def index() -> pc.Component:
    return pc.list(
        # We expect this pc.cond call to behave like 'if arr:..', hiding the button if the list is empty
        pc.cond(State.arr, pc.button("Compute", on_click=State.unsafe_compute)),
    )

If the user expects pc.cond(State.arr, ...) to behave like Python's if arr: ..., they will expect the button to only appear when len(arr) >= 1.

Expected behavior I would expect either the Cond component to follow Python's truthfulness semantics completely, or a mention in the Cond docs of the fact that the component's condition is evaluated in Javascript, and what that entails.

As far as I can tell, empty lists are the only values for which Python and Javascript's truthfulness logic diverges (except NaN -- which can't be included in JSON -- and objects where the __bool__ method can return False).

jonaengs avatar Mar 14 '23 15:03 jonaengs