.. Mars Documentation Copyright (C) 2008 Matt Giuca 11/12/2008 .. 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 . .. _ref-values: Values ====== .. sectionauthor:: Matt Giuca Term-level *values* are units of data which may be stored in variables and data structures, and passed as arguments. Each value has a corresponding type, with each :ref:`built-in type ` having a special set of values, and :ref:`user-defined types ` having a set of rules that define what values inhabit each type. This section describes the values that inhabit each type in Mars. It also describes, for each type family, how the values may be constructed, and how values are to be displayed (which affects both their appearance when printed by the interactive prompt, as well as the output of the :func:`show` function). .. _ref-value-num: Numbers ------- Number values are members of the :type:`Num` type. Mars numbers are represented internally as binary floating-point numbers; as such, the members of this type form a subset of the real numbers. The numbers have at least 64-bit "double" precision. The usual caution about floating-point rounding errors and imprecision applies. The most common representation is the IEEE 754 binary64 format (commonly known as "double"), but the implementation is allowed to use any binary floating-point format that satisfies the following criteria: * Support for positive and negative values. * A minimum exponent of at most -1022 and a maximum exponent of at least 1023, * A mantissa capable of representing integer values up to at least 2^53. .. note:: The IEEE 754 binary64 format has a 52-bit mantissa. It represents values up to 2^53 via an implicit 1 bit. This means that the implementation must provide *at a minimum* a 64-bit "double" format; any larger binary floating point format is also acceptable, and programs should be written to allow for variations in floating-point precision. The implementation is not permitted to represent values as 32-bit floats (the equivalent of the C :type:`float` type). The above rules mean that: * All integers between -2^53 and 2^53, inclusive, are exactly representable. (-9007199254740992 to 9007199254740992, inclusive.) * The maximum possible value will be at least 2^1023 (and the same magnitude on the negative side). * It is possible to represent at least one non-integer between each pair of integers in the range -2^52 to 2^52. * All multiples of 2^-53 between -1 and 1 are exactly representable. * It will be possible to represent values with a non-zero magnitude at least as small as 2^-1022. (Note: IEEE binary formats allow for much smaller numbers to be represented, but this is not required by Mars.) Unlike in some floating-point systems, there is no distinction between 0 and -0. The two values are considered equal under all circumstances, and -0 is displayed without a minus sign. .. warning:: An overflow (a value with a larger magnitude than the largest representable value, which is at least 2^1023) will result in undefined behaviour. While the implementation is likely to generate infinity values, the specifics of dealing with such values are unspecified and this behaviour should not be relied upon. Number values can be created using :ref:`number literal expressions `. Also, many built-in functions produce number values (such as all of the arithmetic functions). The string representation of a number is an ASCII decimal representation, preceded by a hyphen if the value is negative. Integers (whole numbers) are always displayed without a decimal point or fractional component. Other numbers are displayed with a decimal point as a number literal; the implementation is allowed to display numbers with a large or small magnitude with the "``e``" exponent notation, such as ``4.2e+18`` (which is not a valid number literal). .. _ref-value-array: Arrays ------ Array values are members of the :type:`Array` type family. Arrays in Mars are extensible arrays (sometimes known as "vectors"), the elements of which may be accessed in constant time. An array is a collection of elements that has a specific order and allows duplicate elements. Array types are parameterised by a type variable *a*; this denotes the type of all of the elements. For example, the type :type:`Array(Num)` permits only elements of type :type:`Num`. Array elements are typically referred to by *index*. The index is an integer, where the first element of the array has index 0, and each subsequent element has an index 1 greater than the previous. The *length* of the array is the number of elements contained within it. The index of the last element of the array is therefore *length*-1. It is not meaningful to talk about elements with a negative index, or elements whose index is greater than or equal to *length*. Individual array elements can be modified in constant time, regardless of the element's position in the array. Furthermore, new elements can be added to the end of the array in amortised constant time (typically, this is implemented by allocating more memory than the array requires, and having the array occasionally resize by doubling the amount of memory allocated). .. warning:: Constant-time array updates are currently only possible by importing the :mod:`impure` library module, and are considered to be an unofficial part of the language. :token:`Array literals ` may be used to build array values. Built-in functions are also available to create and manipulate arrays. The string representation of an array is the same as the array literal syntax: a comma-separated list of the string representation of each element, enclosed in square brackets. .. _ref-value-function: Functions --------- Function values, or *closures*, are members of the :type:`->` and :type:`->io` type families. As Mars is a functional programming language, all functions are first-class and may be treated as ordinary values. A function value may be *called*, with a fixed number of arguments being supplied, and a resulting value will be *returned*. Some functions may also perform I/O effects (such as printing) when they are called. If the :type:`->` type constructor is given *n* arguments, the first *n*-1 arguments are the types of the function parameters, while the final argument is the type of the function result. For example, values of type ``(a, b) -> c`` are functions which accept two arguments of types ``a`` and ``b`` respectively, and produce a result of type ``c``. The data carried by a function value is opaque, but it is likely to include the code that specified the original function. Because Mars supports *closures*, function values may also contain other data values. For example, the expression ``add(1, ...)`` creates a function value that not only includes the code for the :func:`add` function, but also the value ``1`` which will be needed when the function is called. Functions may only be created by being declared at the top level, or through currying. The string representation of a function is implementation-defined. Because functions are considered opaque, it should not technically be obtain any information about a function other than by calling it. However, implementations may display information about the function object, such as its original name or memory location, in order to help identify the function. The string should therefore not be used in computations (only for debugging or display purposes). There are two distinct type constructors for functions: :type:`->` and :type:`->io`. These distinguish between functions declared as "pure" (without the :keyword:`io` keyword) and those declared with the :keyword:`io` keyword. These two types are totally incompatible: it is not possible to convert an I/O function to a pure function, and a pure function cannot be used in a place where an I/O function is expected. .. note:: It is possible to explicitly convert a pure function to an I/O function using the :func:`toio` functions in the :mod:`iofuncs` module. .. _ref-value-userdef: Values of user-defined types ---------------------------- When a type is declared using the :keyword:`type` keyword, a set of values is created for that type. The values that inhabit each user-defined type are totally distinct from those of any other type. This is because a) each user-defined type declares a unique set of data constructor names, and b) each value of a user-defined type belongs to some constructor of that type. As described in :ref:`ref-type-declarations`, each user-defined type *T* consists of a set of one or more data constructors *c0*, ..., *cn*, and each constructor *ci* has a unique name, and a sequence of zero or more fields *fi0*, ..., *fim* (where *m* varies from one constructor to another). Each field *fij* has a type *tij*. Every value of type *T* belongs to a particular data constructor *ci*, and has a value of type *tij* for each field of that constructor. User-defined types may also be parameterised; the type parameter is used to specify the types of various fields. For example, the :type:`List` type from the :mod:`prelude` is defined as:: type List(a): Cons(head :: a, tail :: List(a)) Nil This type has two data constructors, :func:`Cons` and :func:`Nil`. This means that every value of type :type:`List(a)` belongs to either the :func:`Cons` or :func:`Nil` constructor. Values that belong to the :func:`Cons` constructor contain two sub-values: one value of type *a* and one value of type :type:`List(a)`. There is only one value that belongs to the :func:`Nil` constructor: :func:`Nil` (as that constructor has no fields). Values of a user-defined type can be created by calling the constructor function of the same name as one of the constructors; this will determine which constructor the value belongs to and also initialise all of the fields. Values of parameterless constructor (one declared without parentheses) cannot be created; they already exist as global values of the same name (for example, :func:`Nil` is a global constant which is the only value that belongs to the constructor :func:`Nil`). The :keyword:`switch` statement can be used to determine which constructor a particular value belongs to, and also access the value's fields. The :ref:`assignment statement ` and :ref:`field reference expression ` can also be used to access the value's fields. Two values of the same type are considered equal if a) they both belong to the same constructor, and b) all of their corresponding field values are equal (see :func:`eq`). The string representation of a value of a user-defined type is the same as the construction syntax: for parameterless constructors, it is just the constructor name. Otherwise, it is the constructor name, followed by a comma-separated list of the string representation of each field, enclosed in parentheses.