Tour: Start

Let's start off with a very simple example. We'll write a program that increments a counter from 0 to 100, printing the multiples of 10 to the console as we go.

namespace program;

import gu4::Out;

value class Program {
    entry fn main() -> void {
        let mutable counter = 0;

        for i in 0..100 {
            counter = counter + 1;
            if counter % 10 == 0 {
                Out::println("counter reached: " + counter);
            }
        }

        Out::println("Done!");
    }
}

Most of this code should be familiar to you, but you will notice a few trivial differences from the likes of Java or C++:

One less-trivial difference is the presence of keyword mutable in the declaration of variable counter. In Guardian, the bindings of fields and local variables are immutable by default. Making a binding mutable means that you won't be able to share it between threads, even if bound to a type which is normally safe to share.

Guardian Toolchain

To compile and run this program in one shot, you can use the grun tool. Assuming you have the grun tool in your path, and a file called program.gu with your Guardian code in it, you can invoke grun like so:

$ grun program.gu

You can pass multiple files to grun to compile them all. If there is a single entry fn across all the files, it will be invoked. If there are multiple, you will have to set the entryClass env var to indicate which class contains the entry point of the program.

$ grun MainProgram.gu HelperClass.gu
$ entryClass=Program1 grun Program1.gu Program2.gu

If you insist, you can also use gu4c (the Guardian v4 compiler) to compile the program to the chosen target. You will then be responsible for the rest of the build process. As of writing, the only supported backend is Java, so that entails invoking javac and java on the output of gu4c. The compiler will generate a .gu4manifest.json file which lists all the generated files and their dependencies.

$ gu4c -o path/to/output/dir program.gu

If you want to run the test suite, that's grunt:

$ grunt

Both grun and grunt are written in the Flour Language, so you will need that in your path as well.

Notebook Server

If you happen to be developing on the Flour Notebook Server, you will need cell magics to interact with grun.

In the first cell of a notebook, you will need the following:

from flour import grun

With that executed, you can use the %%grun cell magic to execute a Guardian program.

%%grun
namespace notebook;

import gu4::Out;

value class Main {
    entry fn main() -> void {
        Out::println("Hello, notebook!");
    }
}

Next Steps

When you execute the program with grun, you should see something like the following:

[grun] Invoking gu4c... (may take a while if gradle needs to rebuild the compiler)
[grun] Invoking javac...
[grun] Executing your program (entry class: program.Program)
counter reached: 10
counter reached: 20
counter reached: 30
counter reached: 40
counter reached: 50
counter reached: 60
counter reached: 70
counter reached: 80
counter reached: 90
counter reached: 100
Done!

Now, let's get parallelizing.

Next page: Counting in Parallel