# funprog

##### Common Higher-Order Functions in Functional Programming Languages

`Reduce`

uses a binary function to successively combine the
elements of a given vector and a possibly given initial value.
`Filter`

extracts the elements of a vector for which a predicate
(logical) function gives true. `Find`

and `Position`

give
the first or last such element and its position in the vector,
respectively. `Map`

applies a function to the corresponding
elements of given vectors. `Negate`

creates the negation of a
given function.

- Keywords
- programming

##### Usage

```
Reduce(f, x, init, right = FALSE, accumulate = FALSE)
Filter(f, x)
Find(f, x, right = FALSE, nomatch = NULL)
Map(f, ...)
Negate(f)
Position(f, x, right = FALSE, nomatch = NA_integer_)
```

##### Arguments

- f
- a function of the appropriate arity (binary for
`Reduce`

, unary for`Filter`

,`Find`

and`Position`

, $k$-ary for`Map`

if this is called with $k$ arguments). An arbitrary predicate function for`Negate`

. - x
- a vector.
- init
- an R object of the same kind as the elements of
`x`

. - right
- a logical indicating whether to proceed from left to right (default) or from right to left.
- accumulate
- a logical indicating whether the successive reduce combinations should be accumulated. By default, only the final combination is used.
- nomatch
- the value to be returned in the case when “no match” (no element satisfying the predicate) is found.
- ...
- vectors.

##### Details

If `init`

is given, `Reduce`

logically adds it to the start
(when proceeding left to right) or the end of `x`

, respectively.
If this possibly augmented vector $v$ has $n > 1$ elements,
`Reduce`

successively applies $f$ to the elements of $v$
from left to right or right to left, respectively. I.e., a left
reduce computes $l_1 = f(v_1, v_2)$, $l_2 = f(l_1, v_3)$, etc.,
and returns $l_{n-1} = f(l_{n-2}, v_n)$, and a right reduce does
$r_{n-1} = f(v_{n-1}, v_n)$, $r_{n-2} = f(v_{n-2}, r_{n-1})$
and returns $r_1 = f(v_1, r_2)$. (E.g., if $v$ is the
sequence (2, 3, 4) and $f$ is division, left and right reduce give
$(2 / 3) / 4 = 1/6$ and $2 / (3 / 4) = 8/3$, respectively.)
If $v$ has only a single element, this is returned; if there are
no elements, `NULL`

is returned. Thus, it is ensured that
`f`

is always called with 2 arguments.

The current implementation is non-recursive to ensure stability and scalability.

`Reduce`

is patterned after Common Lisp's `reduce`

. A
reduce is also known as a fold (e.g., in Haskell) or an accumulate
(e.g., in the C++ Standard Template Library). The accumulative
version corresponds to Haskell's scan functions.

`Filter`

applies the unary predicate function `f`

to each
element of `x`

, coercing to logical if necessary, and returns the
subset of `x`

for which this gives true. Note that possible
`NA`

values are currently always taken as false; control over
`NA`

handling may be added in the future. `Filter`

corresponds to `filter`

in Haskell or `remove-if-not`

in
Common Lisp.

`Find`

and `Position`

are patterned after Common Lisp's
`find-if`

and `position-if`

, respectively. If there is an
element for which the predicate function gives true, then the first or
last such element or its position is returned depending on whether
`right`

is false (default) or true, respectively. If there is no
such element, the value specified by `nomatch`

is returned. The
current implementation is not optimized for performance.

`Map`

is a simple wrapper to `mapply`

which does not
attempt to simplify the result, similar to Common Lisp's `mapcar`

(with arguments being recycled, however). Future versions may allow
some control of the result type.

`Negate`

corresponds to Common Lisp's `complement`

. Given a
(predicate) function `f`

, it creates a function which returns the
logical negation of what `f`

returns.

##### See Also

Function `clusterMap`

and `mcmapply`

(not
Windows) in package parallel provide parallel versions of `Map`

.

##### Examples

`library(base)`

```
## A general-purpose adder:
add <- function(x) Reduce("+", x)
add(list(1, 2, 3))
## Like sum(), but can also used for adding matrices etc., as it will
## use the appropriate '+' method in each reduction step.
## More generally, many generics meant to work on arbitrarily many
## arguments can be defined via reduction:
FOO <- function(...) Reduce(FOO2, list(...))
FOO2 <- function(x, y) UseMethod("FOO2")
## FOO() methods can then be provided via FOO2() methods.
## A general-purpose cumulative adder:
cadd <- function(x) Reduce("+", x, accumulate = TRUE)
cadd(seq_len(7))
## A simple function to compute continued fractions:
cfrac <- function(x) Reduce(function(u, v) u + 1 / v, x, right = TRUE)
## Continued fraction approximation for pi:
cfrac(c(3, 7, 15, 1, 292))
## Continued fraction approximation for Euler's number (e):
cfrac(c(2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8))
## Iterative function application:
Funcall <- function(f, ...) f(...)
## Compute log(exp(acos(cos(0))
Reduce(Funcall, list(log, exp, acos, cos), 0, right = TRUE)
## n-fold iterate of a function, functional style:
Iterate <- function(f, n = 1)
function(x) Reduce(Funcall, rep.int(list(f), n), x, right = TRUE)
## Continued fraction approximation to the golden ratio:
Iterate(function(x) 1 + 1 / x, 30)(1)
## which is the same as
cfrac(rep.int(1, 31))
## Computing square root approximations for x as fixed points of the
## function t |-> (t + x / t) / 2, as a function of the initial value:
asqrt <- function(x, n) Iterate(function(t) (t + x / t) / 2, n)
asqrt(2, 30)(10) # Starting from a positive value => +sqrt(2)
asqrt(2, 30)(-1) # Starting from a negative value => -sqrt(2)
## A list of all functions in the base environment:
funs <- Filter(is.function, sapply(ls(baseenv()), get, baseenv()))
## Functions in base with more than 10 arguments:
names(Filter(function(f) length(formals(args(f))) > 10, funs))
## Number of functions in base with a '...' argument:
length(Filter(function(f)
any(names(formals(args(f))) %in% "..."),
funs))
## Find all objects in the base environment which are *not* functions:
Filter(Negate(is.function), sapply(ls(baseenv()), get, baseenv()))
```

*Documentation reproduced from package base, version 3.2.0, License: Part of R 3.2.0*