Fruitful Functions vs. Void Functions
The return statement sends a value from inside a function back to the calling code, making that value the result of the function call.
A Result Needs a Route Out
A function can compute a result internally, but the calling code needs a way to receive that result. The return statement provides that route. It sends a value from inside the function back to the code that called it, making the value the result of the entire function call.
Following the Returned Value
Consider a function named addtwo that receives two parameters. Inside the function, a local variable named added stores the sum of those parameters. The return statement sends added back to the calling code. When the calling code uses addtwo with 3 and 5, the function computes 8. That 8 becomes the result of the function call, and the calling code can store it in a variable named x.
Tracing addtwo
Determine what value is stored in x after the calling code uses addtwo with 3 and 5.
Receive inputs: The function receives 3 and 5 as its two parameter values.
Compute locally: The local variable added stores the sum of the parameters, which is 8.
Return: The return statement sends the value 8 out of the function.
Capture the result: The complete function call produces 8, and the calling code assigns that result to x.
x stores 8. The calling code receives the returned value, not the internal variable named added.
Return Ends Execution
A return statement does two jobs at once. It sends a value back to the caller, and it immediately ends the function. Any code placed after that return statement inside the same function will not run. This behavior is intentional, not an error.
What do you think happens?
A function receives 15. It checks whether the value is greater than 10. If it is, the function returns twice the value, and a print action appears later in the function. Does the print action run?
Reveal answer
Answer: No, because return ends the function immediately.
With 15, the condition is true, so returning 30 ends the function before the later print action can run. With 5, the condition is false, the conditional block is skipped, the print action runs, and then returning 5 ends the function.
When tracing a function, stop reading its body as soon as you reach the return statement that executes. Then follow the returned value back to the calling expression.
Local Names and Calling Scope
Variables created inside a function are local to that function. They exist while the function is running and cease to exist once the function returns. The calling code can access the value that was returned, but it cannot access the internal variables used to calculate that value.
The area variable does not escape
A function named calculate_area creates a local variable named area with the value 20 and returns that value. The calling code stores the result in result. What can the calling code access?
Inside the function: area exists inside calculate_area and holds 20 while the function is running.
At return: The function sends the value 20 back to the calling code.
After return: area ceases to exist because it was local to the function.
In the caller: The calling code stores the returned value in result, so result contains 20.
The calling code can use result, but it cannot use area. Trying to print area in the calling code produces a NameError because area was never defined in that scope.
Two Kinds of Function Results
A fruitful function returns a value that the calling code can assign, print, use in an expression, or pass to another function. The returned value can be a number, string, list, dictionary, or another object, depending on what the function computes.
A void function only performs actions and does not communicate a usable result back to the code that called it. The distinction is about what the caller receives: a fruitful function delivers a value, while a void function performs an action without delivering a result for the caller to use.
| Feature | Fruitful function | Void function |
|---|---|---|
| Main behavior | Computes and returns a value | Performs an action without communicating a usable result |
| What the caller receives | A value that can be assigned, printed, used, or passed onward | No usable computed result |
| Role of return | Delivers the function's output | The function does not deliver a result back to the caller |
Mistakes in Return Tracing
Treating a local variable as though it remains available after the function returns
area was created inside the function and ceases to exist when the function returns.
Fix:
Use the variable in the calling scope that captured the returned value, such as result.Reading code after an executing return statement as though it will run
return immediately terminates the function.
Fix:
Stop the trace at the return and do not include later actions in the output.Confusing the local computation with the function call's result
The names are different and belong to different scopes, even though the returned value is copied into the caller's variable.
Fix:
Trace the value separately from the variable name: added produces the value, return sends it, and x receives it.
Practice the Trace
A function receives the value 5. It checks whether the value is greater than 10. If the condition is true, it returns twice the value. Otherwise, it performs a print action and then returns the original value. Predict which value the function returns and whether the print action runs.
Hints
- First decide whether 5 is greater than 10.
- If the condition is false, follow the path after the conditional block.
- The function still returns a value after the print action.
The correct trace is: 5 is not greater than 10, so the conditional return is skipped. The print action runs, and then the function returns 5. This contrasts with the input 15, where the function returns 30 immediately and the later print action never runs.
Essential Takeaways
- The return statement sends a value from inside a function back to the calling code.
- The returned value becomes the result of the complete function call and can be assigned to a variable in the calling scope.
- Executing return ends the function immediately, so later code inside that function does not run.
- Local variables exist only while their function is running; after return, the caller can access the returned value but not those local variables.
- A fruitful function delivers a usable result, while a void function performs an action without delivering a usable result.
Key Takeaways
- Return moves a computed value from a function to its calling code.
- A function call's result can be stored in a variable, printed, used in an expression, or passed to another function.
- Return stops the function immediately.
- Local variables disappear when the function returns, while the caller retains the returned value in its own variable.
- Fruitful functions return usable values; void functions perform actions without communicating a usable result.