They allow us to re-use code instead of repeating it.
The more general the function, the more ways it can be reused
New feature changes only have to be made in one place—where the function is defined.
DRY
Don’t Repeat Yourself (DRY)
A principle of computer programming that holds that general solutions should be set forth in one place and usable in many places, and that information needed in many places should be defined authoritatively in one place.
Writing functions keeps your code DRY.
A Function is Like A Magic Hat
the function = the hat
manyCat
just the function there (no parentheses)
calling the function is like tapping the hat
manyCat(word = "Kentucky", n = 5)
parentheses make the call
then cool stuff happens! (e.g., rabbit comes out)
console output
Function Syntax
function is the reserved word in R that permits us to define functions.
The general form of a function definition is:
functionName <-function(parameter, parameter, ...) { Body of the Function ...}
name of function is an identifier
parameters in parentheses, separated by commas
body of function is the encapsulated code
it is enclosed in brackets
it uses the parameters
Definitions
Parameters of a Function
The parameters of a function (also called the formal arguments of the function) are the names that will be used in the body of the function to refer to the actual arguments supplied to the function when it is called.
Argument
An argument for a function is a value that is assigned to one of the parameters of the function.
Parameters vs. Arguments
manyCat(word ="Kansas", n =4)
Parameter
Argument
word
“Kansas”
n
4
The Body
Body of a Function
The body of a function is the code that is executed when the function is called.
In R, when the body consists of more than one expression then it appears inside of curly braces.
No Need For Brackets …
… if the body is just one expression:
In the Call, Parameters Need Not Be Named ….
… as long as you keep in mind the order.
These calls all do the same thing:
manyCat(word ="Hello", n =4)manyCat(word ="Hello", 4)manyCat("Hello", n =4)manyCat("Hello", 4)manyCat(n =4, word ="Hello")
But This is Wrong (Why?)
The Problem Was …
… that R thought:
word is 4
n is “Hello”
Practice
What would happen if you run this code?
Why?
Advice for Writing Functions
Go Slow
DON’T:
just start typing code
DO:
read the specifications carefully
break up your work into small steps
Suggested Procedure
Break your work into five steps:
Read the specifications carefully.
Write a program that performs the stated task, for a specific example. If necessary, revise your program until it is fully general.
Encapsulate your work into a function.
Test the function on a few examples.
Read the specifications again. If necessary, revise the code for the function until it meets all specifications, and test again.
Problem: A Scrambler
Write a function called scramble() that takes a given vector and returns a vector consisting of all the odd-numbered elements in front of all of the even-numbered elements.
The function should tke a single parameter called vec, the vector to be scrambled.
Just changing vec to the desired input was not enough!
Our solution won’t work unless vec has length 6.
Step 2: Back to the Drawing Board
We need a program that works for a vector of any length.
Let’s make a name for the length:
n <-length(vec)
Think About Indices More Generally
Construct the odd indices:
oddIndices <-seq(1, n, by =2)oddIndices
[1] 1 3 5 7
Construct the even indices:
evenIndices <-seq(2, n, by =2)evenIndices
[1] 2 4 6
Step 2: Still Thinking Generally About Indices
All of the indices:
allIndices <-c(oddIndices, evenIndices)allIndices
[1] 1 3 5 7 2 4 6
Now select, based on all of the indices:
vec[allIndices]
[1] "the" "is" "my" "tree" "cat" "in" "elm"
Step 2: Our Second Stab at It
So it seems this program will work (try it):
If the program REALLY works, it will work for a different example just by changing vec.
Step 2: Checking …
So let’s change vec and see:
Looking good!
Step 3: Encapsulate Into a Function
Encapsulate your work into a function.
The function-skeleton is this:
scramble <-function(vec) {## the "work" involving parameter goes here}
Step 3: Encapsulate Your Work
Run this code:
You encapsulated all of the “work” (except the first line that defined vec).
Step 4: Test on a Few Examples
Test the function on a few examples.
Step 5: Read the Specs Again
Read the specifications again. If necessary, revise the code for the function until it meets all specifications, and test again.
OK, let’s do that …
Write a function called scramble() that takes a given vector and returns a vector consisting of all the odd-numbered elements in front of all of the even-numbered elements.
The function should tke a single parameter called vec, the vector to be scrambled.