Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/dirkschumacher/defmacro
Load Time R Package Macros
https://github.com/dirkschumacher/defmacro
Last synced: 23 days ago
JSON representation
Load Time R Package Macros
- Host: GitHub
- URL: https://github.com/dirkschumacher/defmacro
- Owner: dirkschumacher
- License: other
- Created: 2019-09-14T22:03:39.000Z (about 5 years ago)
- Default Branch: master
- Last Pushed: 2022-10-16T13:21:06.000Z (about 2 years ago)
- Last Synced: 2024-08-13T07:15:32.945Z (4 months ago)
- Language: R
- Homepage:
- Size: 28.3 KB
- Stars: 35
- Watchers: 4
- Forks: 2
- Open Issues: 3
-
Metadata Files:
- Readme: README.Rmd
- License: LICENSE
Awesome Lists containing this project
- jimsghstars - dirkschumacher/defmacro - Load Time R Package Macros (R)
README
---
output: github_document
---```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "100%"
)
```
# defmacro[![Lifecycle: experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://lifecycle.r-lib.org/articles/stages.html#experimental)
[![Codecov test coverage](https://codecov.io/gh/dirkschumacher/defmacro/branch/master/graph/badge.svg)](https://app.codecov.io/gh/dirkschumacher/defmacro?branch=master)
[![CRAN status](https://www.r-pkg.org/badges/version/defmacro)](https://CRAN.R-project.org/package=defmacro)
[![R-CMD-check](https://github.com/dirkschumacher/defmacro/workflows/R-CMD-check/badge.svg)](https://github.com/dirkschumacher/defmacro/actions)The goal of `defmacro` is to experiment with compile time macros in R.
The idea is to add a macro expansion step during the `.onLoad` step of the package.A macro is a function that takes code and returns code.
An example package is [here](https://github.com/dirkschumacher/defmacroex).
## Example
For example in a package you define a macro that evaluates an expression at "compile time":
```{r, eval=TRUE}
constexpr <- defmacro::defmacro(function(expr) {
eval(expr)
})
```Then you might have a regular function that tests if a value exceeds a quantile of the standard normal distribtion:
```{r}
is_invalid <- function(value) {
value > constexpr(qnorm(0.975))
}
```After macro expansion during `.onLoad` the following function is exported to the user:
```{r}
defmacro::expand_function(is_invalid)
```Thus the call to `qnorm` never happens at runtime as it could have been evaluated during package load.
You could also define your own piping function and have all the overhead removed during runtime:
```{r}
`%>%` <- defmacro::defmacro(function(lhs, rhs) {
fun_args <- c(list(lhs), unlist(as.list(rhs[-1L]), FALSE))
rlang::get_expr(rlang::quo(`!!`(rhs[[1L]])(!!!(fun_args))))
})
``````{r}
analyze_dataset <- function(data) {
data %>%
dplyr::filter(hp > constexpr(50 + 50)) %>%
dplyr::group_by(cyl) %>%
dplyr::summarise(dplyr::n())
}
``````{r}
defmacro::expand_function(analyze_dataset)
```This can also be used to elide parts of your code, akin to `#if` in C:
```{r}
dash_if <- defmacro::defmacro(function(code, condition) {
if (condition) code
})
``````{r}
conditional <- function() {
dash_if(kept(), TRUE)
dash_if(removed(), FALSE)
}
``````{r}
defmacro::expand_function(conditional)
```## Related packages
* [debugme](https://github.com/r-lib/debugme) - Easy and efficient debugging for R packages