## 3.3 What a Function Returns

In this section we learn about return-values of functions.

### 3.3.1 The Final Expression Evaluated

Let’s write a small function to raise a number to a power:^{7}

```
<- function(x,y) {
pow ^y
x }
```

Check to see that it works:

`pow(2,3)`

`## [1] 8`

All seems well.

If we like we can assign the result of `pow()`

to some variable, for use later on:

```
<- pow(2,4)
a cat("I have", a, "cats.")
```

`## I have 16 cats.`

In computer programming parlance, `pow(x, y)`

is said to *return* the numerical value `x^y`

: `pow(2,3)`

returns 8, `pow(2,4)`

returns 16, and so on.

In R, what a function returns is: *the value of the final expression that it evaluates*. You can see this principle at work in the following example:

```
<- function(x) {
f 2*x + 3
45
"hello"
^2
x
}
f(4)
```

`## [1] 16`

We put in 4 as the argument for the parameter `x`

, but:

- we did not get back 11 (\(2 \times 4 +3\)),
- nor did we get back 45,
- nor did we get back the string “hello.”

When `f()`

was called, R evaluated all of the expressions in its body, but returned only the value of the final expression it evaluated: \(4^2 = 16\).

### 3.3.2 The `return()`

Function

R does have a special function to force a function to cease evaluation at a specific point. Its name, unsurprisingly, is `return()`

. Here is an example:

```
<- function(x) {
g <- 3*x +7
val return(val)
"Hello!"
}
g(1)
```

`## [1] 10`

We get \(3*1+7 = 10\), but we don’t get “Hello!” After returning the 10, the function stopped evaluating expressions: hence it never even bothered to evaluate “Hello,” much less to display it in the console.^{8}

It follows that it does not matter whether or not you wrap the final expression of a function in `return()`

. The following two functions do exactly the same thing:

```
<- function(x) x^2
f1 <- function(x) return(x^2) f2
```

Some people—especially those who are familiar with other programming languages where return statements are required—like to wrap the final expression in `return()`

, simply as a matter of clarity.

### 3.3.3 Writing a “Talky” Function

Suppose that you would like your function to raise a number to a power, returning the answer to the user, but you also want it to print out a message to the console. You might try writing your function like this:

```
<- function(x) {
talkySquare <- x^2
result
resultcat("The square of ", x, " is: ", result, ".\n", sep = "")
}
```

We try it out:

`talkySquare(4)`

`## The square of 4 is: 16.`

All seems well. But what if we want to save the result in a variable, so that we could perhaps add a number to it later? Something like this, perhaps:

`<- talkySquare(4) a `

`## The square of 4 is: 16.`

`+ 4 a `

`## numeric(0)`

The results don’t really make sense. What happened, of course is that R dutifully returned the value of the final expression in the function’s body—the result of the `cat()`

call, not the value of the variable `result`

. If we want both the print-out *and* the square to be returned, the we have to write our functions like this:

```
<- function(x) {
talkySquare <- x^2
result cat("The square of ", x, " is: ", result, ".\n", sep = "")
result }
```

This works out as expected:

`<- talkySquare(4) a `

`## The square of 4 is: 16.`

`+ 4 a `

`## [1] 20`

Well, maybe it doesn’t work *exactly* as we would like. It would nice if the function would talk to us only when we ask for the results in the console, not when we are simply assigning the results to a variable for later use. In Chapter 4 we will learn how to make our talky function keep quiet when we prefer silence.

### 3.3.4 The `print()`

Function

Consider the following function:

```
<- function(x) {
grumpySquare "OK, OK, I'm getting to it ... "
^2
x }
```

We know by now not to expect to see the grumpy message:

`grumpySquare(4)`

`## [1] 16`

If we want to see the message, we could wrap it in `cat()`

. Another possibility is to use the `print()`

function:

```
<- function(x) {
grumpySquare print("OK, OK, I'm getting to it ... ")
^2
x
}grumpySquare(4)
```

`## [1] "OK, OK, I'm getting to it ... "`

`## [1] 16`

When R executes a call to `print()`

it is forced to print something out to the console, even if it is in the midst of evaluating expressions in a function. The `print`

-statement is not involved in what the function returns—that’s all up to the final expression, the `x^2`

—but it does cause a result *outside of the function itself*. Any external result produced by a function (other than what the function returns) is called a *side-effect* of the function. `cat()`

and `print()`

are examples of functions that, when called inside of some other function, produce side-effects.

You should know that in R you have been calling the `print()`

function quite a bit, without even knowing it. Consider the following line of code:

`2+2`

`## [1] 4`

R evaluates the expression `2+2`

, arriving at the value 4. But what makes the `4`

appear on our console? Behind the scenes, R actually evaluated the expression

`print(2+2)`

That’s what got the 4 into the console! The fact is that whenever you make R evaluate an expression at “top level” (i.e., when you type the epxression into the Console) then R will call `print()`

to put the value of the expression into the Console so you can see it.

At this point we don’t use `print()`

explicitly very much—we just rely on R to call it for us when we are evaluating expressions at the console. Later on we will find that it has other uses.^{9}

### 3.3.5 Practice Exercises

What, if anything, does the following function return?

`<- function(n) { f cat("We have ", n, " dogs.\n", sep = "") }`

What, if anything, does the following function return?

`<- function(n) { g + 3 n "Hello" }`

What, if anything, does the following function return?

`<- function(n) { h "Hello" +3 n }`

### 3.3.6 Solutions to the Practice Exercises

Like any function,

`f()`

returns the value of the last expression that it evaluates. This time the final (and only) expression is the call to`cat()`

. But what does`cat()`

return? It turns out that`cat()`

always returns`NULL`

. You can see this in a couple of ways. One way is to store the result of a call to`f()`

in a variable, and then print the variable:`<- f(4) result`

`## We have 4 dogs.`

`result`

`## NULL`

`result`

got the value returned by the call`f(4)`

.`result`

turned out to be 4. Hence the call`f(4)`

must have returned`NULL`

.Another way to see this is to rewrie the function so as to force the final expression to return its result

*visibly*to the console. This is done by placing parentheses arund the expression, like this:`<- function(n) { f cat("We have ", n, " dogs.\n", sep = "")) ( }`

Now let’s call the functon:

`f(4)`

`## We have 4 dogs.`

`## NULL`

Yep, there’s

`NULL`

, visible in the Console!Well, let’s give it a try an see:

`<- g(4) result result`

`## [1] "Hello"`

Sure enough,

`g()`

returns the value of the last expression that it evaluates. In this case, it’s the expression`"Hello"`

.Like all functions,

`h()`

returns the value of the final expression that ti evaluates. Hence it will return three more than the value it was given for`n`

.

I know, I know—R already has the exponentiation operator. We just need an example to work with, here.↩︎

You might wonder why anyone would write a function that contains expressions after a call to

`return()`

. We’ll learn why in Chapter 4.↩︎R is one of very few major programming languages that engage in behind-the-scenes calls to a print function. In many other languages you have to call its print-function explicitly if you want the value of an expression to be displayed.↩︎