Tacit programming, also called point-free style, is a programming paradigm in which function definitions do not identify the arguments on which they operate. Instead the definitions merely compose other functions, among which are combinators that manipulate the arguments. Tacit programming is of theoretical interest, because the strict use of composition results in programs that are well adapted for equational reasoning. It is also the natural style of certain programming languages, including APL and its derivatives, and concatenative languages such as Forth. The lack of argument naming gives point-free style a reputation of being unnecessarily obscure, hence the epithet "pointless style". Unixscripting uses the paradigm with pipes. The key idea in tacit programming is to assist in operating at the appropriate level of abstraction. That is, to translate the natural transformation given by currying into computer functions, where the left represents the uncurried form of a function and the right the curried. CA denotes the functionals from A to C, while A × B denotes the Cartesian product of A and B.
Tacit programming can be illustrated with the following Python code. A sequence of operations such as the following: def example: y = foo z = bar w = baz return w
... is written in point-free style as the composition of a sequence of functions, without parameters: def compose: return functools.partial example = compose
Functional programming
A simple example is a program which takes a sum of a list. A programmer might define a sum recursively using a pointed method as: sum = x + sum xs sum = 0
However, by noting this as a fold the programmer could replace this with: sum xs = foldr 0 xs
And then the argument is not needed, so this can be replaced with sum = foldr 0
which is point-free. Another example uses function composition: p x y z = f z
The following Haskell-like pseudo-code exposes how to reduce a function definition to its point-free equivalent: p = \x -> \y -> \z -> f z = \x -> \y -> f = \x -> \y -> y = \x -> f. = \x -> = \x -> . g) x = . g
so p = . g
Finally, to see a complex example imagine a map filter program which takes a list, applies a function to it, and then filters the elements based on a criterion mf criteria operator list = filter criteria
It can be expressed point-free as mf = . . filter Note that, as stated previously, the points in 'point-free' refer to the arguments, not to the use of dots; a common misconception.
APL family
In J, the same sort of point-free code occurs in a function made to compute the average of a list of numbers: avg=: +/ % # +/ sums the items of the array by mapping summation to the array. % divides the sum by the number of elements in the array. Euler's formula expressed tacitly: cos =: 2 o. ] sin =: 1 o. ] Euler =: ^@j. = cos j. sin
The same tacit computations expressed in Dyalog APL: avg ← +⌿ ÷ ≢ cos ← 2 ○ ⊢ sin ← 1 ○ ⊢ j ← ⍝ this part is not tacit Euler ← *∘j = cos j sin
is a tacit or point-free composition which returns the counts of its arguments and the arguments, in the order of decreasing counts. The 'sort' and 'uniq' are the functions, the '-c' and '-rn' control the functions, but the arguments are not mentioned. The '|' is the composition operator.