Chapter 11 Function operators

11.1 Introduction

A function operator is a function that takes one (or more) functions as input and returns a function as output

…How exactly does this definition differ from a function factory?

Term Required Input Optional Input Output
Functionals Function Vector Vector
Function Factory NA Vector,Function Function
Function Operator Function Function Function

Function operators are closely related to function factories; indeed they’re just a function factory that takes a function as input

Can anyone confirm that, by definition, function operators can only take functions as inputs (and not any kind of vector)? Book quote: “A function operator is a function that takes one (or more) functions as input and returns a function as output.” If this is true, then something like the following would only be a function factory, not both a function factory and a function operator:

## Sleeping for 1.5 seconds.
## [1] "hello world"

Function factories are “any function that returns a function” and Hadley uses “simple” examples where you pass in a numeric or character to get back a customized function (pass a number to a power function to get a function dedicated to cubes)

Function operators are factories where you pass in a function and modify its behaviour a little, without actually building up the logic for a function from scratch. The operator does not supply the actual meat of the logic. examples: safely, silently, rate-limity etc

11.2.1 purrr::safely

It seems like safely is a condition wrapper - are all conditions a kind of function operator?

safely/possibly/quietly are function operators that are condition-wrappers, but tryCatch/withCallingHandlers are not function operators (they catch the outputs and do X thing but don’t actually return a function)

How would we apply safely to find which dataframe in a list of dataframes is causing an error?

## Warning in is.data.frame(y): restarting interrupted promise evaluation

## Warning in is.data.frame(y): restarting interrupted promise evaluation

## Warning in is.data.frame(y): restarting interrupted promise evaluation
## $result
## data frame with 0 columns and 0 rows
## 
## $error
## $error$a
## <simpleError in is.data.frame(y): object 'filter_starwars' not found>
## 
## $error$b
## <simpleError in is.data.frame(y): object 'filter_starwars' not found>
## 
## $error$c
## <simpleError in is.data.frame(y): object 'filter_starwars' not found>
## 
## $error$d
## <simpleError in is.data.frame(y): object 'filter_starwars' not found>

11.2.2 memoise

How do you check how much memory is allocated to memoise’s caching?

## 16,232 B

Could we create a memoise wrapper that clears the cache when that’s a certain number?

## 14,472 B
## 15,392 B
## 16,280 B
## 17,176 B
## 18,080 B
## 18,920 B
## 19,760 B
## 20,672 B
## 21,576 B
## 22,408 B
## 23,240 B
## 24,080 B
## 24,920 B
## 25,816 B
## 26,592 B
## 27,488 B
## 28,264 B
## 29,032 B
## 29,864 B
## 30,776 B
## Clearing cache [@30776]
## 14,432 B
## 15,344 B
## 16,232 B
## 17,136 B
## 17,968 B
## 18,808 B
## 19,704 B
## 20,624 B
## 21,464 B
## 22,240 B
## 23,136 B
## 23,912 B
## 24,752 B
## 25,528 B
## 26,320 B
## 27,176 B
## 27,952 B
## 28,728 B
## 29,504 B
## 30,344 B
## Clearing cache [@30344]
## 14,432 B
## 15,344 B
## 16,184 B
## 17,088 B
## 17,928 B
## 18,784 B
## 19,624 B
## 20,464 B
## 21,352 B
## 22,256 B
## 23,088 B
## 23,984 B
## 24,760 B
## 25,680 B
## 26,520 B
## 27,408 B
## 28,184 B
## 29,056 B
## 29,896 B
## 30,736 B
## Clearing cache [@30736]
## 14,432 B
## 15,328 B
## 16,240 B
## 17,080 B
## 18,000 B
## 18,896 B
## 19,720 B
## 20,560 B
## 21,456 B
## 22,312 B
## 23,152 B
## 23,992 B
## 24,824 B
## 25,600 B
## 26,368 B
## 27,200 B
## 28,104 B
## 28,816 B
## 29,656 B
## 30,544 B
## Clearing cache [@30544]
## 14,424 B
## 15,320 B
## 16,232 B
## 17,152 B
## 18,048 B
## 18,920 B
## 19,752 B
## 20,584 B
## 21,424 B
## 22,136 B
## 22,976 B
## 23,752 B
## 24,584 B
## 25,424 B
## 26,200 B
## 27,040 B
## 27,952 B
## 28,792 B
## 29,632 B
## 30,536 B

Can we come up with simple example for these function operators?

possibly

## [1] 1.394 1.272 2.170    NA

quietly

Quetly doesn’t work on errors, only warnings:

11.2.3.1 Exercises

Vectorize() provides a convenient and concise notation to iterate over multiple arguments, but has some major drawbacks that mean you generally shouldn’t use it.

What are these drawbacks the solution manual is referring to?

11.0.0.2 Jim’s Way

  1. SIMPLIFY logical or character string; attempt to reduce the result to a vector, matrix or higher dimensional array; see the simplify argument of sapply. This means the type of the function output depends on the input.
## some/path/abc/001.txt 
##         "abc_001.txt"
## named list()
## list()
  1. Vectorize does not generate functions with easily inspect-able code
  2. Vectorize functions use do.call(), which can have unexpected performance consequences
  3. Vectorize does not actually make your code execute faster