Harding is a Smalltalk dialect written in Nim. It keeps the distinguishing features of Smalltalk — live objects, messages, blocks, the image-like feel — while fitting into modern tooling and staying able to call straight into Nim and C libraries.
The interpreter is a stackless, AST-based one with classic green threads in the Smalltalk style, which is the interesting engineering problem underneath: real coroutines without giving up a simple evaluator.
"Hello, World!" println
Point := Object derivePublic: #(x y)
Point>>distanceFromOrigin [ ^ ((x * x) + (y * y)) sqrt ]
p := Point new
p x: 3; y: 4
p distanceFromOrigin println
- Genuine Smalltalk — classes, inheritance, blocks and non-local returns.
- Nim and C interop — reach into the ecosystem without FFI ceremony.
- Green threads — stackless AST interpreter, no OS threads required.
Bona, the IDE
Harding is not just a REPL. Bona (Bonadventure IDE) is a GTK4 IDE for the
language, and the interesting part is that it is written in Harding — the
windows, browser, inspector and editor logic are Harding source under
lib/gui/bona/, several thousand lines of it, sitting on a thin Nim binding
layer that exposes GTK. So the language gets used at real scale instead of only
in examples, and a GUI toolkit is reachable from Smalltalk-style code.
It ships the tools a Smalltalk environment is expected to have:
- Workspace — the code editor, with Do It, Print It and Inspect It.
- System Browser — browse classes by library (Core, Collections, GUI, IDE).
- Inspector — examine object slots and values.
- Transcript — the output console for logging and results.
- Terminal — an embedded VTE terminal for shell and agent workflows.
- Launcher — the window that opens everything else.
The IDE also serves itself over MCP, so an agent can reach into a live Bona and inspect the running system.
Granite, the compiler
Granite is Harding’s native compiler: it takes Harding source and emits Nim, which then goes through Nim’s C backend to a native binary. That gives you two ways to run the same code — interpret it for the live-coding feel, or compile it when you want a real executable with real performance:
granite compile src/main.hrd -o src/main.nim
granite build src/main.hrd --release -o myapp
Granite runs the full Harding VM while compiling, specifically so it has the
complete live class model in hand — that is what makes the generated code
accurate instead of a syntactic translation. Bona is itself built with it
(-d:granite), which is the kind of thing you only do once your compiler is
good enough to depend on.