1.1Statements and the structure of a program

Last updated June 11, 2026

Chapter introduction

Welcome to the first real programming chapter. Chapter 1 takes a wide, deliberately shallow pass over the core of Rust: enough of each piece for you to write and understand small programs, with the depth deferred to later chapters. Don't expect mastery of anything yet, and don't worry when a lesson says "we'll explain the rest later." That's the design, and the later chapters keep the promise. Starting in this chapter, every lesson ends with a short quiz; do them, even when they look easy.

A computer program is a list of instructions, and in Rust the most basic instruction is called a statement. A statement makes the program do something: create a variable, compute a value, print some text. Statements are the sentences of a programming language, and like sentences end with periods, most Rust statements end with a semicolon ;.

A program is many statements executed in order, top to bottom, one after another. So far, so simple. The next question is where that top is.

Functions and main

Statements don't float around loose. They live inside functions: named bundles of statements that run as a group, in order, whenever the function is used. We'll spend all of chapter 2 on functions; for now you only need the most famous one.

When you run a Rust program, execution begins at the top of a function named main. Statements inside main run in order, and when the last one finishes, the program ends.

Rule

Every Rust program must have exactly one function named main. No main, no program; the build fails before anything runs.

Dissecting Hello, world

You met this program in lesson 0.8, where we refused to explain it. Time to pay up.

fn main() {
    println!("Hello, world!");
}

Line 1: fn is the keyword that defines a function (Rust spells things tersely; get used to it). main is the function's name, the parentheses () hold the function's inputs (none here; chapter 2 fills them), and the opening brace { begins the function's body, the statements that belong to it.

Line 2 is the body's one statement, and it does the printing. println! is the tool being used: its name comes from "print line", and its job is to write text to the screen, then move to the next line. The text it prints is "Hello, world!", a piece of text data in quotes (text in quotes is called a string literal; more in lesson 1.10). The parentheses hand the text to println!, and the semicolon ends the statement.

Line 3: the closing brace } ends the body of main, and with it, the program.

So what's that exclamation mark about? The ! means println! is a macro rather than a function. For now, here's the working definition: a macro is a supercharged function, used much like a regular one, with the ! as its name tag.

Key insight

Why does printing need to be "supercharged" at all? Because println! accepts things ordinary functions can't, like any number of values to print at once. You'll use macros constantly and write none of them for a very long time; the full story is in chapter 24, and nothing before it depends on those details. When you see !, think "macro, called like a function," and read on.

Syntax errors

A programming language has grammar rules, just like English, and the compiler enforces them to the letter. Break one and you get a syntax error. Here's a program with a semicolon missing at the end of line 2:

fn main() {
    println!("Hello")
    println!("world");
}

The compiler refuses, and tells you why:

error: expected `;`, found `println`
 --> src/main.rs:2:22
  |
2 |     println!("Hello")
  |                      ^ help: add `;` here
3 |     println!("world");
  |     ------- unexpected token

This is worth reading slowly, because you'll be reading messages like it all week. The first line states the problem: the compiler expected a semicolon and found the word println instead. The --> line gives the location as file, line, and column. The caret ^ points at the exact spot, and help: spells out the fix. Rust's error messages will usually meet you at least this far; many go further and write the corrected code for you.

Key insight

The compiler reports where it noticed the problem, which isn't always where the problem is. Here the missing semicolon belongs to line 2, but the compiler only became certain something was wrong when line 3 started with an unexpected println. If an error location looks innocent, check just above it.

The best thing you can do right now is break this program yourself. Type it in correctly, then sabotage it one change at a time: remove a semicolon, delete a brace, misspell println, drop a quote. Compile after each. You'll meet half a dozen error messages in five minutes, in the lowest-stakes setting you'll ever meet them.

Quiz time

Question #1

What is a statement?

Show solution

A statement is the smallest instruction that makes a program do something, such as creating a variable or printing text. Most statements in Rust end with a semicolon.

Question #2

What is a function?

Show solution

A named bundle of statements that run as a group, in order, whenever the function is used.

Question #3

What is the name of the function every Rust program must have, and what is special about it?

Show solution

main. When the program runs, execution starts at the top of main, and the program ends when main finishes. Every program must have exactly one.

Question #4

In println!, what does the ! tell you?

Show solution

That println! is a macro rather than a regular function. At this point in the course, treat a macro as a supercharged function that's called the same way; chapter 24 explains what's actually super about it.

Question #5

What is a syntax error?

Show solution

A violation of the language's grammar rules, caught by the compiler, which then refuses to build the program. A missing semicolon is the classic example.

Question #6

Without compiling it, what's wrong with this program?

fn main() {
    println!("Hi there")
}

Trick question warning: try compiling it after you've answered.

Show solution

It looks like the semicolon mistake from this lesson, but this program actually compiles and runs. When the last thing in a function body has no semicolon, Rust treats it as something subtly different from a statement, and it's legal. The why is lesson 1.11's whole job. (The lesson here: with one statement per function body, some semicolon mistakes are forgiven. With two, as in the example above, they're not.)

In the next lesson, we'll cover the second-most-used tool after println!: notes to yourself that the compiler ignores entirely.