hanki

hanki

A statically typed language with Ruby-flavored syntax, Erlang-style actors, and one effect system underneath both. Pure functions and actions share the keyword def. The ! on a name is what tells them apart.

There are two tiers: a bytecode interpreter with a REPL, and an ahead-of-time compiler. Both are equally supported.

# The smallest program that shows both layers: a pure function and an action.

use io

def greet(name: string) -> string
  "Hello, #{name}\n"
end

def main!() -> () [io]
  io.print!(greet("world"))
end

greet is pure. It has no !, so it can perform no effect at all. main! has one, and [io] says which capability it needs. Run that program under hanki run --deny io and it refuses to start.

Status

The language reference opens with this:

spec-first. Most of what follows describes the target design. The "Implementation status" section near the end tracks what's actually built.

The source is not public yet either, so none of what follows is something you can do today.

Building it

Both tiers come out of one front end. The native one needs a Rust toolchain and LLVM 22:

cargo build --release

The bytecode tier needs neither:

cargo build --release --no-default-features

Then:

hanki new hello
hanki run hello
hanki test hello
hanki build hello

hanki run uses the bytecode interpreter and starts instantly. hanki build compiles through LLVM. A program is required to behave identically on either, and a differential test corpus runs every example both ways to check that it does.