Functions and Expressions

Reading Assignments

Intro to Functions

  • Three components of a function:
    • body (= the lines of code with in braces)
    • arguments (= inputs of your function)
    • environment \(\Rightarrow\) Global Environment vs Execution Environment

Example 10.2.1

# future value function with default arguments
FV = function(pv = 100, r = 0.01, n = 1) {
  fv = pv * (1 + r)^n
  fv
}

# Execution
FV()
#> [1] 101

pv=200
FV(pv)
#> [1] 202

Expressions

Simple Expression vs Compound Expression

  • Simple expression are written with no braces (normally in one single line!).

Simple Expression Examples:

# Every line below is a simple expression

deposit = 1000 
deposit
#> [1] 1000
rate = 0.02 
rate
#> [1] 0.02
year = 3 
year
#> [1] 3
  • Compound expressions consist of simple expressions separated by newlines (or semicolons), and most importantly, grouped within braces.

Compound Expression Examples:

{
  deposit = 1000
  deposit
  rate = 0.02
  rate
  year = 3
  year
}
#> [1] 3
# Equivalently, 
{
  deposit = 1000; deposit; rate = 0.02; rate; year = 3; year
}
#> [1] 3

When to use compound expression?

Compound expression is typically used together with other programming structures (e.g. functions, conditionals, loops).

Example:

FV = function(pv = 100, r = 0.01, n = 1) {
  fv = pv * (1 + r)^n
  fv
}
calc_powers = function(x) {
  zero = x ^ 0
  one = x ^ 1
  two = x ^ 2
  three = x ^ 3
  c(zero, one, two, three)
}

How compound expression is run?

  • R runs everything inside of the compound expression as a single block of code.
  • Every expression in R has a value: the value of the last evaluated statement.
x <- {
  deposit = 1000
  deposit
  rate = 0.02
  rate
  year = 3
  year
}

x
#> [1] 3

Example: A function with compound expressions

calc_powers = function(x) {
  zero = x ^ 0
  one = x ^ 1
  two = x ^ 2
  three = x ^ 3
  c(zero, one, two, three)
  # OR, return(c(zero, one, two, three))
}
calc_powers(5)
#> [1]   1   5  25 125

The value of a function can be established in two ways:

  • As the last evaluated simple expression (in the body of the function)
  • An explicitly returned value via return()

Guess the output of the following codes:

RESULT <- calc_powers(5)
RESULT

zero
one
two
three

Results

RESULT <- calc_powers(5)
RESULT
#> [1]   1   5  25 125

zero # Function's local variables cannot be accessed by the global environment
#> Error in eval(expr, envir, enclos): object 'zero' not found
one # local variable
#> Error in eval(expr, envir, enclos): object 'one' not found
two  # local variable
#> Error in eval(expr, envir, enclos): object 'two' not found
three  # local variable
#> Error in eval(expr, envir, enclos): object 'three' not found

Revisit Example 10.2.1

# title: future value function
# description: computes future value using compounding interest
# inputs:
# - present: amount for present value
# - rate: annual rate of return (in decimal)
# - years: number of years
# output:
# - computed future value


# future value function with default arguments
FV = function(pv = 100, r = 0.01, n = 1) {
  fv = pv * (1 + r)^n
  return(fv) # It's recommended to use return()
}
# Execution
FV() # Default Execution using pv = 100, r = 0.01, n = 1
#> [1] 101


pv=200
FV(pv) # pv = 200, r = 0.01, n = 1
#> [1] 202
  • Steps to write a function:
    • Step 1: Start with a concrete example
    • Step 2: Make your code more generalizable
    • Step 3: Encapsulate the code into a function
    • Step 4: Test that the function works

The more complicated the function you write, the more crucial it is to follow the steps.