Start learning free

LESSON 34 OF 414 · FUNCTIONS I

Quiz: Execution Flow Between Functions in Rust

Quiz Read the full explanation

Quiz: What would this code produce if we were to copy-paste it in a code editor and run it?

fn welcome_user() {
	println!("Hey coder!");
}
fn main_function() {
	println!("Welcome back!");
	welcome_user();
}

Important Note:

Do not use an actual code editor to get the answer! It would defy the whole purpose of the quiz!

Pick your answer

Next lesson

RUST · FUNCTIONS I

Quiz Indentation 1 in Rust, explained

Problem overview

The quiz shows two functions and asks what the code prints:

fn welcome_user() {
    println!("Hey coder!");
}
fn main_function() {
    println!("Welcome back!");
    welcome_user();
}

The options are: A, Hey coder! then Welcome back!; B, only Welcome back!; C, errors; D, Welcome back! then Hey coder!. As in the other quizzes of this chapter, main_function is the main part of the program, the code that runs. The answer is recorded in a comment and printed with println!.

Approach: follow the flow of execution

Execution flow means the order in which statements run. Inside a function body it is top to bottom. When a statement is a call to another function, the flow jumps into that function, runs its body, then returns to the line after the call.

Walk through it:

  1. Definitions. welcome_user and main_function are only defined. Nothing prints yet.
  2. First statement of main_function. println!("Welcome back!"); runs. The output so far is Welcome back!.
  3. Second statement. welcome_user(); is a call. The flow jumps into welcome_user and runs println!("Hey coder!");. The output is now Welcome back! and then Hey coder!.
  4. Return. The body of welcome_user ends, control returns to main_function, and there are no more statements.

That is option D.

Why the others fail

  • A reverses the order. It would be right if the call came before the print in main_function.
  • B forgets the call. welcome_user(); does run, and its message appears.
  • C has no basis in the code. The definitions are valid, and the call uses a function that exists. The quiz's two functions are written one after the other at the top level, and the order of two top-level definitions does not matter.

A way to check yourself

Keep a running list of the output and add to it each time a println! actually runs. When you reach a call, pause the current function, trace the called function completely, then come back. Here the list goes Welcome back! and then, from inside the call, Hey coder!. The same technique works for any chain of calls, however deep. If welcome_user itself called a third function, you would trace that one completely before returning to welcome_user.

The solution in Rust

// answer = "D"
println!("D");

/* Explanation:

We first only define the welcome_user() function, so the println!("Hey coder!") won't actually be executed for now.

The main_function() is our "main program" so all the statements inside there will be executed in the order they are written.

First one is the "println!("Welcome back!");", which will be executed and the output so far is:
Welcome back!

Then, the "welcome_user();" function call will be executed.
So the code inside the function body (println!("Hey coder!");) will get executed now and the output is:
Welcome back!
Hey coder!
*/

Rust details:

  • Layout does not decide the order. In Rust, indentation and blank lines do not change what runs. The order of statements inside the braces does. In the quiz, welcome_user is defined first, but it prints second, because it is called second.
  • A call inside a body is a statement. welcome_user(); ends with a semicolon and, once it finishes, the next statement continues.
  • Entry point. A complete Rust program starts in a function named main. The quiz calls its main part main_function, and the lesson's tests only read the letter you print.

Edge cases and common mistakes

  • Thinking the first-defined function runs first. Definition order is not execution order. The flow is decided by what is called, and when.
  • Forgetting to return. After a called function ends, the flow continues after the call. With one more line, such as println!("Bye!"); after welcome_user();, the output would be Welcome back!, Hey coder!, Bye!.
  • Dropping the called function's output. Output from inside a called function appears at the point of the call, not at the end of the program.
  • Letter mismatch. The comment and the printed letter should both be D.
Keep going with RustAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
Start learning free