impure — Impure functions
This module provides functions which break the declarative semantics of Mars.
Warning
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.