Friday, 30 August 2019

Error Handling via Failure Values with Tridash 0.5

Version 0.5 of the Tridash programming language has released. If you want to know more about why I wrote Tridash, check out This new version brings a significant improvement in the semantics of the language.


Ad hoc null values have been replaced with special failure types. Failures values automatically trigger a failure of the current operation, thus creating a new failure value, when evaluated. These are used to represent the absence of values, which were previously represented by null's, failure of an operation or special classes of values, such as the empty list.

int(input) -> x
The node input stores the value retrieved from an input text field. An integer value is parsed, using the int function, from the value of input (a string), and stored in the node x.

Previously, and in some other languages, you would have to check whether an integer value was successfully parsed from input, and only then make use of the value of x. With failures, if the string value does not contain a valid integer, x is set to a failure value. All nodes which evaluate x will automatically evaluate to failures, thus terminating whatever operation was being performed with the value of x.
x + y -> sum
If an integer was successfully parsed from input, x evaluates to the integer value and the node sum is set to the sum of x and y. If however input does not contain a valid integer, x is set to a failure and the sum of x and y is not computed, instead x + y evaluates to a failure.

This allows the value of x to be treated as though it is guaranteed that an integer is always parsed successfully from input, since if an integer cannot be parsed from input, any usage of x will simply trigger a new failure rather than resulting in undefined behaviour or incorrect results being computed.

This propagation of failures removes the need for littering the main application logic with error handling/checking code.

The error handling code can be separated from the application logic, since Tridash allows any node to be bound to any other node, with the state of each node automatically updated when the state of its dependency nodes changes. As a result, indicating to the user that the value entered is not a valid integer can be as simple as adding the following line:
if(fails?(x), "Invalid integer entered!", "") -> error
The node error evaluates to the string "Invalid integer entered!" when x evaluates to a failure, thus an integer could not be parsed from input. Otherwise, when an integer is successfully parsed from input, error evaluates to the empty string.

This error handling technique isn't just for a single value entered for input, but works even when the value of input is changed by the user. Remember input can represent the value of a text input field, thus its value changes when the user changes the contents of the text field. When the value of input is changed, the value of x is recomputed and likewise the value of sum and error is recomputed. If the new value is a valid integer, error will change to the empty string and sum will be set to the sum of x and y.

This is all made possible due to Tridash's non-linear nature, rather than composing a program out of a linear sequence of instructions, a program is composed out of a set of dependencies (bindings) between nodes. The task of automatically updating and recomputing the value of nodes is taken care of by Tridash, rather than having to be performed manually by the programmer. This, along with the new failure value semantics, added in version 0.5, presents a new error handling technique which simplifies the error handling logic and may, hopefully, lead to more robust applications being written in the future.