An Anonymous Function (also known as a *lambda expression*) is a
function definition that is not bound to an identifier. That is, it is a
function that is created and used, but never assigned to a variable.

In a prior post I discussed how I am not completely ssatisfied with `purrr`

/`rlang`

’s
anonymous function syntax as it has no capability for naming the
function arguments anything other than `.x`

and `.y`

.

In a follow-up post, I looked at alternate syntaxes for creating anonymous functions.

In this post, I

- outline what I think would unify the anonymous function implementations
- introduce the ‘anon’ package

## Thoughts on a unifying anonymous function implementation

After looking at the other syntaxes for creating anonymous functions, my ideas for a unifying anonymous function implementation are as follows:

- Use a short function to create other anonymous functions
- This is mostly personal preference.
- Overloading an existing operator seems fraught with compatibility issues.

- Support both
**implicit**and**explicit**formal arguments.- Supporting only one or the other limits the flexibility.
- I want the generation of arguments to work automatically when it’s obvious what is meant, but still retain the ability to be explicit when more clarifying information is needed about the ordering/existence of variables as the formal arguments.

- For
**explicit formal arguments**allow multiple representations i.e. to be familiar across more existing packages, the following should all create the same anonymous function`f(x, y, x + y)`

`f(x, y ~ x + y)`

`f(x, y, ~x + y)`

`f(x + y ~ x + y)`

- Try and match
`purrr`

/`rlang`

’s syntax as close as possible- This seems to be the most popular anonymous function syntax, so don’t rock the boat by being too different.
- Yet still be valid without the leading tilde
- I.e. the following should all create the same anonymous function
`f(x + y)`

`f(~x + y)`

`f(~.x + .y)`

## Introducing the `anon`

package for anonymous functions in R

The `anon`

package provides two functions to help define succinct anonymous functions (also called *lambdas*).

# Features

`anon`

provides two user-facing functions:

`lambda()`

for easily and compactly creating lambda expressions in R, while being broadly compatible with a number of existing lambda syntaxes. This function is also aliased to`L()`

for the sake of brevity.`patch_purrr_mapper()`

to patch`purrr`

to allow`anon`

to convert formulas to functions instead of`rlang::as_function()`

. Using`anon`

to convert formulas-to-functions enables:- automatic argument extraction (rather than forcing the arguments to be
`.x`

and`.y`

) - explicit arguments through the use of 2 sided formulas i.e. the formal arguments are extracted from
the expression on the LHS of a two-sided formula e.g.
`a:b ~ a + b + 1`

becomes`function(a, b) {a + b + 1}`

- automatic argument extraction (rather than forcing the arguments to be

# Example use of `lambda()`

/`L()`

for creating anonymous functions

The following calls all create the same anonymous function:

`function(x, y) x + y`

`L(.x + .y)`

`L(x + y)`

`L(~x + y)`

`L(x, y, x + y)`

`L(x, y ~ x + y)`

`L(x, y, ~x + y)`

`L(x:y ~ x + y)`

# Example use of `patch_purrr_mapper()`

to enable extended functionality for lambdas in `purrr`

By running `patch_purrr_mapper()`

an extra S3 method is added for `purrr::as_mapper()`

i.e.
`as_mapper.formula()`

.

By doing so, any *formula-used-as-function* in `purrr`

will be passed to `anon::as_function_formula()`

which allows for more expressiveness
than `rlang::as_function()`

. i.e.

- Can use any name for the variables, not just
`.x`

and`.y`

- Can set explicit formal arguments (by specifying the LHS of the formula)
- If no explicit formal arguments are given, then all variable names on the RHS of the formula are used as formal arguments. The order of the formal arguments is the same as the order of appearance of the variables.
- If
`.x`

or`.y`

appear on the RHS and no explicit formal arguments are given on the LHS, then they are used as the first formal arguments (regardless of the order in which they appear on the RHS) - You can use
`.`

as a stand-in for the first argument.

```
library(purrr)
anon::patch_purrr_mapper()
z <- 10L
map_int(1:3, ~. + 1L)
[1] 2 3 4
map_int(1:3, ~.x + 1L)
[1] 2 3 4
map_int(1:3, ~ value + 1L)
[1] 2 3 4
map_int(1:3, val ~ val + 1L)
[1] 2 3 4
map_int(1:3, val ~ val + z)
[1] 11 12 13
map2_dbl(1:3, 4:6, ~ .x / .y)
[1] 0.25 0.40 0.50
map2_dbl(1:3, 4:6, ~ a / b)
[1] 0.25 0.40 0.50
map2_dbl(1:3, 4:6, ~ b / a)
[1] 0.25 0.40 0.50
map2_dbl(1:3, 4:6, b:a ~ a / b)
[1] 4.0 2.5 2.0
pmap_int(list(1:2, 3:4, 5:6, 7:8), ~a * b * c * d)
[1] 105 384
```

## Share this post

Twitter

Google+

Facebook

Reddit

LinkedIn

StumbleUpon

Pinterest

Email