impure — Impure functions

This module provides functions which break the declarative semantics of Mars.


Mars is, fundamentally, a pure language. This means that no function can modify an existing value or global state, only return a value (and perform input/output, if the function is declared as io).

The functions in this module break that purity by modifying their input arguments. They should not be considered part of the language semantics, and are not intended to be used by most code. They are provided to increase performance in certain situations. Use at your own risk.

Comparison functions

is(x :: a, y :: a) :: Num

Returns 1 if x has the same identity as y, 0 otherwise. This performs “reference” equality, such that two values are only considered equal if they are the same object or are directly aliased. This is somewhat unspecified, because the implementation can choose to make certain data elements aliased if they are equal. The implementation must make the following guarantees:

  • If x and y are inequal according to eq, is must return false.
  • If x and y are functions, if they do not have the same behaviour (results, errors and non-termination) for all possible inputs, is must return false.
  • If x and y are the result of the same allocation operation, is must return true. This means that if the value of x is assigned to y, then is(x, y) will be true.
  • Otherwise, the result is unspecified.

Some important caveats follow:

  • There is no guarantee that two equal numbers will have the same identity; this largely depends on whether the implementation uses boxed or unboxed numbers and whether it interns boxed number values. For example, is(0, 0) is unspecified, because each reference to the value 0 could create distinct number values.
  • There is no guarantee that two function values loaded from the same global function will have the same identity. For example, is(add, add) is unspecified, because add is a global function name, and the two references to it could create distinct function values.
  • Two identical functions, defined separately, may be considered to have the same identity. For example, given a function double1(x :: Num) :: Num = x * 2 and a function double2(x :: Num) :: Num = x + x the result of is(double1, double2) is unspecified. While it is most likely that is would return false in this case, it is conceivable that an optimisation could realise that they are equivalent and combine their definitions, making the two names refer to the same location in memory, and hence is might return true.

This function breaks the pure semantics of the Mars programming language because in a pure language, it should not be possible to distinguish between two aliased objects and two unaliased objects which are equal. Note that the language implementation is allowed to arbitrarily decide to alias any equal data structures without changing the semantics of the language; hence it is the is function and other functions in this module that are considered to be outside the semantics.

Array operations

These functions apply an operation to all values which are aliased to the input array (for which is compares true).

array_set(array :: Array(a), index :: Num, value :: a) :: Array(a)

Replaces array element index with value. Returns array. It is an error if array has no element at index.

array_append(array :: Array(a), value :: a) :: Array(a)

Appends value onto the end of array. Returns array.

array_extend(array1 :: Array(a), array2 :: Array(a)) :: Array(a)

Appends each element of array2 onto the end of array1. Does not modify array2. Returns array1.

array_delete(array :: Array(a), index :: Num) :: Array(a)

Removes array element index. Returns array. It is an error if array has no element at index.

Table Of Contents

Previous topic

debug — Debugging functions

Next topic

iofuncs — I/O versions of higher-order functions

This Page