Skip to content

Getting started

Halis installs with one command. The release archive carries the whole toolchain — the compiler hlc and the formatter hlfmt as binaries, the standard library std/ and the freestanding runtime core/ as source — so you need no C compiler, no make and no Python.

Terminal window
curl -fsSL https://raw.githubusercontent.com/mhieuhonda/halis-lang/main/install.sh | sh

The installer picks the archive matching your platform, verifies its SHA-256 against the release’s own SHA256SUMS before unpacking anything, installs into /usr/local (or ~/.local if that is not writable), and then runs its own acceptance gate: it compiles a program that imports std.result and formats that program twice — the second pass must equal the first.

Create hello.hls:

fn greet(name: str) -> str {
return "Hello, " + name + "!"
}
fn main() -> int uses IO {
println(greet("Halis"))
println("A high-security programming language, compiled native.")
println("Compiled by a compiler written in HLS itself.")
return 0
}

Two things are already different from most languages:

  • greet has no uses clause, so the compiler guarantees it is pure.
  • main declares uses IO — without it, the call to println is a compile error, not a warning.

hlc emits C, and the system C compiler turns that into a native binary:

Terminal window
hlc hello.hls hello.c
cc -o hello hello.c -lm -pthread
./hello
Terminal window
hlc --check hello.hls

--check type-checks and effect-checks the program without emitting code. It is the fastest way to see the effect error message:

error: function 'main' calls 'println' which requires effect 'IO'
not declared (declared: (none - pure); missing: IO)
Terminal window
hlc --audit hello.hls

--audit prints, for every function, the capabilities it declared and the capabilities the compiler computed by walking the call graph. A function that declares nothing and computes nothing is proven pure; a mismatch is a violation with the offending call chain named.

Command What it does
hlc prog.hls prog.c Compile HLS to C
hlc --check prog.hls Type- and effect-check without generating code
hlc --audit prog.hls Print the capability and taint-flow report
hlc --emit llvm prog.hls out.ll Emit LLVM IR instead of C
hlc --sandbox DIR prog.hls Confine file builtins to DIR
hlfmt -w prog.hls Format the file in place
hllint prog.hls Run the safety-first linter
hltest Run the in-language test suite

If you want to work on the compiler itself, or you are on a platform without a prebuilt archive:

Terminal window
git clone https://github.com/mhieuhonda/halis-lang.git
cd halis-lang
make bootstrap # ~20 s: cc builds the committed snapshot, HLS takes over
make run F=examples/hello.hls
make test

make bootstrap compiles the committed C snapshot and then requires the freshly built compiler to re-derive that snapshot byte for byte. A stale or hand-edited snapshot fails the build loudly. See the bootstrap law.

The VS Code extension lives in editors/vscode/halis/ and bundles the language server, the formatter, the linter and the debug adapter. Neovim syntax and plugin files are in editors/neovim/.