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.