11.1 Introduction

In this chapter, you’ll learn about function operators. A function operator is a function that takes one (or more) functions as input and returns a function as output. The following code shows a simple function operator, chatty(). It wraps a function, making a new function that prints out its first argument. You might create a function like this because it gives you a window to see how functionals, like map_int(), work.

chatty <- function(f) {
  function(x, ...) {
    res <- f(x, ...)
    cat("Processing ", x, "\n", sep = "")
f <- function(x) x ^ 2
s <- c(3, 2, 1)

purrr::map_dbl(s, chatty(f))
#> Processing 3
#> Processing 2
#> Processing 1
#> [1] 9 4 1

Function operators are closely related to function factories; indeed they’re just a function factory that takes a function as input. Like factories, there’s nothing you can’t do without them, but they often allow you to factor out complexity in order to make your code more readable and reusable.

Function operators are typically paired with functionals. If you’re using a for-loop, there’s rarely a reason to use a function operator, as it will make your code more complex for little gain.

If you’re familiar with Python, decorators is just another name for function operators.


  • Section 11.2 introduces you to two extremely useful existing function operators, and shows you how to use them to solve real problems.

  • Section 11.3 works through a problem amenable to solution with function operators: downloading many web pages.


Function operators are a type of function factory, so make sure you’re familiar with at least Section 6.2 before you go on.

We’ll use purrr for a couple of functionals that you learned about in Chapter 9, and some function operators that you’ll learn about below. We’ll also use the memoise package (Wickham et al. 2018) for the memoise() operator.



Wickham, Hadley, Jim Hester, Kirill Müller, and Daniel Cook. 2018. Memoise: Memoisation of Functions. https://github.com/r-lib/memoise.