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.
| kernel | Halka | C /O2 | Python | vs C |
|---|---|---|---|---|
| recursive calls, fib(35) | 153 ms | 141 ms | 9 344 ms | 1.08x |
| integer arithmetic, 200M | 424 ms | 349 ms | 26 606 ms | 1.21x |
| floating point, 900×900 | 593 ms | 638 ms | 39 158 ms | 0.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 pauses | C++ / Rust |
| Memory safety by default | Rust |
| Arbitrary-precision integers | Python |
| Indentation-structured, readable | Python |
| Errors as values | Go / Rust |
| Lightweight tasks and channels | Go |
| Traits, generics, pattern matching | Rust / ML |
| Compile-time execution, macros | Zig / Lisp |
| Direct C, C++ and Python interop | Zig / Cython |
| Capability-based security | Pony / Deno |
Refused, and enforced
| Exceptions | rule #23 — use Result<T> |
| Function overloading | rule #21 — use generics |
| Lambdas | rule #17 — pass a named function |
| A second interface system | rule #16 — traits do that |
| C-style casts | rule #15 — as or to |
| Ambient authority | rule #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.
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
| Version | Milestone |
|---|---|
| v0.1 | The language runs — locked spec implemented end to end |
| v0.2 | Static type inference, and a native backend at C-level speed. Here now. |
| v0.3 | Ownership and borrow checking as a static pass |
| v0.4 | Enums, match, maps and tasks in the native backend |
| v0.5 | Real C, C++ and Python FFI |
| v0.6 | Self-hosting: the compiler written in Halka |
| v0.7 | Tensors, GPU kernels, compile-time shape checking |
| v1.0 | Frozen semantics, package registry, debugger |
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.