Our intuitive idea of a function is that it describes the dependence of one quantity upon another. There is no condition on what kind of quantities are involved. They could be integers, Turing machines, binary search trees, window hierarchies, digital circuits or whatever. The possibilities are endless. The idea of functional programming is that functions are described applicatively, by plugging together other functions. This recursive dependence of functions on other functions bottoms out with the primitive operators. If the primitive operators are “effective,” i.e., they can be used to calculate, compute, construct or build one quantity from another, then all functions expressed applicatively are similarly effective. Imperative functional programming is the application of these ideas to imperative computations. Quantities here are imperative computations and functions denote dependences between imperative computations. Effectiveness of a function means that a computation produced from it can be effectively carried out whenever the input computations can be effectively carried out. It is often felt that imperative computations and functional programming are in conflict. Adding imperative computations to a functional programming language is found to destroy its “referential transparency.” See, for example, [Abelson et al., 1985, Sec. 3.1] for a discussion of the issue. However, in languages where such issues arise, imperative computations are thrown together by extending or modifying functional computation. The idea that functions denote dependences is lost in the process. In contrast, imperative functional programming does not involve altering functional computation in any way. It merely applies it to a new context, that of imperative compu-
Read full abstract