.. 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*.