From the comp.lang.functional FAQ:
Any subset of a language that describes only values and transformations upon them may be considered purely functional. This can be done by separating evaluation and execution, e.g. by allowing the language to conveniently describe and calculate values that describe executions, but not allowing them to execute without being hit with an executional primitive (such as a 'Just do it!' imperative).
The language as a whole may be considered purely functional if it only allows the description of values and transformations upon them.
In contrast: An ImpureFunctionalLanguage?, as used presently, is one that provides functional capabilities but also allows the mixing of evaluation and execution -- e.g. if you can put a 'print' statement inside a calculation, and that print statement is executed when that calculation is evaluated, then the language is impure. LispLanguage, SchemeLanguage, and ObjectiveCaml are impure. An ImperativeLanguage is any that allows description of evaluation by describing what to do or how to do it. Any language with MutableState (as in: mutable by the programmer) is necessarily Imperative. A PureImperativeLanguage? would be one that defines all evaluations in terms of executions, and forbids you to describe things in terms of what you want... allowing, instead, only descriptions of what to do. Assembler language and CeeLanguage are decent examples of PureImperativeLanguages?.
HaskellLanguage is nearly a PureFunctionalLanguage, excepting only the special treatment it gives functions returning an IO type called from a function named "main". By standardizing that particular use, it allows one to describe execution by assignment of a description of execution to a special name.
See also FunctionalProgrammingLanguage, PurelyFunctional