Lesson 16: Functions with Return Values
Overview
In this lesson students are introduced to the return command and learn to write their own functions that return values. Students first complete a simple unplugged activity based on the game Go Fish to introduce the concept of a return value. They will then complete a short sequence of exercises in Code Studio, which introduces preferred patterns for writing functions that return values. At the end of the sequence, students write and use functions that return values in a simple turtle driver app.
Purpose
The ability to return values is closely tied to the concept of scope. All variables declared within a function are in local scope and so will be removed once the end of the function is reached. As a result any useful information generated during that function will be lost. One solution to this problem is storing the value in a global variable, but this is generally considered bad programming practice. Global variables can be accessed by many functions and so reasoning about their logic requires considering the logic of all of those functions. Return values are a way to move information out of the local scope of a function without using a global variable. As a result a function call can be treated as if it were the type of data that a function returns, and it is up to the programmer to determine if or how it will be used.
Agenda
Getting Started (20 minutes)
Activity (25 minutes)
Wrap-up (5 minutes)
View on Code Studio
Objectives
Students will be able to:
- Use the return command to design functions.
- Identify instances when a function with a return value can be used to contain frequently used computations within a program.
- Design functions that return values to perform frequently needed computations within a program.
Links
Heads Up! Please make a copy of any documents you plan to share with students.
For the Students
- Activity Guide - Return Values with Go Fish - Activity Guide
Vocabulary
- Return Value - A value sent back by a function to the place in the code where the function was called from - typically asking for value (e.g. getText(id)) or the result of a calculation or computation of some kind. Most programming languages have many built-in functions that return values, but you can also write your own.
Introduced Code
Teaching Guide
Getting Started (20 minutes)
Unplugged Activity: Return Values with Go Fish
Goal
Introduce the idea of a function with a return value as a process in which a question is asked, something computes an answer and gives the answer back to the asking location. We are looking to draw out the need for some way to share the information between the two parts of the program.
Teaching Tip
Students’ algorithms will vary. An example of what they might create is: function responder(desiredCard)
- var gaveCard = false
- for each card in responder’s hand
- if card is equal to desiredCard
- gaveCard = true
- RETURN card
- if card is equal to desiredCard
- if gaveCard is false
- RETURN “Go Fish”
Although technically this first example is not how you would write this with code, as the return statement would cause you to leave the function, it gets across the main understanding we are working towards.Therefore, it is a completely correct way for students to be thinking at this point. You should not feel the need to correct this understanding before students work on the levels, but if you are wondering about more correct versions of this algorithm, check out below. A more correct version of this algorithm would be: function responder(desiredCard)
- var cardsToGive = []
- for each card in responder’s hand
- if card is equal to desiredCard
- add card to cardsToGive list
- if card is equal to desiredCard
- if cardsToGive length is 0
- RETURN “Go Fish”
- else
- RETURN cardsToGive
The above algorithm is good, as it will return at the end of the computation and therefore could be something you could use to translate into code. However, it is usually best practice to always return the same type of information. “Go Fish” is a string, whereas cardsToGive is an array.
Even better would be:
function responder(desiredCard)
- var cardsToGive = []
- for each card in responder’s hand
- if card is equal to desiredCard
- add card to cardsToGive list
- if card is equal to desiredCard
- RETURN cardsToGive
Opening:
Remarks
Today we are going to look at how to write our own functions with return values. We are going to explore this idea by playing the classic card game Go Fish.
Distribute: Activity Guide - Return Values with Go Fish - Activity Guide
- Break students into groups of 4 with a set of cards.
- Give each student a copy of the worksheet.
- Each group should play a couple rounds of Go Fish with their team.
- They do not need to finish the game to get the point here.
- Students should complete the worksheet together as a group.
Share:
Have students share their algorithms for the Responder.
- The main goal here is for students to talk about the parameters for the function, the algorithm used in the function and, most important, the information that needs to be returned at the end of the function.
Discussion Prompt:
- "Why do we need to return some information from the Responder to the Asker?"
The main thing to draw out:
- Once the asker has gained the information, he uses it to continue computing information.
- The asker can not easily gain the information without the help of the responder, as he doesn’t have access to the cards.
Transitional Remarks
As we saw playing Go Fish, we often need to ask for information and receive an answer to be able to make decisions. We have seen a few different functions that do something like this, such as randomNumber, getText, and includes. Up until now, though, we have never been able to create our own functions that return information. Today we are going to learn how to write functions with return values.
Activity (25 minutes)
App Lab: Functions with Return Values
Wrap-up (5 minutes)
Exit ticket: Function with Returns vs. Functions without Returns
Goal
Highlight the benefits of using a function that returns a value, in particular the fact that it makes it much easier to reason about a program.
Remarks
Return values are a useful way to move useful information generated inside of a function to the rest of your program. There is another way we can do this. If we write our function so that it stores its output within a global variable, then that information will be accessible when the function terminates, since the global variable will stay in scope.
Prompt:
- "Why would we prefer to write a function that returns a value to using the strategy shown above? How might return values make our function more generally useful? How might they make our code easier to reason about?"
Discuss:
Ask students to share their responses to this question. They may need to be reminded about the concept of variable scope. The primary points to pull out are:
- A function that saves output in a global variable must specifically reference that variable by name. Since that name is “hard-coded,” your function can only ever save information in that variable. If we wish for our functions to be generally useful, we should be able to decide how to use the output a function generates.
- A global variable is accessible by all functions. As a result, it can be difficult to determine every location in your program that modifies this variable. Reasoning about how its value will change over the course of the program is much harder, as is debugging unexpected behavior. Using a return value limits the effects of a function to the local variables of the function and the place where the function was called.
- Lesson Overview
- Teacher Overview
- Student Overview
- The Return Command
- 2
Student Instructions
Using Output from Functions
We already know that parameters provide input values to our functions. It is also possible for functions to generate output values which can be used to change the logical flow of the program.
We have already seen many examples of functions that generate output, including:
randomNumber
includes
promptNum
getText
toUpperCase
toLowerCase
You may not have thought of it at the time, but when you called these functions you treated them as if they were a value. In reality you were using the value returned by these functions.
Examples of Return Functions Used as Values
Using the randomNumber
function as a number
Using the getText
function as a string
Let's have a look at how we can write functions like this ourselves.
The return Command
When you call a function, you are telling the computer to run a piece of code elsewhere in your program. When that function is finished running, execution of the program returns to the point in the code where the function was called. In some programming languages you must explicitly tell the program to return at the end of a function, but in JavaScript this just happens automatically when you reach the closing }
of your function.
It is possible to make your program return at any point using the return
command. This command tells the function to stop executing immediately, skipping any commands that appear afterwards within the function. This example shows how a console.log
statement after a return
is never executed. It will even generate a warning in your program.
Most of the time we want every line of our functions to run, and so we wouldn't write functions with commands after a return
statement. If we had ever used return
, it would have been as the last line in our functions, and since reaching the closing curly brace will automatically do the same thing as a return
command, there's been no reason to use it at all.
Returning Values
There is one critical difference between reaching the last line of your function and using return
. When you use return
you are also able to specify a single value that will be "returned" to whatever code called the function in the first place. The effect is that the function acts like any expression that evaluates to a single value. You can think of it as though the value simply replaces the function where it was called in the code.
When your function is done executing it will be replaced by whatever value you return, just like randomNumber
is replaced by a randomly generated number and getText
is replaced by the text of one of your UI elements. This is how your functions can generate output that other parts of your program can use.
Notice that we need to place our new function inside of a console.log
statement in order to display the value it returned. Without this statement, the value would be calculated, but it would not be used anywhere in your program. This is no different than if you were to call randomNumber
and not use the value generated. It is up to you, the programmer, to decide how this returned value will be used in the rest of your program.
You will typically write a function that returns a value when you have a calculation that you perform many times in your code (for example, finding the minimum value in an array). Your function would use parameters to provide inputs, would calculate a result, and would return that result as output. To help you get started writing your own functions that return values, here are some simple guidelines to follow.
Guidelines for Writing Functions with Return Values
- Decide what values you need as input to your computation. Make these parameters of your function.
- Use your parameters to calculate your result and save that result in a single variable.
- Return that variable on the last line of your function.
- Using minVal
- 3
Student Instructions
Using Functions that Return Values
We have used functions that return values many times before, but in this exercise you will see how they are actually created by using the return
command. The function minVal
accepts two numbers as input and returns the minimum of the two as output. You can call this function just like any other, and because it returns a number, you can treat the function call as if it were a number.
Do This:
- Starter code has been provided that creates the function
minVal
and generates two random values. - Inspect the code of
minVal
to understand the logic of this function. - On the
console.log
line call the function usingrand1
andrand2
as parameters and ensure the minimum value is returned. You should treat the function call as if it were a number.
- Check that the program generates output similar to the output shown below.
Student Instructions
Writing Functions that Return Values
Now you are going to write your own function that returns a value, maxVal
. This function should return the maximum of two values provided as input. The code for minVal
is provided so that you can replicate the pattern used in this function.
Pattern for Functions that Return Values Use parameters to provide input. Declare a variable that will be used as output, possibly initializing its value. Update the value in your output variable throughout your program. Return your output variable on the last line of your function.
You may actually recognize many similarities between how we wrote functions that process arrays and functions that return values. These patterns aren't rules of programming, but they help make your code easy to read and understand.
Do This:
- Starter code has been provided which stubs out
maxVal
and generates two random values.minVal
is still provided so that you can replicate the pattern used. - Write
maxVal
, replicating the pattern used to writeminVal
. - Use
maxVal
within theconsole.log
statement as if it were a number to generate the output similar to the one shown below.
Student Instructions
Debugging and Multiple Return Statements
Having multiple return
statements in a program can lead to tricky situations. You may use multiple return statements, but it makes it easier to introduce logical errors into your program. We're going to look at some examples of functions with return values that include logical errors and debug them. The goal is to recognize common errors with return values now so you can avoid them when writing your own programs.
There is a logical error somewhere in the version of maxVal
you are about to see which uses multiple return statements. As a result, the function works correctly for some inputs but not all. You'll need to inspect the code to understand what the issue is and make changes accordingly. In particular, look closely for conditions that are not currently handled by the program.
Do This:
- Run the program and identify the errors generated in the output.
- Inspect the logic of
maxVal
to identify the logical error. - Correct the logical error so that the function returns the correct value for all inputs.
Student Instructions
Debugging and Multiple Return Statements: constrain
We're going to debug another function that uses multiple return statements. The function is called constrain
and is used to limit an input number to a certain range. The function accepts three parameters.
input
: the number to be constrained.low
: the lower bound of the range. Ifinput
is below this value, the function should return the value oflow
.high
: the upper bound of the range. Ifinput
is above this value, the function should return the value ofhigh
.
Click for sample input and output for constrain
constrain(15,10,20)
should return 15 since it is within the range of 10 to 20.
constrain(5,10,20)
should return 10 since the input is below the range of 10 to 20.
constrain(25,10,20)
should return 20 since the input is above the range of 10 to 20.
Unfortunately, because of the way this function was written, it does not always work as expected. In particular, because of how
return
was used, some portions of the function never run. Change the structure of the function to use the pattern you have been shown in previous exercises, included below.
Pattern for Functions that Return Values Use parameters to provide input. Declare a variable that will be used as output, possibly initializing its value. Update the value in your output variable throughout your program. * Return your output variable on the last line of your function.
Do This:
- Run the program and identify the errors generated in the output.
- Inspect the logic of
constrain
to identify the logical errors. - Rewrite
constrain
to make use of the pattern for functions that return values, shown above. - Run the program to ensure it is now running as you expect.
Student Instructions
Use a Function that Returns a Value in an App
We create functions to contain blocks of code that will be used multiple times within our program. The same is true with functions that return values. Let's see an example of how we might use one of the functions we've written.
This exercise comes with starter code that creates a simple turtle driver app. The x and y location of the turtle are stored in the variables xloc
and yloc
. An event handler is used to update these values when the arrow keys are pressed, and then a separate updateTurtle
function is called to draw the turtle on the screen.
Currently the turtle can drive off the screen. If we are clever about how we use our constrain
function, however, we can prevent this from happening.
Do This:
- Starter code is provided which allows the turtle to move. Additionally a working version of
constrain
is provided. - Call the
constrain
function twice within theupdateTurtle
function to prevent the turtle from going outside the screen.- One call to the function for
xloc
and one time foryloc
. - Recall the screen is 320 by 450 pixels.
- One call to the function for
- Run your app and confirm the turtle cannot leave the screen.
Student Instructions
Use a Function that Returns a Value in an App - Part 2
This time, you're going to write a function that returns a value to add functionality to the turtle driver. The updateTurtle
function now is making a call to a function called wrap
that has not been written yet. It accepts three parameters and should work in the following way:
input
: the input value to the function. If it is within the range it should just be returned.low
: the lower bound of the range. Ifinput
is below this value the output should be the value ofhigh
.high
: the upper bound of the range. Ifinput
is above this value the output should be the value oflow
.
By using this function you can create the illusion that the screen "wraps" around, so when the turtle leaves the top of the screen it appears again at the bottom.
Do This:
- Starter code is provided which allows the turtle to move.
- The
updateTurtle
function now makes two calls towrap
, but the function is not yet written. - Write the
wrap
function so that it implements the logic described above. - Run your app and confirm the turtle now "wraps" when it leaves the screen.
Standards Alignment
View full course alignment
Computer Science Principles
1.1 - Creative development can be an essential process for creating computational artifacts.
1.1.1 - Apply a creative development process when creating computational artifacts. [P2]
- 1.1.1B - Creating computational artifacts employs an iterative and often exploratory process to translate ideas into tangible form.
1.2 - Computing enables people to use creative development processes to create computational artifacts for creative expression or to solve a problem.
1.2.3 - Create a new computational artifact by combining or modifying existing artifacts. [P2]
- 1.2.3A - Creating computational artifacts can be done by combining and modifying existing artifacts or by creating new artifacts.
- 1.2.3C - Combining or modifying existing artifacts can show personal expression of ideas.
2.2 - Multiple levels of abstraction are used to write programs or create other computational artifacts
2.2.1 - Develop an abstraction when writing a program or creating other computational artifacts. [P2]
- 2.2.1A - The process of developing an abstraction involves removing detail and generalizing functionality.
- 2.2.1C - An abstraction generalizes functionality with input parameters that allow software reuse.
2.2.2 - Use multiple levels of abstraction to write programs. [P3]
- 2.2.2A - Software is developed using multiple levels of abstractions, such as constants, expressions, statements, procedures, and libraries.
- 2.2.2B - Being aware of and using multiple levels of abstraction in developing programs helps to more effectively apply available resources and tools to solve problems.
4.1 - Algorithms are precise sequences of instructions for processes that can be executed by a computer and are implemented using programming languages.
4.1.1 - Develop an algorithm for implementation in a program. [P2]
- 4.1.1A - Sequencing, selection, and iteration are building blocks of algorithms.
- 4.1.1B - Sequencing is the application of each step of an algorithm in the order in which the statements are given.
- 4.1.1C - Selection uses a Boolean condition to determine which of two parts of an algorithm is used.
- 4.1.1D - Iteration is the repetition of part of an algorithm until a condition is met or for a specified number of times.
- 4.1.1E - Algorithms can be combined to make new algorithms.
- 4.1.1F - Using existing correct algorithms as building blocks for constructing a new algorithm helps ensure the new algorithm is correct.
5.1 - Programs can be developed for creative expression, to satisfy personal curiosity, to create new knowledge, or to solve problems (to help people, organizations, or society).
5.1.2 - Develop a correct program to solve problems. [P2]
- 5.1.2A - An iterative process of program development helps in developing a correct program to solve problems.
- 5.1.2B - Developing correct program components and then combining them helps in creating correct programs.
- 5.1.2C - Incrementally adding tested program segments to correct, working programs helps create large correct programs.
- 5.1.2J - A programmer designs, implements, tests, debugs, and maintains programs when solving problems.
5.3 - Programming is facilitated by appropriate abstractions.
5.3.1 - Use abstraction to manage complexity in programs. [P3]
- 5.3.1A - Procedures are reusable programming abstractions.
- 5.3.1B - A function is a named grouping of programming instructions.
- 5.3.1C - Procedures reduce the complexity of writing and maintaining programs.
- 5.3.1D - Procedures have names and may have parameters and return values.
- 5.3.1E - Parameterization can generalize a specific solution.
- 5.3.1F - Parameters generalize a solution by allowing a function to be used instead of duplicated code
- 5.3.1G - Parameters provide different values as input to procedures when they are called in a program.
- 5.3.1K - Lists and list operations, such as add, remove, and search, are common in many programs.
- 5.3.1L - Using lists and procedures as abstractions in programming can result in programs that are easier to develop and maintain.
5.5 - Programming uses mathematical and logical concepts.
5.5.1 - Employ appropriate mathematical and logical concepts in programming. [P1]
- 5.5.1E - Logical concepts and Boolean algebra are fundamental to programming.
- 5.5.1J - Basic operations on collections include adding elements, removing elements, iterating over all elements, and determining whether an element is in a collection.
CSTA K-12 Computer Science Standards (2017)
AP - Algorithms & Programming
- 3B-AP-14 - Construct solutions to problems using student-created components, such as procedures, modules and/or objects.