# FunctionChains.jl

FunctionChains.jl implements chained functions with functionality beyond `Base.ComposedFunction`

.

The package defines the function `fchain`

that turns a sequence of functions into a callable function chain. Functions are applied in the order they are given, so `fchain(f, g, h)`

and `fchain((f, g, h))`

are semantically equivalent to `h ∘ g ∘ f`

.

Function chains can be based on tuples of functions but also on arrays (e.g. `fchain([x -> i * x for i in 1:4])`

or generators/iterators (e.g. `fchain((x -> i * x for i in 1:4))`

of functions. `fchain`

will always try to generate type-stable function chains if possible.

The function chain generated by `fchain`

supports `InverseFunctions.inverse`

and/or `ChangesOfVariables.with_logabsdet_jacobian`

, as well as the `Adapt`

, `Functors`

and `FlexiMaps`

APIs, if all functions in the chain do support the respective API.

FunctionChains also exports the convenience functions `asfunction(f)`

and `typed_callable(f)`

that wrap a callable `f`

in a properly typed callable function (object) if necessary, e.g. if `f`

is a type (constructor).

Example:

```
using FunctionChains
f = fchain(Complex, sqrt)
f(-1)
# output
0.0 + 1.0im
```

```
g = fchain((x -> i * x for i in 1:4))
g(1.75)
# output
42.0
```

The functions chains `f`

and `g`

in this example are both type stable

```
using Test
@inferred f(-1)
```

`@inferred g(1.75)`

In general, type stability will depend on the functions in the sequence and the type of the sequence itself.