v0.2 · compiles to native · pre-1.0

One assignment operator.
One separator.
One way to write things.

Halka is a general-purpose language whose entire surface grammar rests on two rules: : associates, , separates. Everything else follows. Small enough to learn in an afternoon — and it compiles to native code as fast as hand-written C, with memory safety, no lifetime annotations, and real multicore parallelism.

What it looks like

# Types are inferred. Annotate when you want to.
let name: "HALKA"
let age: int: 25

greet(who: string: "world"),
    give "Hello, {who}!"

say greet(name)

if age >= 18,
    say "adult",
else,
    say "minor"

# Collections, slices, ranges.
let numbers: [10, 20, 30, 40]
say numbers[1:3]        # [20, 30]
say numbers[-1]         # 40
for i in 1..=3,
    say i
# Errors are values. There is no try/catch.
parse_age(text),
    let r: text to int,
    if r is error,
        give Error("not a number: {text}"),
    else,
        give r

match parse_age("42"),
    Ok(value),
        say value,
    Error(message),
        say message

# Cleanup survives an early `give`.
read_config(),
    let file: open("config.hk"),
    defer close file,
    give parse(file)

# Concurrency is built in.
let a: start fetch("/users"),
let b: start fetch("/orders"),
let users: await a,
let orders: await b

Get started

The reference toolchain needs Node 22.6 or newer and has no runtime dependencies.

git clone https://github.com/Nulfied/halka.git
cd halka/compiler
npm link

halka run ../examples/hello.hk
halka repl

halka run

Run a program.

halka build

Compile to a native binary.

halka check

Parse and check without running.

halka fmt

Format to the one canonical style.

halka test

Run test_*.hk files.

halka repl

An interactive session.

halka lsp

The language server, over stdio.

As fast as hand-written C

Halka compiles to C99 and hands it to whatever C compiler the machine already has. Halka and C below were built by the same compiler with the same flags, so this measures the code Halka generates. Best of 5; all three produce identical output.

kernelHalkaC /O2Pythonvs C
recursive calls, fib(35)153 ms141 ms9 344 ms1.08x
integer arithmetic, 200M424 ms349 ms26 606 ms1.21x
floating point, 900×900593 ms638 ms39 158 ms0.93x

What the GIL costs

The same workload, single-threaded and then across 8 threads.

halka  1 thread :   45 ms
halka  8 threads:   14 ms   speedup 3.20x   <- real cores

python 1 thread : 1863 ms
python 8 threads: 3681 ms   speedup 0.51x   <- the GIL

Adding threads made Python twice as slow — pure-Python threads cannot run bytecode concurrently. Halka's parallel: lowers to real OS threads and the runtime has no interpreter lock. Methodology and caveats →

What Halka takes, and what it refuses

Taken

Deterministic cleanup, no GC pausesC++ / Rust
Memory safety by defaultRust
Arbitrary-precision integersPython
Indentation-structured, readablePython
Errors as valuesGo / Rust
Lightweight tasks and channelsGo
Traits, generics, pattern matchingRust / ML
Compile-time execution, macrosZig / Lisp
Direct C, C++ and Python interopZig / Cython
Capability-based securityPony / Deno

Refused, and enforced

Exceptionsrule #23 — use Result<T>
Function overloadingrule #21 — use generics
Lambdasrule #17 — pass a named function
A second interface systemrule #16 — traits do that
C-style castsrule #15 — as or to
Ambient authorityrule #45 — declare requires

The compiler does not merely omit these — it recognises them and says which rule removed it, and what to write instead:

error[E0303]: `catch` is reserved and is not
             part of Halka V49
  --> app.hk:12:5
   |
12 |     catch e,
   |     ^^^^^
  = locked rule: #23 — Exception model
  = help: Halka has no exception system.
          Match on Result<T>.

The specification is locked

54 rules, frozen

The whole syntax lives in one document, transcribed from the authored design records which are archived unchanged. CI fails if the two ever drift. Changing a locked rule needs a numbered proposal and a version bump.

One program, one parse

Rule #52 forbids the parser from guessing. Where two locked forms look alike, a numbered resolution gives the deterministic answer — and may only narrow a locked rule, never contradict it. Each one has a test.

The 54 locked rules →    Grammar resolutions →

Editor support

halka lsp speaks LSP 3.17 over stdio with no dependencies: diagnostics, hover, completion, go-to-definition, symbols, rename and formatting. Highlighting ships as both a TextMate and a Tree-sitter grammar.

VS Code

Extension in editors/vscode.

Neovim

lspconfig plus Tree-sitter.

Helix

Drop into languages.toml.

Zed

Dev extension in editors/zed.

Sublime Text

TextMate grammar and the LSP package.

Anything else

Point any LSP client at halka lsp.

Where it is going

VersionMilestone
v0.1The language runs — locked spec implemented end to end
v0.2Static type inference, and a native backend at C-level speed. Here now.
v0.3Ownership and borrow checking as a static pass
v0.4Enums, match, maps and tasks in the native backend
v0.5Real C, C++ and Python FFI
v0.6Self-hosting: the compiler written in Halka
v0.7Tensors, GPU kernels, compile-time shape checking
v1.0Frozen semantics, package registry, debugger

The full roadmap →

Help build it

The syntax is locked; everything else is open.

  • Type checker — the largest remaining piece.
  • C backend — well-scoped and self-contained.
  • Standard library — written in Halka.
  • Adversarial tests — find a program with two parses. Rule #52 says that is a bug.

How to contribute →