6.1 Introduction

If you’re reading this book, you’ve probably already created many R functions and know how to use them to reduce duplication in your code. In this chapter, you’ll learn how to turn that informal, working knowledge into more rigorous, theoretical understanding. And while you’ll see some interesting tricks and techniques along the way, keep in mind that what you’ll learn here will be important for understanding the more advanced topics discussed later in the book.

Quiz

Answer the following questions to see if you can safely skip this chapter. You can find the answers in Section 6.9.

  1. What are the three components of a function?

  2. What does the following code return?

    x <- 10
    f1 <- function(x) {
      function() {
        x + 10
      }
    }
    f1(1)()
  3. How would you usually write this code?

    `+`(1, `*`(2, 3))
  4. How could you make this call easier to read?

    mean(, TRUE, x = c(1:10, NA))
  5. Does the following code throw an error when executed? Why or why not?

    f2 <- function(a, b) {
      a * 10
    }
    f2(10, stop("This is an error!"))
  6. What is an infix function? How do you write it? What’s a replacement function? How do you write it?

  7. How do you ensure that cleanup action occurs regardless of how a function exits?

Outline

  • Section 6.2 describes the basics of creating a function, the three main components of a function, and the exception to many function rules: primitive functions (which are implemented in C, not R).

  • Section 6.3 discusses the strengths and weaknesses of the three forms of function composition commonly used in R code.

  • Section 6.4 shows you how R finds the value associated with a given name, i.e. the rules of lexical scoping.

  • Section 6.5 is devoted to an important property of function arguments: they are only evaluated when used for the first time.

  • Section 6.6 discusses the special ... argument, which allows you to pass on extra arguments to another function.

  • Section 6.7 discusses the two primary ways that a function can exit, and how to define an exit handler, code that is run on exit, regardless of what triggers it.

  • Section 6.8 shows you the various ways in which R disguises ordinary function calls, and how you can use the standard prefix form to better understand what’s going on.