1.3 Designing Functions
Functions are an essential ingredient of all programs, large and small, and serve as our primary medium to express computational processes in a programming language. So far, we have discussed the formal properties of functions and how they are applied. We now turn to the topic of what makes a good function.
It is not enough that we know how to create a function. As programmers, we must make sure that our codes are still human-readable.
Fundamentally, the qualities of good functions all reinforce the idea that functions are abstractions.
Each function should have exactly one job. That job should be identifiable with a short name and characterisable in a single line of text. Functions that perform multiple jobs in sequence should be divided into multiple functions.
Don’t repeat yourself is a central tenet of software engineering. The so-called DRY principle states that multiple fragments of code should not describe redundant logic.
Here are some additional guidelines in designing functions.
1.3.1 Choosing Function and Parameter Names
Well-chosen function and parameter names are essential for the human interpretability of function definitions.
The interchangeability of names does not imply that formal parameter names do not matter at all.
The following are adapted from style guide for Python code.
Function names are lowercase, with words separated by underscores. Descriptive names are encouraged.
✗
Generate()
,estimate value()
,f()
,CalcTotPrice()
✓
fetch_user_data()
,generate_report_summary()
Function names typically evoke operations applied to arguments by the interpreter (e.g.,
print
,add
,square
) or the name of the quantity that results (e.g.,max
,abs
,sum
).Parameter names are lowercase, with words separated by underscores. Single-word names are preferred.
Parameter names should evoke the role of the parameter in the function, not just the kind of argument that is allowed.
Single letter parameter names are acceptable when their role is obvious, but avoid “
l
” (lowercase ell), “O
” (capital oh), or “I
” (capital i) to avoid confusion with numerals.
1.3.2 Documentation
When writing R programs, include documentation for all but the simplest functions. Remember, code is written only once, but often read many times.
Use Ctrl + Alt + Shift + R to insert a documentation skeleton. If it is not inserted inside the function, just cut and paste it.
pressure <- function(v, t, n){
#' Custom function for calculating pressure
#'
#' Applies the ideal gas law.
#' http://en.wikipedia.org/wiki/Ideal_gas_law
#'
#' Parameters
#'
#' @param v -- volume of gas, in cubic meters
#' @param t -- absolute temperature in degrees Kelvin
#' @param n -- particles of gas
k = 1.38e-23 # Boltzmann's constant
result <- n*k*t/v
return(result)
}
When writing R programs, include documentation for all but the simplest functions. Remember, code is written only once, but often read many times. Not only by computers, but by humans as well.
1.3.3 Default Argument Values
Use as few parameters as possible.
A consequence of defining general functions is the introduction of additional arguments. Functions with many arguments can be awkward to call and difficult to read.
In R, we can provide default values for the arguments of a function. When calling that function, arguments with default values are optional. If they are not provided, then the default value is bound to the formal parameter name instead.
For instance, if an application commonly computes pressure for one mole of particles, this value can be provided as a default.
pressure <- function(v, t, n=6.022e23){
#' Custom function for calculating pressure
#'
#' Applies the ideal gas law.
#' http://en.wikipedia.org/wiki/Ideal_gas_law
#'
#' Parameters
#'
#' @param v -- volume of gas, in cubic meters
#' @param t -- absolute temperature in degrees Kelvin
#' @param n -- particles of gas
k = 1.38e-23 # Boltzmann's constant
result <- n*k*t/v
return(result)
}
The =
symbol in the function statement header (i.e., this part: function(v, t, n=6.022e23)
, =
assigns a default value to n
.
We can call the function pressure
without defining what the value of particles of gas is.
## [1] 2269.975
Of course, we can override this value by defining the 3rd argument.
## [1] 6809.925
Practice Exercise
Using only arithmetic operations (+
, -
, *
, and /
) and the functions max
and min
, write a simple function that computes for the trimmed mean of five numbers if the sixth argument is equal to 1, and for the untrimmed mean if 0.
By default, the function should compute for the untrimmed mean.
The function should be named mean_5
that takes in six arguments. Then use the function mean_5
to find the untrimmed and trimmed mean of 2, 4, 20, 0, and -3. Include proper documentation.
Do not use conditional statements yet.
Hint: How does indicator functions work?
## [1] 4.6
## [1] 2