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

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 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 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
  • 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.
  • The Return Command
  • 2
  • (click tabs to see student view)
View on Code Studio

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:

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.

Continue

  • Using minVal
  • 3
  • (click tabs to see student view)
View on Code Studio

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 using rand1 and rand2 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.

  • Writing and Debugging maxVal
  • 4
  • 5
  • 6
  • (click tabs to see student view)
View on Code Studio

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 write minVal.
  • Use maxVal within the console.log statement as if it were a number to generate the output similar to the one shown below.

View on Code Studio

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.
View on Code Studio

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. If input is below this value, the function should return the value of low.
  • high : the upper bound of the range. If input is above this value, the function should return the value of high.

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.

  • Return Values in Apps
  • 7
  • 8
  • (click tabs to see student view)
View on Code Studio

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 the updateTurtle function to prevent the turtle from going outside the screen.
    • One call to the function for xloc and one time for yloc.
    • Recall the screen is 320 by 450 pixels.
  • Run your app and confirm the turtle cannot leave the screen.

View on Code Studio

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. If input is below this value the output should be the value of high.
  • high: the upper bound of the range. If input is above this value the output should be the value of low.

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 to wrap, 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.