.. Mars Documentation
Copyright (C) 2010 Matt Giuca
.. This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
.. This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.. You should have received a copy of the GNU General Public License
along with this program. If not, see .
:mod:`impure` --- Impure functions
==================================
.. sectionauthor:: Matt Giuca
.. moduleauthor:: Matt Giuca
.. module:: impure
:synopsis: Provides functions which break the declarative semantics of
Mars.
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 :keyword:`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
--------------------
.. function:: 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 :func:`eq`, :func:`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, :func:`is`
must return false.
* If *x* and *y* are the result of the same allocation operation,
:func:`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 :func:`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 :func:`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 :func:`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 :func:`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 :func:`is` compares true).
.. function:: 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*.
.. function:: array_append(array :: Array(a), value :: a) :: Array(a)
Appends *value* onto the end of *array*. Returns *array*.
.. function:: 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*.
.. function:: 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*.