# Finch for Beginners
**Never written a program before? This guide is for you.**
No experience needed, and no math beyond what you learned in primary school.
Take it slowly, one section at a time, and type every example yourself: that is how it sticks.
> 🇵🇱 Polska wersja: [dla-poczatkujacych.md](../pl/dla-poczatkujacych.md)
---
## Contents
1. [What is a program?](#1-what-is-a-program)
2. [Getting Finch ready](#2-getting-finch-ready)
3. [Your first program](#3-your-first-program)
4. [Showing things on the screen](#4-showing-things-on-the-screen)
5. [Boxes with names: variables](#5-boxes-with-names-variables)
6. [Kinds of values](#6-kinds-of-values)
7. [Doing math](#7-doing-math)
8. [Making decisions: if](#8-making-decisions-if)
9. [Repeating things: loops](#9-repeating-things-loops)
10. [Your own commands: functions](#10-your-own-commands-functions)
11. [Lists: many values in one box](#11-lists-many-values-in-one-box)
12. [Playing with text](#12-playing-with-text)
13. [Asking the user](#13-asking-the-user)
14. [Your own kinds of values: structs](#14-your-own-kinds-of-values-structs)
15. [Saving to a file](#15-saving-to-a-file)
16. [When something goes wrong](#16-when-something-goes-wrong)
17. [Small projects to try](#17-small-projects-to-try)
18. [Cheat sheet](#18-cheat-sheet)
19. [Words you will hear](#19-words-you-will-hear)
---
## 1. What is a program?
A computer is very fast, but it does not think. It only does exactly what it is told,
one step at a time.
A **program** is a list of those steps, written down. Like a recipe:
> 1. Take two eggs.
> 2. Break them into a bowl.
> 3. Stir.
A **programming language** is the way we write that recipe so the computer understands it.
**Finch** is one of those languages. It was made to be small and simple, so you
can learn it quickly.
The computer reads your program from top to bottom, line by line.
---
## 2. Getting Finch ready
Finch runs on **Linux** computers. If a teacher, parent or friend has already set it up
for you, skip to the next section.
Otherwise, open the **Terminal** program (a window where you type commands) and type
these lines one by one, pressing **Enter** after each:
```sh
git clone https://github.com/Nexoniarz/Finch.git
cd Finch
nix-shell
cmake -S . -B build -G Ninja
ninja -C build
```
If the last line finishes without the word `error`, Finch is ready.
(If your computer does not have `nix-shell`, ask someone to follow the
[guide for technicians](for-technicians.md#2-installing). It explains the other way.)
To check it works, type:
```sh
./build/finch version
```
You should see something like `finch 2.3.0`.
---
## 3. Your first program
1. Open any text editor (for example *Text Editor*, *Kate*, *gedit* or *VS Code*).
2. Type exactly this:
```c
fn main() {
print("Hello!")
}
```
3. Save it in the `Finch` folder as **`hello.fch`**. The `.fch` at the end tells everyone it is a Finch program.
4. In the Terminal, type:
```sh
./build/finch run hello.fch
```
You will see:
```
Hello!
```
🎉 **You have just written and run a program.**
### What did we write?
```text
fn main() { ← "here starts the main part of my program"
print("Hello!") ← "show the text Hello! on the screen"
} ← "the main part ends here"
```
- `fn main()` is where every Finch program **starts**. Each program has exactly one `main`.
- The curly brackets `{` and `}` hold everything that belongs to `main`, like the two covers of a book.
- `print(...)` shows something on the screen.
- Text always goes inside double quotes: `"Hello!"`.
The spaces at the start of `print` are not required, but they make it easy to see
what is inside the brackets. Always add them. It is a good habit.
---
## 4. Showing things on the screen
`print` can show text and numbers. Put a comma between things, and Finch adds a space for you:
```c
fn main() {
print("I am", 10, "years old")
print("2 + 2 =", 2 + 2)
print()
print("The line above is empty")
}
```
Shows:
```
I am 10 years old
2 + 2 = 4
The line above is empty
```
Every `print` starts a new line. `print()` with nothing inside makes an empty line.
### Notes for yourself: comments
Anything after `//` is ignored by the computer. Use it to leave notes:
```c
// This program says hi
fn main() {
print("Hi") // this shows Hi
}
```
---
## 5. Boxes with names: variables
Imagine a box with a label on it. You can put something in the box and later look
at what is inside by reading the label. In programming that box is called a **variable**.
```c
fn main() {
age := 10
print(age)
}
```
`age := 10` means: *"make a new box, label it `age`, and put 10 in it."*
You can change what is in the box later, using just `=`:
```c
fn main() {
score := 0
print("Score:", score)
score = 5
print("Score:", score)
score = score + 1
print("Score:", score)
}
```
```
Score: 0
Score: 5
Score: 6
```
`score = score + 1` reads as: *"take what is in `score`, add 1, and put the result back into `score`."*
There is a shorter way to write the same thing: `score += 1`.
**Remember:**
- `:=` makes a **new** box. You use it only once per name.
- `=` puts a new value into a box **that already exists**.
### Naming your boxes
Names can use the English letters `a`–`z` and `A`–`Z`, digits and `_`, but cannot start with a digit:
`age`, `total_points`, `player2` are fine. `2player` is not.
Letters like `é`, `ü` or `ż` cannot be used in names, only inside text in quotes: `print("Zürich")` is fine.
Pick names that say what is inside: `price` is better than `p`.
---
## 6. Kinds of values
Finch keeps track of what *kind* of thing is in each box. The kind is called a **type**.
These are the ones you will use most:
| Type | What it holds | Examples |
|---------|------------------------------|--------------------------|
| `int` | whole numbers | `0`, `42`, `-7` |
| `float` | numbers with a decimal point | `3.14`, `0.5`, `-2.0` |
| `str` | text | `"Hello"`, `"Ola"` |
| `bool` | yes or no | `true`, `false` |
| `char` | a single letter or sign | `'A'`, `'z'`, `'?'` |
Finch figures out the type by itself when you use `:=`:
```c
name := "Ola" // str
age := 10 // int
height := 1.42 // float
likes_cats := true // bool
```
You can also write the type yourself, in front of the name:
```c
int age = 10
str name = "Ola"
```
Both ways do the same thing. Use the one you like.
**A box keeps its type.** If `age` holds whole numbers, you cannot put text in it later.
Finch will stop and tell you, which helps you catch mistakes early.
---
## 7. Doing math
| Sign | Meaning | Example | Result |
|------|----------------------------|----------|--------|
| `+` | add | `7 + 2` | `9` |
| `-` | subtract | `7 - 2` | `5` |
| `*` | multiply | `7 * 2` | `14` |
| `/` | divide | `7 / 2` | `3` |
| `%` | what is left after dividing | `7 % 2` | `1` |
**Careful with dividing whole numbers:** `7 / 2` gives `3`, not `3.5`, because both are
whole numbers, so the answer is a whole number too (the part after the dot is dropped).
If you want `3.5`, use a decimal number: `7.0 / 2`.
Multiplication and division happen before adding and subtracting, just like at school.
Use brackets to change the order:
```c
print(2 + 3 * 4) // 14
print((2 + 3) * 4) // 20
```
`%` is handy to check if a number is even: an even number divided by 2 leaves nothing,
so `n % 2` is `0`.
You **cannot divide by zero**. If your program tries, it stops and tells you which line did it.
---
## 8. Making decisions: if
Programs can choose what to do. `if` means *"only do this when something is true"*.
```c
fn main() {
temperature := 25
if temperature > 20 {
print("It's warm, wear a t-shirt")
}
}
```
Add `else` for *"otherwise, do this"*:
```c
if temperature > 20 {
print("It's warm")
} else {
print("Take a jacket")
}
```
And `else if` for more choices. Finch checks them from top to bottom and does only
the **first** one that is true:
```c
if temperature > 25 {
print("Hot!")
} else if temperature > 15 {
print("Nice")
} else {
print("Cold")
}
```
### Comparing things
| Sign | Means |
|------|-----------------------------|
| `==` | is equal to |
| `!=` | is not equal to |
| `<` | is smaller than |
| `>` | is bigger than |
| `<=` | is smaller than or equal to |
| `>=` | is bigger than or equal to |
⚠️ **One `=` puts a value in a box. Two `==` ask "are these equal?"**
You can compare text too: `if name == "Ola" { ... }`.
### Joining questions
- `&&` means **and**: both must be true. `if age > 6 && age < 12 { ... }`
- `||` means **or**: at least one must be true. `if day == "Sat" || day == "Sun" { ... }`
- `!` means **not**: it flips true and false. `if !raining { ... }`
---
## 9. Repeating things: loops
Computers never get bored. A **loop** repeats the same steps many times.
### Counting with `for`
```c
fn main() {
for i in 1..6 {
print("Number", i)
}
}
```
```
Number 1
Number 2
Number 3
Number 4
Number 5
```
`for i in 1..6` means: *"count with `i` from 1, up to but **not including** 6"*.
So `0..10` gives you ten numbers: 0, 1, 2 … 9.
### Repeating while something is true: `while`
```c
fn main() {
count := 3
while count > 0 {
print(count)
count -= 1
}
print("Go!")
}
```
```
3
2
1
Go!
```
⚠️ Make sure the loop can end. If `count` never went down, the loop would run forever.
If that happens, press **Ctrl + C** in the Terminal to stop it.
### Stopping early and skipping
- `break` leaves the loop right away.
- `continue` skips the rest of this round and goes to the next one.
```c
for i in 1..100 {
if i == 5 {
break // stop when we reach 5
}
print(i) // prints 1 2 3 4
}
```
---
## 10. Your own commands: functions
When you do the same thing in many places, give it a name. That named block is a **function**.
You already know one: `main`.
```c
fn say_hello(str name) {
print("Hello,", name)
}
fn main() {
say_hello("Ola")
say_hello("Tom")
}
```
```
Hello, Ola
Hello, Tom
```
`str name` in brackets means: *"this function needs one piece of text, and inside it
we call that text `name`."* The thing you put in brackets when using it is passed in.
### Functions that give back an answer
Write `->` and the type of the answer, and use `return` to give it back:
```c
fn add(int a, int b) -> int {
return a + b
}
fn main() {
result := add(2, 3)
print(result) // 5
}
```
It does not matter where in the file you put your functions, above or below `main`.
---
## 11. Lists: many values in one box
Sometimes one box is not enough. A shopping list has many things on it.
A **list** (programmers also say **array**) keeps many values in order:
```c
fn main() {
fruits := ["apple", "banana", "cherry"]
print(fruits)
print("I have", fruits.len, "fruits")
print("The first one is", fruits[0])
}
```
```
["apple", "banana", "cherry"]
I have 3 fruits
The first one is apple
```
- Square brackets `[ ]` make a list. Commas separate the values.
- `.len` tells you how many things are in the list.
- `fruits[0]` is the **first** thing. Counting starts at **0**, so `fruits[1]` is the second, and `fruits[2]` the third.
If you ask for a place that doesn't exist, like `fruits[10]`, the program stops and tells you:
`index 10 is out of range (the length is 3)`.
### Adding and taking away
```c
fn main() {
[]int scores // an empty list of whole numbers
scores.push(10) // put 10 at the end
scores.push(25)
scores.push(7)
print(scores) // [10, 25, 7]
last := scores.pop() // take the last one out
print(last, scores) // 7 [10, 25]
scores.sort()
print(scores)
}
```
### Going through a list
`for ... in` visits every value, one by one:
```c
fn main() {
total := 0
for n in [3, 5, 2] {
total += n
}
print("Total:", total) // Total: 10
}
```
Lists can do more: `contains`, `find`, `insert`, `remove`, `sort`, `reverse`, `join`.
The [guide for technicians](for-technicians.md#arrays) lists them all.
---
## 12. Playing with text
Text can be glued together with `+`:
```c
fn main() {
name := "Ola"
greeting := "Hello, " + name + "!"
print(greeting)
}
```
To glue a number to text, turn the number into text first with `str(...)`:
```c
age := 10
print("Age: " + str(age))
```
Text has handy tools too:
```c
fn main() {
word := "Finch"
print(word.len) // 5 letters
print(word[0]) // F (the first letter)
print(word.upper()) // FINCH
print(word.lower()) // finch
print(word.contains("in")) // true
for letter in word {
print(letter) // F, i, n, c, h, one per line
}
}
```
---
## 13. Asking the user
`input` shows a question and waits until the person types an answer and presses Enter:
```c
fn main() {
name := input("What's your name? ")
print("Nice to meet you,", name)
}
```
The answer is always **text**. If you need a number, turn it into one with `int(...)`:
```c
fn main() {
answer := input("How old are you? ")
age := int(answer)
print("Next year you will be", age + 1)
}
```
If the person types something that isn't a number, the program stops with a message
like `can't turn "abc" into int`.
---
## 14. Your own kinds of values: structs
Imagine a card in a library: each card has a title, an author and a year.
A **struct** lets you make your own kind of value with named parts:
```c
struct Book {
str title
str author
int year
}
fn main() {
b := Book(title: "The Hobbit", author: "Tolkien", year: 1937)
print(b.title, "by", b.author)
b.year = 1938
print(b)
}
```
```
The Hobbit by Tolkien
Book(title: "The Hobbit", author: "Tolkien", year: 1938)
```
- `struct Book { ... }` describes what every book has. Put it **outside** `main`.
- `Book(title: ..., author: ..., year: ...)` makes one book.
- `b.title` reads one part. `b.year = 1938` changes it.
You can give parts a starting value. Then you don't have to fill them in:
```c
struct Player {
str name
int lives = 3
}
fn main() {
p := Player(name: "Ola")
print(p.lives) // 3
}
```
And you can keep many of them in a list: `[]Book shelf`, then `shelf.push(b)`.
---
## 15. Saving to a file
Programs forget everything when they end. To remember things, save them to a file:
```c
fn main() {
write_file("note.txt", "Buy milk")
print(read_file("note.txt"))
}
```
- `write_file(name, text)` saves the text in a file (and replaces what was there).
- `read_file(name)` gives you the file's text back.
- `file_exists(name)` tells you if the file is there (`true` or `false`).
The file appears in the folder where you ran the program.
---
## 16. When something goes wrong
Everyone makes mistakes when programming, even experts, every day.
Finch tries hard to explain what went wrong in plain words. Example:
```c
fn main() {
age := 10
print(agee)
}
```
```
hello.fch:3:11: error: there is no variable named 'agee'
3 | print(agee)
| ^
```
How to read it:
- `hello.fch` is the file,
- `3` is the **line** number,
- `11` is how far into the line (the **column**),
- then the explanation, and the line itself with a `^` pointing at the problem.
Here we simply misspelled `age`.
### Common mistakes
| Finch says | What it means | Fix |
|---|---|---|
| `there is no variable named 'x'` | The name is misspelled, or you never made that box | Check spelling. Create it with `x := ...` |
| `a variable named 'x' already exists here` | You used `:=` twice for the same name | Use `=` the second time |
| `'x' must be int, but this is str` | Wrong kind of value for that box | Put the right kind of value in |
| `put each statement on its own line` | Two commands on one line | Press Enter between them |
| `this '{' is never closed` | A `}` is missing | Add the `}` |
| `a condition must be bool` | `if` needs a yes/no question | Compare something: `if x > 0` |
| `runtime error: division by zero` | You divided by 0 while the program ran | Check the number before dividing |
| `index 5 is out of range (the length is 3)` | You asked a list for a place it doesn't have | Remember counting starts at 0; check `.len` |
| `can't turn "abc" into int` | `int(...)` got text that isn't a number | Check what the person typed |
| `can't use '+' on str and int` | Text plus a number | Use `str(...)` on the number |
---
## 17. Small projects to try
Try writing each one yourself first. Look at the solution only if you get stuck.
### Project 1: Times table
Show the 7 times table, from 7 × 1 to 7 × 10.
Solution
```c
fn main() {
for i in 1..11 {
print("7 x", i, "=", 7 * i)
}
}
```
### Project 2: Even or odd
For every number from 1 to 10, show whether it is even or odd.
Solution
```c
fn main() {
for n in 1..11 {
if n % 2 == 0 {
print(n, "is even")
} else {
print(n, "is odd")
}
}
}
```
### Project 3: Celsius to Fahrenheit
Show a table from 0 °C to 100 °C, every 10 degrees. Formula: `F = C * 9 / 5 + 32`.
Solution
```c
fn to_fahrenheit(float c) -> float {
return c * 9 / 5 + 32
}
fn main() {
for c in 0..11 {
celsius := float(c * 10)
print(celsius, "C =", to_fahrenheit(celsius), "F")
}
}
```
`float(...)` turns a whole number into a decimal number.
### Project 4: Fizz Buzz
Count from 1 to 20. For numbers divisible by 3 say `Fizz`, by 5 say `Buzz`,
by both say `FizzBuzz`, otherwise say the number.
Solution
```c
fn main() {
for n in 1..21 {
if n % 15 == 0 {
print("FizzBuzz")
} else if n % 3 == 0 {
print("Fizz")
} else if n % 5 == 0 {
print("Buzz")
} else {
print(n)
}
}
}
```
### Project 5: Biggest of three
Write a function `biggest(int a, int b, int c) -> int` that gives back the largest number.
Solution
```c
fn biggest(int a, int b, int c) -> int {
if a >= b && a >= c {
return a
}
if b >= c {
return b
}
return c
}
fn main() {
print(biggest(4, 9, 2)) // 9
}
```
### Project 6: Guess the number
The computer picks a secret number. The player guesses until they find it,
and the computer says "higher" or "lower" each time.
Solution
```c
fn main() {
secret := 42
tries := 0
while true {
guess := int(input("Your guess: "))
tries += 1
if guess < secret {
print("Higher!")
} else if guess > secret {
print("Lower!")
} else {
print("Yes! You needed", tries, "tries")
return
}
}
}
```
`return` inside `main` ends the program. (A version with a random number is in `examples/guess.fch`.)
### Project 7: Class average
Ask for 3 grades, keep them in a list, and show the list and the average.
Solution
```c
fn main() {
[]int grades
for i in 0..3 {
grades.push(int(input("Grade: ")))
}
sum := 0
for g in grades {
sum += g
}
print("Grades:", grades)
print("Average:", float(sum) / grades.len)
}
```
---
## 18. Cheat sheet
```c
// a comment
fn main() { // the program starts here
print("text", 42) // show things
x := 5 // new box (type guessed)
int y = 10 // new box (type written)
x = 7 // change a box
x += 1 // add 1 to x
if x > 5 { // decide
print("big")
} else if x > 0 {
print("small")
} else {
print("zero or less")
}
for i in 0..10 { // count 0 to 9
print(i)
}
while x > 0 { // repeat while true
x -= 1
}
}
fn add(int a, int b) -> int { // your own command
return a + b
}
struct Pet { // your own kind of value
str name
int age = 1
}
// lists: nums := [1, 2, 3] nums.push(4) nums[0] nums.len for n in nums { }
// text: "a" + "b" str(42) int("42") s.len s.upper() s.contains("x")
// ask: name := input("Name? ")
// files: write_file("f.txt", text) read_file("f.txt")
```
---
## 19. Words you will hear
| Word | Meaning |
|---|---|
| **program** | A list of steps for the computer |
| **code** | The text of a program |
| **run** | Make the computer do the steps |
| **compile** | Translate your code into something the computer can run. `finch run` does this for you |
| **variable** | A named box holding a value |
| **type** | The kind of value: number, text, yes/no… |
| **function** | A named group of steps you can use again |
| **loop** | Steps that repeat |
| **condition** | A yes/no question, like `x > 5` |
| **list / array** | Many values kept in order, like `[1, 2, 3]` |
| **index** | The position of a value in a list, starting at 0 |
| **struct** | Your own kind of value, made of named parts |
| **input** | What the person types into the program |
| **error** | A message saying something is wrong, and where |
| **bug** | A mistake in a program |
---
**What next?** When this all feels easy, move on to the
[guide for technicians](for-technicians.md). It covers every part of Finch.