Advanced Concepts
Learn about advanced concepts behind how TruScript works.
Truthiness
Conditions in TruScript (e.g., if, while, and, or, not) do not require a boolean value. Instead, they evaluate the "truthiness" of a value.
A value is considered "truthy" if it has existent-like qualities. This feature makes it easy to write concise code without having to explicitly check for nil or false-like values.
Value |
Truthiness |
|
Always falsy |
|
Always falsy |
|
Always falsy |
|
Always truthy |
Numbers |
Truthy if non-zero, falsy if zero or |
Strings |
Truthy if non-empty, falsy if empty |
Objects |
Always truthy, including empty arrays ( |
if "": print("never") # empty string is falsy
if "anything": print("runs") # non-empty string is truthy
if 0: print("never") # zero is falsy
if []: print("runs") # empty array is truthy
Checking for truthiness
A common idiom for checking if a value is truthy in an expression context is to use the not operator. As the not operator inverts the result of the check, you can use another not to invert it back to the original value.
local value = "hello"
printf("{0} is truthy: {1}", value, not not value) # prints "hello is truthy: true"
Only the empty string is falsy. Any string with at least one character is truthy, including whitespace characters. The string "false", which is a non-empty string, is also truthy. If you want to convert a string to a boolean value, including checking for the string "false", you can use the tobool function instead of a truthiness check.
|
Short-circuiting and, or
It may be surprising to learn that TruScript’s and and or operators do not actually return a boolean value (like true or false). Instead, they determine the truthiness of the left operand and returns back either the left or right operand. This behavior opens up some interesting possibilities for using these operators in complex expressions.
-
a or b- Ifais truthy, returnsa. Otherwise, returnsa. -
a and b- Ifais falsy, returnsb. Otherwise, returnsa.
This behavior allows for you to provide a default value with the or operator, known in some other languages as "null coalescing". For example:
func print_display_name(player_name):
local name = player_name or "Anonymous"
print(name)
print_display_name("Pat") # prints "Pat"
print_display_name(nil) # prints "Anonymous"
If the left operand of and or or is sufficient to determine the result, the right operand is not evaluated.
This is known as "short-circuiting" because the right operand is not evaluated if the left operand is sufficient to determine the result. This can be useful for avoiding unnecessary computations or side effects. For example, consider the following script:
func expensive_computation():
print("Expensive computation running...")
wait(9999)
return 42
printf("Result: {0}", true or expensive_computation()) # prints "Result: true" and does not run the expensive computation
printf("Result: {0}", false and expensive_computation()) # prints "Result: false" and does not run the expensive computation
Equality
The == and != operators check for equality in TruScript. Whether two objects are considered "equal" is governed by these rules:
-
If values are different types, they are never equal.
-
If both values are
nil, they are equal. -
nilis equal tovoid. -
Numbers are equal if they are the same value, with a precision epsilon of 1e-10. This means that numbers that differ by one ten-billionth or less are considered equal.
-
Strings are compared character by character, and are equal if they have the same length and characters.
-
Booleans are equal if they are both
trueor bothfalse(XNOR gate). -
Objects compare by identity, meaning that two objects are equal if they are the exact same object in memory. Two different arrays containing the same values are not equal, and two different tables with the same keys and values are not equal.
The tolerant number comparison means == is not perfectly transitive at the very edge of the tolerance. We designed TruScript this way to allow for ordinary floating-point rounding errors to not break equality checks. However, it can also break mathematical transitivity in some cases. This is something you should be aware of when working with very small numbers!
|