What are partial and unsafe operators?

119 Views Asked by At

While reading the Pony Tutorial on Operations, I noticed that some infix operators have partial and unsafe versions. Coming from C#, Java, Python, and JS/TS, I haven't the faintest clue what those do.

In C# there are checked and unchecked contexts for arithmetic. In a checked block, math that would result in a overflow throws an exception. Are the unsafe operators related to that?

Can someone please explain unsafe and partial operators?

1

There are 1 best solutions below

0
On

The regular operators, such as add/+, mod/%%, etc. will always return the most sensible result. This leads to certain results, such as division by zero being equal to 0. This is because these functions are mathematically considered non-partial, meaning that for every input, there is a defined output; even if the output may be unusual, like an addition that overflows having its result being smaller than the inputs.

However, there are certain situations where having a clearly defined result for every input is not what the programmer wants. That's where unsafe and partial operators come in.

  1. Since these functions must return defined results (see the division by zero example above), they have to run both extra and expensive instructions for that guarantee. The unsafe version of the operators removes these guarantees, and uses a quicker CPU instruction that may give unexpected results for certain inputs. This is useful when you know that your inputs cannot reach certain conditions (eg. overflow, division by zero), and you want your code to squeeze out some extra performance. From the documented definition of the add_unsafe/+~ and mod_unsafe/%%~ operators in trait Integer¹, for example:
  fun add_unsafe(y: A): A =>
    """
    Unsafe operation.
    If the operation overflows, the result is undefined.
    """

  fun mod_unsafe(y: A): A
    """
    Calculates the modulo of this number after floored division by `y`.

    Unsafe operation.
    If y is 0, the result is undefined.
    If the operation overflows, the result is undefined.
    """
  1. Alternatively, you may want to detect these conditions that would return mathematically-wrong results in your code at runtime, meaning that the functions do not return a value for every set of inputs, and are therefore partial. These will raise errors that you can handle as usual. Also reading the documentation of the add_partial/+? and mod_partial/%%? operators in trait Integer¹, we find:
  fun add_partial(y: A): A ?
    """
    Add y to this number.

    If the operation overflows this function errors.
    """

  fun mod_partial(y: A): A ?
    """
    Calculates the modulo of this number and `y` after floored division (`fld`).
    The result has the sign of the divisor.

    If y is `0` or the operation overflows, this function errors.
    """

¹ This trait is implemented by all integer types in Pony, both signed and unsigned.