forked from hadley/adv-r
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Meta.Rmd
44 lines (32 loc) · 3.92 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
# (PART) Metaprogramming {-}
# Introduction {#metaprogramming .unnumbered}
```{r, include = FALSE}
source("common.R")
```
\index{metaprogramming}
\index{non-standard evaluation}
One of the most intriguing things about R is its ability to do __metaprogramming__. This is the idea that code is data that can be inspected and modified programmatically. This is a powerful idea; one that deeply influences much R code. At the most basic level, it allows you to do things like write `library(purrr)` instead of `library("purrr")` and enable `plot(x, sin(x))` to automatically label the axes with `x` and `sin(x)`. At a deeper level, it allows you to do things like use `y ~ x1 + x2` to represent a model that predicts the value of `y` from `x1` and `x2`, to translate `subset(df, x == y)` into `df[df$x == df$y, , drop = FALSE]`, and to use `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__, NSE for short. This term, which is commonly used to describe the behaviour of R functions, is problematic in two ways. Firstly, NSE is actually a property of the 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's not (standard), so in this book I'll introduce 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 the quirks of implementation 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 may seem backward to some, but it's like learning how to drive using an automatic transmission rather than a stick shift: it allows you to focus on the big picture before having to learn 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 more practical introduction, I recommend the tidy evaluation book at <https://tidyeval.tidyverse.org>[^tidyeval-wip].
[^tidyeval-wip]: As I write this chapter, the tidy evaluation book is still a work-in-progress, but by the time you read this it will hopefully be finished.
You'll learn about metaprogramming and tidy evaluation in the following five chapters:
1. Chapter \@ref(meta-big-picture) gives a high level description of the whole
metaprogramming story, briefly learning about all major components
and how they fit together to form a cohesive whole.
1. Chapter \@ref(expressions) shows that all R code can be described as a
tree. You'll learn how to visualise these trees, how the rules of R's
grammar convert linear sequences of characters into these trees, and how to
use recursive functions to work with code trees.
1. Chapter \@ref(quasiquotation) presents tools from rlang that you can use to
capture (quote) unevaluated function arguments. You'll also learn about
quasiquotation, which provides a set of techniques to unquote input to make
it possible to easily generate new trees from code fragments.
1. Chapter \@ref(evaluation) moves on to evaluating 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 works in base R, and how to
write functions that work like `subset()`.
1. Chapter \@ref(translation) finishes up by combining first-class environments, lexical
scoping, and metaprogramming to translate R code into other languages,
namely HTML and LaTeX.