forked from hadley/adv-r
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMeta.Rmd
45 lines (33 loc) · 3.89 KB
/
Meta.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# (PART) Metaprogramming {-}
# Introduction {.unnumbered}
```{r, include = FALSE}
source("common.R")
```
\index{metaprogramming}
\index{non-standard evaluation}
One of the most intriguing things about R is its capability for __metaprogramming__: the idea that code is itself data, and can be inspected and modified programmatically. This is a powerful idea and deeply influences much R code. At a simple level it allows you to write `library(purrr)` instead of `library("purrr")` and enables `plot(x, sin(x))` to label the axes with `x` and `sin(x)`. At a deeper level it allows `y ~ x1 + x2` to represent a model that predicts the value of `y` from `x1` and `x2`, `subset(df, x == y)` to be translated to `df[df$x == df$y, , drop = FALSE]`, and `dplyr::filter(db, is.na(x))` to generate the SQL `WHERE x IS NULL` when `db` is a remote database table.
Closely related to metaprogramming is __non-standard evaluation__, or NSE for short. This term is commonly used to describe the behaviour of R functions, but there are two problems with it. Firstly, NSE is actually a property of an argument (or arguments) of a function, so talking about NSE functions is a little sloppy. Secondly, it's confusing to define something by what it is not (standard), so in this book I'll teach you more precise vocabulary.
Specifically, this book focuses on tidy evaluation (sometimes called tidy eval for short). Tidy evaluation is implemented in the rlang package [@rlang], and I'll use rlang extensively in these chapters. This will allow you to focus on the big ideas, without being distracted by implementation quirks that arise from R's history. After I introduce each big idea with rlang, I'll then circle back to talk about how those ideas are expressed in base R. This approach seems backward to some, but it's analogous to learning how to drive an automatic transmission before a manual one so you can focus on the big picture before learning the details. This book focusses on the theoretical side of tidy evaluation, so you can fully understand how it works from the ground up. If you are looking for a practical introduction, I recommend the "tidy evaluation book", <https://tidyeval.tidyverse.org>[^tidyeval-wip].
[^tidyeval-wip]: The tidy evaluation book is a work-in-progress at the time I wrote this chapter, but will hopefully be finished by the time you read it.
You'll learn about metaprogramming and tidy evaluation in the following five chapters:
* In __Big picture__, Chapter \@ref(meta-big-picture), you'll get a glimpse of
the whole metaprogramming story, briefly learning about each of the major
components and how they fit together into a cohesive whole.
* In __Expressions__, Chapter \@ref(expressions), you'll learn that all R code
can be described as a tree. You'll learn how to visualise that tree, how the
rules of R's grammar convert linear sequences of characters into a tree, and
how to use recursive functions to work with code trees.
* In __Quasiquotation__, Chapter \@ref(quasiquotation), you'll learn to use
tools from rlang to capture ("quote") unevaluated function arguments. You'll
also learn about quasiquotation, which provides a set of techniques for
"unquoting" input that makes it possible to easily generate new trees from
code fragments.
* In __Evaluation__, Chapter \@ref(evaluation), you'll learn how to evaluate
captured code. Here you'll learn about an important data structure, the
__quosure__, which ensures correct evaluation by capturing both the code
to evaluate, and the environment in which to evaluate it. This chapter will
show you how to put all the pieces together to understand how NSE in base
R works, and how to write your own functions that work like `subset()`.
* Finally, in __Translating R code__, Chapter \@ref(translation), you'll see
how to combine first-class environments, lexical scoping, and metaprogramming
to translate R code into other languages, namely HTML and LaTeX.