**domain**is a set of values. A value might be in several domains.

**Finite**domains have a limited number of values, they can be enumerated.

**Infinite**domains do not. Domains may be empty.

A domain is most abstractly defined by a **constraint**, a function which determines, for a given value, whether or not it is part of the domain. A constraint which always returns **false** will define an empty domain; a constraint which always returns **true** will define the infinite domain of all possible values.

The domain of a **function** is the set of values the function will accept as **input** (precondition.) The **range** of a function is the set of values the function might **output** (postcondition.) They are both defined by domain constraints.

A **variable** is a (named) storage space. It contains one representation of a value at a time. A variable has a domain that defines which values may be assigned to the variable.

A value may have a **type** associated with it. A type is an assertion that the value is a member of a particular (named) domain. Other domain constraints may use this as a starting point (assumption) from which appropriate tests may be devised to decide the membership of a value in a particular domain. Type, if included at all, is part of the value itself.

**Deterministic** functions consistently return the same value when given the same parameters. Using non-deterministic functions in a domain constraint definition may lead to errors.

[TODO: constants, side-effects, procedures, symbols, L-values, R-values, passing functions as parameters -- functions as values rather than symbols, unnamed functions, l-values with parameters, namespaces, overloading, overriding, most-specific type, function priority, ...]