22 KiB
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
Contents
- What is a program?
- Getting Finch ready
- Your first program
- Showing things on the screen
- Boxes with names: variables
- Kinds of values
- Doing math
- Making decisions: if
- Repeating things: loops
- Your own commands: functions
- Lists: many values in one box
- Playing with text
- Asking the user
- Your own kinds of values: structs
- Saving to a file
- When something goes wrong
- Small projects to try
- Cheat sheet
- 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:
- Take two eggs.
- Break them into a bowl.
- 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:
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. It explains the other way.)
To check it works, type:
./build/finch version
You should see something like finch 2.3.0.
3. Your first program
- Open any text editor (for example Text Editor, Kate, gedit or VS Code).
- Type exactly this:
fn main() {
print("Hello!")
}
- Save it in the
Finchfolder ashello.fch. The.fchat the end tells everyone it is a Finch program. - In the Terminal, type:
./build/finch run hello.fch
You will see:
Hello!
🎉 You have just written and run a program.
What did we write?
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 onemain.- The curly brackets
{and}hold everything that belongs tomain, 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:
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:
// 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.
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 =:
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 :=:
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:
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:
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".
fn main() {
temperature := 25
if temperature > 20 {
print("It's warm, wear a t-shirt")
}
}
Add else for "otherwise, do this":
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:
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
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
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
breakleaves the loop right away.continueskips the rest of this round and goes to the next one.
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.
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:
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:
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. .lentells you how many things are in the list.fruits[0]is the first thing. Counting starts at 0, sofruits[1]is the second, andfruits[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
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:
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 lists them all.
12. Playing with text
Text can be glued together with +:
fn main() {
name := "Ola"
greeting := "Hello, " + name + "!"
print(greeting)
}
To glue a number to text, turn the number into text first with str(...):
age := 10
print("Age: " + str(age))
Text has handy tools too:
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:
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(...):
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:
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 outsidemain.Book(title: ..., author: ..., year: ...)makes one book.b.titlereads one part.b.year = 1938changes it.
You can give parts a starting value. Then you don't have to fill them in:
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:
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 (trueorfalse).
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:
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.fchis the file,3is the line number,11is 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
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
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
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
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
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
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
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
// 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. It covers every part of Finch.