This is a build of R that adds an experimental pipe assignment operator <|>.
LHS <|> RHS is parsed as LHS <- RHS(LHS, ...).
x <|> sqrt() # becomes x <- sqrt(x)
x[item] <|> foo() # becomes x[item] <- foo(x[item])
x$elem <|> foo() # becomes x$elem <- foo(x$elem)
names(x) <|> toupper() # becomes names(x) <- toupper(names(x))
x <|> gsub("pattern", "replacement", x = _)
# becomes x <- gsub("pattern", "replacement", x = x)Arbitrarily complex left hand sides are allowed, including assignment functions and subassignment.
Chaining <|> is not allowed (and would not make sense).
For a detailed rationale, see https://hughjonesd.github.io/case-for-pipe-assignment.html.
The skinny:
- R is pass-by-value and allows complex subassignment
- Often we want to simply pass variables, or parts of them, through a function
- Doing this involves repeating oneself
In other words, it would be nice to write
names(x)[1:5] <|> toupper()instead of
names(x)[1:5] <- toupper(names(x)[1:5])and
my_data[rows, cols] <|> as.numeric()instead of
my_data[rows, cols] <- as.numeric(my_data[rows, cols])You can build this version from github source using the build-R.sh script. Alternatively, if you have an existing R source tree, you can apply the provided patch:
cd /path/to/r-source
patch -p1 < pipe-assignment-operator.patchThe patch file pipe-assignment-operator.patch modifies:
src/main/gram.y- Grammar file with pipe assignment operatorsrc/main/gram.c- Generated parser (regenerated from gram.y)tests/reg-tests-pipe-assign.R- Test suite for the operator
Afterwards, build R as usual (see the wch/r-source wiki for build instructions from github).
Yeah, this was vibe-coded! Claude basically one-shotted the Yacc, which is much beyond my capability.