Returning Functions
Part of the Logic & Flow section of Coddy's R journey. Lesson 29 of 64.
A function can also return a function. make_multiplier(3) returns a new function that multiplies its argument by 3:
make_multiplier <- function(n) {
function(x) x * n
}
triple <- make_multiplier(3)
print(triple(5))
print(make_multiplier(10)(5))Output:
[1] 15
[1] 50The returned function remembers the values it was built with. This combination of a function and the variables around it is called a closure. Each call of the maker builds a separate closure:
make_greeter <- function(greeting) {
function(name) paste0(greeting, ", ", name, "!")
}
hello <- make_greeter("Hello")
hola <- make_greeter("Hola")
print(hello("Ada"))
print(hola("Ada"))Output:
[1] "Hello, Ada!"
[1] "Hola, Ada!"A maker function turns a few settings into a ready-made tool, for example a converter between units:
make_converter <- function(factor, offset = 0) {
function(x) x * factor + offset
}
c_to_f <- make_converter(1.8, 32)
km_to_miles <- make_converter(0.621)
print(c_to_f(100))
print(km_to_miles(10))Output:
[1] 212
[1] 6.21Functions can be combined into new functions. compose(f, g) returns a function that runs f and then g:
compose <- function(f, g) function(x) g(f(x))
clean <- compose(trimws, toupper)
print(clean(" hi there "))Output:
[1] "HI THERE"Challenge
EasyComplete make_formatter(prefix, digits). It returns a function that takes a number and returns prefix followed by the number with digits decimals: make_formatter("$", 2)(3.5) returns $3.50.
sprintf("%.*f", digits, x) formats x with digits decimals.
The supplied code reads the prefix, the number of decimals and a comma-separated list of numbers. It builds one formatter and prints its result for each number.
Try it yourself
make_formatter <- function(prefix, digits) {
# Write your code here
function(x) ""
}
# Supplied input/output code: keep it as it is
input <- suppressWarnings(readLines(file("stdin")))
fmt <- make_formatter(input[1], as.integer(input[2]))
for (x in as.numeric(strsplit(input[3], ",")[[1]])) cat(fmt(x), "\n", sep = "")
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Logic & Flow
1Strings In Depth
Substrings with substr()Formatting with sprintf()Splitting and JoiningSearching StringsReplacing TextRecap - Username Builder4Matrices
Creating MatricesIndexing MatricesRow and Column SummariesMatrix ArithmeticRecap - Seating Chart2Key-Value Lookups
Named Vector LookupsChecking KeysAdding and Removing KeysLooping Over NamesRecap - Stock Desk3Sets and Counting
Unique ValuesSet OperationsMembership TestsCounting with table()Recap - Event Guests6Functions as Values
Anonymous FunctionsPassing FunctionsReturning FunctionsClosures with StateRecap - Discount Rules9Data Frames
Creating Data FramesColumns and RowsFiltering RowsAdding and SortingRecap - Sales Report12Project - Expense Tracker
Recording ExpensesTotal SpendingPractice on your own: Online R compiler