The **gestalt** package provides a function composition
operator, `%>>>%`

, which improves the clarity,
modularity, and versatility of your functions by enabling you to:

Express complex functions as chains of smaller, more readily intelligible functions

Directly manipulate a composite function as a list-like object, so that you can inspect, modify, or repurpose any part of the chain of constituent functions

More importantly, gestalt fosters a powerful way of thinking about values as functions.

The following example (adapted from purrr) illustrates the use of
`%>>>%`

to express a function that takes the name of
a factor-column of the `mtcars`

data frame, fits a linear
model to the corresponding groups, then computes the R² of the
summary.

```
library(gestalt)
<- mpg ~ wt
fit
<- {split(mtcars, mtcars[[.]])} %>>>%
r2 lapply(function(data) lm(!!fit, data)) %>>>%
: (
summarizelapply(summary) %>>>%
: sapply(`[[`, "r.squared")
stat
)
r2("cyl")
#> 4 6 8
#> 0.5086326 0.4645102 0.4229655
```

gestalt leverages the ubiquity of the magrittr `%>%`

operator, by adopting its semantics and augmenting it to enable you
to:

**Clarify intent**by annotating constituent functions with descriptive names, which also serve as subsetting references**Express nested sub-compositions**, while nonetheless preserving the runtime characteristics of a flattened composition, so you can focus on expressing structure that is most natural for your function**Unquote sub-expressions**with the tidyverse`!!`

operator, to enforce immutability or spare a runtime computation

`%>%`

Despite the syntactic similarity, the `%>>>%`

operator is conceptually distinct from the magrittr `%>%`

operator. Whereas `%>%`

“pipes” a value into a function to
yield a value, `%>>>%`

*composes* functions
to yield a function.

The most significant distinction, however, is that list idioms apply
to composite functions made by `%>>>%`

, so that you
can inspect, modify, and repurpose them, intuitively.

To select the first two functions in `r2`

, in order to get
the fitted model, index with the vector `1:2`

:

```
1:2]("cyl")[["6"]] # Cars with 6 cylinders
r2[#>
#> Call:
#> lm(formula = mpg ~ wt, data = data)
#>
#> Coefficients:
#> (Intercept) wt
#> 28.41 -2.78
```

To compute the residuals rather than the R², reassign the summary-statistic function:

```
<- r2
residuals $summarize$stat <- function(s) sapply(s, `[[`, "residuals")
residualsresiduals("cyl")[["6"]]
#> Mazda RX4 Mazda RX4 Wag Hornet 4 Drive Valiant Merc 280
#> -0.1249670 0.5839601 1.9291961 -0.6896780 0.3547199
#> Merc 280C Ferrari Dino
#> -1.0452801 -1.0079511
```

Consider a function that capitalizes and joins a random selection of characters:

```
<- sample %>>>% toupper %>>>% paste(collapse = "")
scramble
set.seed(1)
scramble(letters, 5)
#> [1] "YDGAB"
```

Here you see the final result of the composition. But because
`scramble`

is a list-like object, you can also inspect its
intermediate steps by applying a standard “map-reduce” strategy, such as
the following higher-order function:

`<- lapply(`%>>>%`, print) %>>>% compose stepwise `

`stepwise`

maps over the constituent functions of a
composite function to add printing at each step:

```
set.seed(1)
stepwise(scramble)(letters, 5)
#> [1] "y" "d" "g" "a" "b"
#> [1] "Y" "D" "G" "A" "B"
#> [1] "YDGAB"
```

Whenever you have a value that results from a series of piped values, such as

```
library(magrittr)
%>%
mtcars split(.$cyl) %>%
lapply(function(data) lm(mpg ~ wt, data)) %>%
lapply(summary) %>%
sapply(`[[`, "r.squared")
#> 4 6 8
#> 0.5086326 0.4645102 0.4229655
```

you can transpose it to a **constant composite
function** that computes the same value, simply by treating the
input value as a constant function and replacing each function
application, `%>%`

, by function composition,
`%>>>%`

:

```
<- {mtcars} %>>>%
R2 split(.$cyl) %>>>%
lapply(function(data) lm(mpg ~ wt, data)) %>>>%
lapply(summary) %>>>%
sapply(`[[`, "r.squared")
```

You gain power by treating (piped) values as (composite) functions:

**Values as functions are lazy**. You can separate the value’s declaration from its point of use—the value is only computed on demand:`R2() #> 4 6 8 #> 0.5086326 0.4645102 0.4229655`

**Values as functions are cheap**. You can cache the value of`R2`

by declaring it as a constant:`<- constant(R2) R2 R2() #> 4 6 8 #> 0.5086326 0.4645102 0.4229655 # On a 2016 vintage laptop ::microbenchmark(R2(), times = 1e6) microbenchmark#> Unit: nanoseconds #> expr min lq mean median uq max neval #> R2() 532 567 709.1435 585 647 39887308 1e+06`

**Values as functions encode their computation**. Since a composite function qua computation is a list-like object, you can compute on it to extract**latent information**.For instance, you can get the normal Q–Q plot of the fitted model for 6-cylinder cars from the head of

`R2`

:`head(R2, 3)() %>% .[["6"]] %>% plot(2)`

In conjunction with `%>>>%`

, gestalt also
provides:

`fn`

, a more concise and flexible variation of`function`

, which supports tidyverse quasiquotation.`<- 5L size fn(x, ... ~ sample(x, !!size, ...)) #> function (x, ...) #> sample(x, 5L, ...)`

`partial`

, to make new functions from old by fixing a number of arguments, i.e., partial application. Like`fn`

, it also supports quasiquotation.`<- partial(sample, size = !!size, replace = TRUE)) (draw #> <Partially Applied Function> #> #> * FUNCTION: #> function(x, prob) ... #> #> Calling 'FUNCTION(...)' is equivalent to calling #> sample(size = ^5L, replace = ^TRUE, ...) #> #> The function 'sample()' has the form #> function(x, size, replace = FALSE, prob = NULL) ... #> #> Recover the called function with 'departial()'. set.seed(2) draw(letters) #> [1] "u" "o" "f" "f" "h"`

Additionally,

`partial`

is:**Hygenic**: The fixed argument values are tidily evaluated promises; in particular, the usual lazy behavior of function arguments, which can be overridden via unquoting, is respected even for fixed arguments.**Flat**: Fixing arguments in stages is*operationally*equivalent to fixing them all at once—you get the same function either way:`partial(partial(sample, replace = TRUE), size = 5L) #> <Partially Applied Function> #> #> * FUNCTION: #> function(x, prob) ... #> #> Calling 'FUNCTION(...)' is equivalent to calling #> sample(replace = ^TRUE, size = ^5L, ...) #> #> The function 'sample()' has the form #> function(x, size, replace = FALSE, prob = NULL) ... #> #> Recover the called function with 'departial()'.`

See the package documentation for more details
(`help(package = gestalt)`

).

The core semantics of

`%>>>%`

conform to those of the magrittr`%>%`

operator developed by Stefan Milton Bache.The engine for quasiquotation and expression capture is powered by the rlang package by Lionel Henry and Hadley Wickham.

The “triple arrow” notation for the composition operator is taken from the Haskell Control.Arrow library by Ross Paterson.