Posted on Categories Programming, Statistics, Tutorials

# Some Neat New R Notations

The `R` package `wrapr` supplies a few neat new coding notations. An Abacus, which gives us the term “calculus.”

The first notation is an operator called the “named map builder”. This is a cute notation that essentially does the job of `stats::setNames()`. It allows for code such as the following:

```library("wrapr")

names <- c('a', 'b')

names := c('x', 'y')
#>   a   b
#> "x" "y"
```

This can be very useful when programming in `R`, as it allows indirection or abstraction on the left-hand side of inline name assignments (unlike `c(a = 'x', b = 'y')`, where all left-hand-sides are concrete values even if not quoted).

A nifty property of the named map builder is it commutes (in the sense of algebra or category theory) with `R`‘s “`c()`” combine/concatenate function. That is: `c('a' := 'x', 'b' := 'y')` is the same as `c('a', 'b') := c('x', 'y')`. Roughly this means the two operations play well with each other.

The second notation is an operator called “anonymous function builder“. For technical reasons we use the same “`:=`” notation for this (and, as is common in `R`, pick the correct behavior based on runtime types).

The function construction is written as: “`variables := { code }`” (the braces are required) and the semantics are roughly the same as “`function(variables) { code }`“. This is derived from some of the work of Konrad Rudolph who noted that most functional languages have a more concise “lambda syntax” than “function(){}” (please see here and here for some details, and be aware the `wrapr` notation is not as concise as is possible).

This notation allows us to write the squares of `1` through `4` as:

```sapply(1:4, x:={x^2})
```

```sapply(1:4, function(x) x^2)
```

It is only a few characters of savings, but being able to choose notation can be a big deal. A real victory would be able to directly use lambda-calculus notation such as “`(λx.x^2)`“. We are also experimenting with the following additional notation:

```sapply(1:4, λ(x, x^2))
```

Edit 2017-08-24: the above functions (including `λ`), have all been moved from `seplyr` to `wrapr` and released on CRAN!

## 6 thoughts on “Some Neat New R Notations”

1. Markk says:

Don’t know what that is, but it is not a usable abacus. Seems to be missing some beads. Ought to have 4 on bottom and one on top in each column.

2. I have improved the `λ` documentation a bit: link.

And, the `lambda(x)(x^2)` form is pretty useless (same form as `function(x) x^2`, and without the `R`-language hooks). Mostly I put it in as a place holder so the `λ(x, x^2)` form has something to cross-link its help to (to prevent generating a help file with complicated character encoding in the help file name). I’ve also changed its syntax to `lambda(x, x^2)` to make it closer the `λ(x, x^2)` form.

3. Stephen Zander says:

Are you familiar with the magrittr syntactic sugar . %>% … and . %>% { … }?

They supply the same functionality as your lamba example above. The only downside being you cannot pass more than one argument. If you expanded := to support multiple arguments on the LHS, similar to the fat-arrow operator (“=>”) in EMACSscript6, that would be a significant improvement.

1. I have used the `magrittr``. %>% f`” notation from time to time.

The `wrapr` function builders can conveniently take multiple arguments:

```library("wrapr")
f <- c(x,y) := { x + 3 * y }
f(1,2)
#>  7
```
```library("wrapr")
defineLambda()
f <-  λ(x, y, x + 2*y)
f(2,4)
#>  10
```

Or even the original formula interface version of arguments:

```library("wrapr")
f <- x~y := x + 3 * y
f(5, 47)
#>  146
```
4. Eugene says:

Nice to learn about another approach to anonymous functions. You might be interesting in the [nofrills](https://cran.r-project.org/package=nofrills) package. Compared to wrapr, it is far more specialized—it only concerns anonymous functions—but has some noteworthy differences: uses essentially the same syntax as the normal function declaration (but shorter), supports quasiquotation (the README explains why), and includes an operator that enables higher-order functions to interpret an even shorter function syntax (in the GitHub version).