Total functional programming

Source: Wikipedia, the free encyclopedia.

Total functional programming (also known as strong functional programming,

provably terminating.[2]

Restrictions

Termination is guaranteed by the following restrictions:

  1. A restricted form of
    substructural recursion, or "strongly normalizing" as proven by abstract interpretation of code.[3]
  2. Every function must be a total (as opposed to partial) function. That is, it must have a definition for everything inside its domain.
    • There are several possible ways to extend commonly used partial functions such as division to be total: choosing an arbitrary result for inputs on which the function is normally undefined (such as for division); adding another argument to specify the result for those inputs; or excluding them by use of type system features such as refinement types.[2]

These restrictions mean that total functional programming is not

asymptotic upper bound
can be calculated (by a program that itself only uses Walther recursion) can be trivially transformed into a provably-terminating function by using the upper bound as an extra argument decremented on each iteration or recursion.

For example,

Haskell
:

import Data.List (partition)

qsort []       = []
qsort [a]      = [a]
qsort (a:as)   = let (lesser, greater) = partition (<a) as
                 in qsort lesser ++ [a] ++ qsort greater

To make it substructural recursive using the length of the vector as a limit, we could do:

import Data.List (partition)

qsort x = qsortSub x x
-- minimum case
qsortSub []     as     = as -- shows termination
-- standard qsort cases
qsortSub (l:ls) []     = [] -- nonrecursive, so accepted
qsortSub (l:ls) [a]    = [a] -- nonrecursive, so accepted
qsortSub (l:ls) (a:as) = let (lesser, greater) = partition (<a) as
                            -- recursive, but recurs on ls, which is a substructure of
                            -- its first input.
                         in qsortSub ls lesser ++ [a] ++ qsortSub ls greater

Some classes of algorithms have no theoretical upper bound but do have a practical upper bound (for example, some heuristic-based algorithms can be programmed to "give up" after so many recursions, also ensuring termination).

Another outcome of total functional programming is that both

strict evaluation and lazy evaluation result in the same behaviour, in principle; however, one or the other may still be preferable (or even required) for performance reasons.[4]

In total functional programming, a distinction is made between

dependent types) also without codata.[5]

Both

Calculus of Constructions
.

See also

References

  1. ^ This term is due to: Turner, D.A. (December 1995). Elementary Strong Functional Programming. First International Symposium on Functional Programming Languages in Education. Springer LNCS. Vol. 1022. pp. 1–13..
  2. ^
  3. . See in particular pp. 86–91.