Your first run
Put something on screen.
Create a file hello.hl:
fn main() {
println("Hello from Hale.");
}
Run it:
hale run hello.hl
Hello from Hale.
hale run compiles your program and runs it in one step — it’s
the same native code hale build produces, just executed
immediately and not left on disk. When you want the artifact to
keep and ship, build it:
hale build hello.hl
./hello
Same compiler, same output: run is the fast inner-loop shape,
build is for the binary you deploy. There’s no separate
interpreter, so anything that runs under build runs identically
under run.
What’s here
-
fn main()is the entry point, the same as it is in C, Go, or Rust. A Hale program starts by calling it. -
println(...)prints its arguments followed by a newline. It takes any number of arguments and concatenates them — there’s no format string:fn main() { let name = "Hale"; println("Hello from ", name, "."); } -
Statements end with
;. Newlines are just whitespace — they don’t end statements. Source is ASCII outside of string literals and comments.
Comments are C-style:
// a line comment
/* a block comment */
That’s the whole surface you need to start. The next chapter introduces variables and the value types — the vocabulary every Hale program is built from.
hale runand imports. A single file’simport "..." as ...;directives are resolved byhale runjust ashale buildresolves them. The one gap is the ad-hoc directory form (hale run ./dir), which bundles the directory’s files without cross-seed import resolution — usehale build ./dirfor a multi-file project that imports libraries.
Build modes, diagnostics, and debugging
A few switches worth knowing from day one:
- Faster iteration:
hale build --dev(orHALE_DEV=1) uses a lighter optimization pipeline — noticeably quicker builds while you’re in an edit-run loop. Release builds default to-O3tuned for your CPU. - Where did the build time go?
HALE_TIME=1 hale build app.hlprints per-phase wall times. - Editor integration:
hale check app.hl --jsonemits one JSON object per diagnostic (file, line, col, severity, message) on stdout.hale checkitself runs in ~10 ms even on large programs, so a save-hook is all an editor needs. - Real debugging: binaries carry DWARF line tables by default —
gdb ./app,break app.hl:42, backtraces with real file:line, and ASAN reports that point at the exact source line. Zero runtime cost; opt out withLOTUS_NO_DEBUGINFO=1.