DEV Community

Cover image for I built a programming language that reads like plain English — and compiles to Go
AdriaanLouw
AdriaanLouw

Posted on

I built a programming language that reads like plain English — and compiles to Go

Six weeks ago I had a broken prototype and a bad habit: I build things to 90% and never ship them.

Today, hotgrin v0.5.4 is live — a programming language that reads like plain English, compiles (via Go) to real native executables, and explains your mistakes kindly in English or Afrikaans.

This is the story, the honest technical bits, and why I think you might enjoy it — whether you've never written a line of code or you've written a million.

Impatient? Fair. → Try it in your browser right now — nothing to install. Or go straight to the GitHub repo.
This is a complete hotgrin program:

action discount with price, percent
    give back price minus (price times percent divided by 100)
end action
Enter fullscreen mode Exit fullscreen mode
set total to 897
say "Total: R" plus total
say "After 10% off: R" plus discount with total, 10
Enter fullscreen mode Exit fullscreen mode
Total: R897
After 10% off: R807.3
Enter fullscreen mode Exit fullscreen mode

Get started with hotgrin here.

Learn hotgrin in 27 small steps.

You can even use hotgrin in you favourite AI Assistant, like Claude, ChatGPT, Gemini or Grok.

No semicolons. No curly braces.

Read the language reference here.

And here you'll find hotgrin's roadmap.

Two things you might not expect:

  1. Names can have spaces. set cart total to 0cart total is one name. A small set of reserved connector words (to, of, with, is...) bound names, and longest-match lexing sorts out phrases like is greater than.
  2. Maths behaves like school maths. 7 divided by 2 is 3.5, because that's what a person means. Brackets group. plus joins text or adds numbers and converts between them for you.

Nothing is hidden (the part for the pros)
hotgrin isn't an interpreter with training wheels. It transpiles to Go and
compiles a real binary — hotgrin build --windows hello.hot hands you a
genuine .exe to give to anyone. And you can look behind the curtain any
time:

$ hotgrin reveal hello.hot
Enter fullscreen mode Exit fullscreen mode
package main

import "fmt"

func main() {
    fmt.Println("Hello, world")
}
Enter fullscreen mode Exit fullscreen mode

Types are inferred (whole numbers, decimals, text, truth values, lists,
records), testing is part of the language (test "..." blocks with
expect ... to be ...), error handling is honest (give back problem /
try / if it fails, and unhandled failures are refused before the program
runs), and there's structured concurrency that compiles to goroutines with
the shared state guarded for you.
And when the language doesn't have something? Open the escape hatch:

use go
import "strings"
func shoutCase(s string) string { return strings.ToUpper(s) + "!" }
end go

say shout case with "howzit"
Enter fullscreen mode Exit fullscreen mode

Anything you declare between use go and end go becomes a callable action —
shoutCase reads as shout case. Return (T, error) and hotgrin treats it as fallible, forcing callers into try.

The entire Go ecosystem is one block away.

The Watcher — my favourite part.

Every program is checked before it runs by something I call the Watcher.
It has one iron rule: it only speaks when it can prove something is wrong.
No false alarms, no style nagging. And it explains like a patient friend:

error  line 2: there is no value called 'totall' here —
       is it a typo, or did you forget to set it?
Enter fullscreen mode Exit fullscreen mode

Prefer Afrikaans? Add --af:

fout   reël 2: daar is geen waarde genaamd 'totall' hier nie —
       is dit 'n tikfout, of het jy vergeet om dit te stel?
Enter fullscreen mode Exit fullscreen mode

As far as I know, hotgrin is the only programming language with first-class Afrikaans error messages. The mechanism is general — isiZulu and isiXhosa are on the roadmap, and native speakers are very welcome.

You will never see a raw Go compiler error. That's a promise built into the design: if the Watcher is happy, the generated Go compiles.

v0.5's headline: units of measure:
This was the dream feature in my original spec, and it shipped this week:

set weight to 129 kg
say weight                    # 129 kg
say weight in g               # 129000 g

set walk to 2 km plus 500 m
say "Walk: " plus walk        # Walk: 2.5 km

if 90 min is greater than 1 h
    say "That is more than an hour"
end if
Enter fullscreen mode Exit fullscreen mode

Measurements print themselves, convert with in, and combine across units of the same dimension. And if you add kilograms to metres?

error  line 3: cannot combine kg and m — one measures mass, the other length
Enter fullscreen mode Exit fullscreen mode

Caught kindly, before anything runs.

What else is in the box?
ask "What is your name?" into name — interactive programs

Files: use "std/data"read file / write file (fallible, so the
language makes you handle the failure)

The web: use "std/web"fetch text a URL, json value to pull a
field out by dotted path

Libraries: local files, or straight from GitHub —
use tools from "github.com/user/repo" (fetched with git, cached, @tag
pinning supported)

A cookbook of 21 recipes — every single one is machine-verified to run exactly as printed

A complete worked project
a loan calculator with real amortization maths and tests.

Why I built it:
I'm Adriaan, from Johannesburg. hotgrin started with a frustration: the
first hour of programming shouldn't be about semicolons — but the tools that fix that are usually toys, and nobody wants to learn a toy.

So the rule became: read like English, compile like Go, and never have a
ceiling. The language you learn on Saturday should be one you could ship
with on Monday.

And because learning lands deepest in your own language, the Watcher speaks two of ours.

The other honest confession: I have a long history of building to phase 90
and never shipping. This project broke that pattern — v0.1.0 to v0.5.0, each release tagged, tested (88 tests across 8 packages, CI on every commit), and released with binaries for Windows, Linux, and macOS built automatically.

It's honestly alpha.
Version 0.5.4, rough edges, small standard library, and a public
roadmap that gets reordered by real use — three of v0.3's features came directly from pain I hit writing the cookbook.

Next up: an interpreter mode (no Go install at all), and more Watcher rules.

Try it in the next 60 seconds. Zero install: the browser playground —
type English on the left, watch real Go appear on the right, flip the
Watcher to Afrikaans for fun.

Have Go? go install github.com/hotgrin/hotgrin/cmd/hotgrin@latest

Prefer a download? Prebuilt binaries for Windows, Linux, and macOS.

Then make a file called hello.hot:

say "Hello, world"
Enter fullscreen mode Exit fullscreen mode
hotgrin run hello.hot
Enter fullscreen mode Exit fullscreen mode

The repo is here → github.com/Hotgrin/hotgrin
please, a star helps more than you'd think at this stage, and an issue telling me what confused you helps even more.

That's literally how the roadmap gets written.

Gaan maak iets. Go make something. 😁

hotgrin is MIT-licensed and built in the open. If you teach programming, or you know someone who's always wanted to start — I'd especially love to hear from you.

Top comments (1)

Collapse
 
adriaanlouw profile image
AdriaanLouw

Hi, thank you for reading this post.
This comment is reserved for future comments, thanks.
Ask questions, make suggestions.
Enjoy hotgrin!