# 2.x Chapter 2 summary and quiz
> Chapter 2's terms in review, plus the classic three-function program quiz.
Source: https://learnrust.net/chapter-2/chapter-2-summary-and-quiz/
Chapter 2 turned your programs from monologues into teams. The review, then the chapter's rite-of-passage program.
## Quick review
A function is a reusable, named piece of program dedicated to one job; you **call** it with parentheses, execution jumps in, runs the body, and returns to the caller. Definitions can appear in any order in the file (no forward declarations exist, or are needed). Calling without parentheses (`greet;`) compiles, does nothing, and draws a warning.
A function declares what it yields with a return type after `->`, and its body is a block whose **tail expression** is the returned value; a reflexive semicolon on that last line is the classic E0308 ("expected `i32`, found `()`"), with the compiler's help line naming the cure. The `return` keyword exists for early exits; code after it is unreachable, and the compiler says so. No arrow means the function returns `()`. Repeated code extracted into one function is the **DRY** principle at work.
A **parameter** is a typed variable in the definition's parentheses; an **argument** is the value a caller supplies for it. Parameter types are mandatory because the function's **signature** is a checked, local contract: wrong-type and wrong-count mistakes (E0061) are reported at the call site, with the contract quoted. For this chapter's types, arguments are *copied* into parameters (the honest asterisk lives in chapter 8).
A variable's **scope** runs from its `let` to its block's closing brace; functions' variables (**local variables**, parameters included) are invisible to each other, which is why names can repeat across functions without a meeting ever occurring. Define variables near first use, and remember blocks-as-expressions can scope scratch work out of existence.
Functions buy organization, reuse, testing, extensibility, and abstraction; one function, one job, named for the job. Design top-down: state the goal, list requirements, decompose into function-sized pieces, then build from a compiling `todo!()` skeleton, one implemented-and-tested function at a time, simplest version first.
## Quiz time
**Question #1**
Without running it, trace this program's complete output:
```rust
fn main() {
let result = transform(3);
println!("main: {result}");
}
fn transform(n: i32) -> i32 {
println!("transform: got {n}");
let n = n + 1;
double(n)
}
fn double(n: i32) -> i32 {
println!("double: got {n}");
n * 2
}
```
Show solution
```
transform: got 3
double: got 4
main: 8
```
`transform` receives 3, makes a new `n` of 4 (block scoping at work), and its tail expression is the call to `double`, whose own result (8) therefore becomes `transform`'s result too. Three functions, three private `n`s, no interference.
**Question #2**
Predict the compiler error:
```rust
fn half(n: i32) -> i32 {
n / 2;
}
fn main() {
println!("{}", half(10));
}
```
Show solution
E0308 at `half`: expected `i32`, found `()`, because the semicolon turned the tail expression into a statement. The help line says to remove the semicolon. If this one's reflexive by now, the chapter did its job.
**Question #3**
The classic. Write a program with three functions:
- `read_number() -> i32`: prompts for and returns one whole number (the 1.6/2.2 recipe)
- `add(x: i32, y: i32) -> i32`: you can guess
- `print_answer(answer: i32)`: prints `The sum is: `
`main` should use them to produce, for inputs 6 and 4:
```
Enter a whole number:
6
Enter a whole number:
4
The sum is: 10
```
Show solution
```rust
fn main() {
let x = read_number();
let y = read_number();
print_answer(add(x, y));
}
fn read_number() -> i32 {
println!("Enter a whole number:");
let mut input = String::new();
std::io::stdin()
.read_line(&mut input)
.expect("failed to read input");
input.trim().parse().expect("that wasn't a whole number")
}
fn add(x: i32, y: i32) -> i32 {
x + y
}
fn print_answer(answer: i32) {
println!("The sum is: {answer}");
}
```
Note how `main` is four lines that read as the plan, the prompt moved *inside* `read_number` (it belongs to that job), and compute (`add`) stayed separate from output (`print_answer`), per lesson 2.5.
A historical footnote you've earned: this course's C++ inspiration sets this same exercise, then spends its versions 2 and 3 splitting the program across multiple files with forward declarations and a header guard. The Rust edition of those follow-ups is chapter 13, lesson 13.4, where the whole topic takes one lesson, mostly because there's so little to configure.
That's functions. Chapter 3 takes the other half of the craft: what to do when the program you built out of them doesn't do what you meant.