Your First Program
Hello, world
Section titled “Hello, world”Put this in hello.sau:
println("Hello, world!")Run it:
saule run hello.sauNaming a file puts the compiler in single-file mode: the script runs
top-to-bottom like a Lua script, and no class Main is required.
Adding types
Section titled “Adding types”Types are checked before a single line executes. On a local the annotation is optional — the initializer implies it — but writing it out is the clearer habit, and parameters and fields have to state theirs.
local name: string = "Arthur"local health: integer = 100local speed: float = 1.5
println(name .. " has " .. health .. " HP")Try changing health to 100.0 and running it again — Saule rejects the
program rather than quietly converting between
integer and float.
A class
Section titled “A class”class Greeter local greeting: string
fn init(greeting: string) self.greeting = greeting end
fn greet(who: string) println(self.greeting .. ", " .. who .. "!") endend
local g = Greeter("Hello")g.greet("world")Fields are declared at the top, fn init is the constructor, and self refers
to the instance. There is no new keyword — calling the class name constructs
an instance.
Handling nothing
Section titled “Handling nothing”A variable cannot be nil unless its type says so. Mark it with ? and the
compiler makes you handle the empty case:
local nickname: string? = nil
-- `??` supplies a fallbacklocal display: string = nickname ?? "no nickname"println(display)
-- `#` needs a definite value, so coalesce before measuringlocal len: integer = #(nickname ?? "")println(len)Drop the ?? "no nickname" and the program stops compiling — a string?
cannot be assigned to a string.
Starting a real project
Section titled “Starting a real project”For anything larger than a script, scaffold a project:
saule init myprojectcd myprojectsaule runsaule init writes a saule.config and an entry file. Running saule run with
no argument — or naming a directory — puts the compiler in project mode,
where the entry file must declare a Main class:
class Main static fn main() println("Hello from a project!") endendWhether the target is a directory is the only thing that chooses between project mode and single-file mode.
Multiple files
Section titled “Multiple files”Project mode resolves imports across your source directories:
-- entities/Player.sauexport class Player local name: string
fn init(name: string) self.name = name end
fn greet() println("I am " .. self.name) endend-- main.saufrom "entities/Player" import Player
class Main static fn main() local p: Player = Player("Arthur") p.greet() endendOnly exported declarations are visible to other files. See
Imports and File Structure for
folder modules, dependencies, and visibility rules.
Passing arguments
Section titled “Passing arguments”Anything after -- goes to your program untouched, and shows up in Os.args():
saule run -- input.txt --verboseNext steps
Section titled “Next steps”- Language Guide — the full tour.
- Project Configuration — what
saule.configaccepts. - CLI Reference —
run,fmt,init.