The answer section is a bit of a work in progress at the moment. Kindly be patient. I am working on providing answers to every exercise.

Note that many exercises may have multiple possible answers. If your code looks a bit differnt from mine, but produces valid results, then your answer is fine. If you are uncertain, you can always contact me.

3. First programs

Exercise 1

You will of course have to replace my name with your own. (The exercise specification is vague enough that you could print your first name, your last name or both.)

1
2
3
4
5
6
7
package main

import "core:fmt"

main :: proc() {
    fmt.println("Lorenzo")
}

Exercise 2

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17

package main

import "core:fmt"

main :: proc() {
    fmt.println(1)
    fmt.println(2)
    fmt.println(3)
    fmt.println(4)
    fmt.println(5)
    fmt.println(6)
    fmt.println(7)
    fmt.println(8)
    fmt.println(9)
    fmt.println(10)
}

If you quoted the numbers (fmt.println("1")), that is perfectly fine as well. The println procedure works with both numbers and strings.

Using what we have learned so far, a program to print the numbers 1-10,000 would be slightly more than 10,000 lines long. It goes without saying that such a program would be highly inefficient.

Exercise 3

All the output will be on a single line:

$ odin run .
Hi there!I am learning OdinIt's a lot of fun so far.$

Depending on the system you use and how it has been configured, you may or may not see the prompt at the end of the output as well.

So println means “print and jump to the next line in the terminal”, wheras print stays on the same line after printing.

Exercise 4

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
package main

import "core:fmt"

main :: proc() {
    fmt.println("January")
    fmt.println("February")
    fmt.println("March")
    fmt.println("April")
    fmt.println("May")
    fmt.println("June")
    fmt.println("July")
    fmt.println("August")
    fmt.println("September")
    fmt.println("October")
    fmt.println("November")
    fmt.println("December")
}

However, if you are not English-speaking, or you are learning some language apart from English, why not print in that other language. Quoted text (called string literals) is Unicode in Odin, which means you can use characters that are not part of the Latin alphabet.

Here, for instance, is the same program but with the month names in Ga instead. If you were learning Ga, you could run this program to remind yourself of the names of the months.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
package main

import "core:fmt"

main :: proc() {
    fmt.println("Aharabata")
    fmt.println("Oflɔ")
    fmt.println("Otsokrikri")
    fmt.println("Abɛibe")
    fmt.println("Agbiɛnaa")
    fmt.println("Otukwajaŋ")
    fmt.println("Maawɛ")
    fmt.println("Manyawale")
    fmt.println("Gbo")
    fmt.println("Antɔŋ")
    fmt.println("Alemle")
    fmt.println("Afuabe")
}

Right now, you really just want to practice writing code as much as possible, so if you speak 5 languages, take the opportunity to write the program 5 times.

Exercise 5

There are two errors you need to fix:

  1. In Odin, the declaration of the main procedure is main :: proc not just main (line 5)
  2. In Odin, string literals are enclosed in a pair of double quotes, not single ones (line 7)

I can’t stress this enough: get familiar with the error messages that the Odin compiler gives and use them as a guide to finding and fixing the problem.

Exercise 6

The output of the program is:

$ odin run .
I am currently learning Odin

The new concept here is a variable, something you will start to look at in the next lesson. Try changing lang := "Odin" to lang := "Go" or something like that and see how the output changes.

Exercise 7

Try taking a very basic program like hellope and capitalizing proc and see the result. Here is the modified program:

1
2
3
4
5
6
7
package main

import "core:fmt"

main :: PROC() {
    fmt.printfln("Hellope!")
}

This is what happens, when I compile:

lorenzo@orthanc:~/Temporary/odin$ odin run .
/home/lorenzo/Temporary/odin/main.odin(5:1) Error: 'main' is reserved as the entry point procedure in the initial scope
	main :: PROC() {

In this case, the error message might not be the most explanatory, but we can safely conclude that Odin is case sensitive. Note however, that this will work fine:

1
2
3
4
5
6
7
package main

import "core:fmt"

main :: proc() {
    fmt.printfln("HELLOPE!")
}

That is because Odin doens’t really care about what you put between the double quotes (there are a few exceptions that we will look at later, such as putting a double qoute between an pair of double quotes).

If you think about it, it’s just like in English. “I ain’t got no book” is unfortunately not considered proper English. If you were studying English and wrote this in an exam, you’d lose points.

However, if you were writing a book and wrote something like

“I ain’t got no book”, he said.

That would be perfectly fine, since you are quoting exactly what somebody said. So Odin follows similar rules to English.

Exercise 8

The hellope program is perfect for these types of small experiments. Simply change main to start and try to run.

lorenzo@orthanc:~/Temporary/odin$ odin run .
/home/lorenzo/src/hellope/main.odin(1:2) Error: Undefined entry point procedure 'main'
	package main
	 ^

That doesn’t work. Conclusion: every Odin program must have a special procedure called main, which acts as the starting point of the program.

It is possible to write things that are not programs, like libraries in Odin as well. As you will see later, they are not required to have a main procedure.

Exercise 9

There was only one bug in the program, println should be all lowercase. Fix that and the program runs well. Do pay attention to the error message before you fix it.

Exercise 10

Here are the errors:

  1. package should not be capitalized (line 1)
  2. The import should be “core:fmt”, not just “core” (line 3)
  3. It should be main :: proc() not proc :: main() (line 5)
  4. println is misspelled. (line 6)

I usually fix one error at a time and try to rerun the program to see if it is working or, if not, how the error output has changed.

It can feel a bit overwhelming at first when you get a long list of error messages. You need to learn to filter it out and only focus on one thing at a time. For example, look at the very first error message and try to figure out what caused that.

Exercise 11

Hopefully you looked at the program first and guessed what it would do before running it in order to confirm.

Here is the output:

a + b = 8
a - b = 2
a * b = 15
a / b = 1

This program uses two variables: a and b. It also uses four different arithmetic operators: plus, minus, multiply and divide.

4. Variables and Conditionals

Exercises 1

Since you haven’t learned how to use fmt.printfln at this stage, getting the output gets a bit finicky.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16

package main

import "core:fmt"
import "core:time"

main :: proc() {
    n := time.now()
    h, m, s := time.clock_from_time(n)

    fmt.print(h)
    fmt.print(":")
    fmt.print(m)
    fmt.print(":")
    fmt.println(s)
}

Note the last print statement is println to ensure that we get a newline at the end of the output. You could also do the following, if you are okay with space in between each part.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
package main

import "core:fmt"
import "core:time"

main :: proc() {
    n := time.now()
    h, m, s := time.clock_from_time(n)

    fmt.println(h, ":", m, ":", s)
}

Notice however, that this solution isn’t exactly according to the specification. This could be a problem, if our program was a part of a larger system where some other part of the system is going to read the time from our program. Those extra spaces could be a problem, if that’s not what the other side expects. That is why it is important in software development, where different teams work on different parts of a larger system, that everybody follows the same spec and does so exactly.

The proper solution to this exercise would have been to use the printfln function that I mentioned above. This version also prepends a zero before any part that is less than 10. We will learn about formatting text with printf and printfln in future lessons.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12

package main

import "core:fmt"
import "core:time"

main :: proc() {
    n := time.now()
    h, m, s := time.clock_from_time(n)

    fmt.printfln("%02d:%02d:%02d", h, m, s)
}

5. Command Line Args