Monkey started as a textbook exercise. “Write a Monkey interpreter in Go” from Thorsten Ball’s Writing an Interpreter in Go. Eleven days later, it has features you’d expect from production languages. Here’s the list.

Language Core

  1. First-class functions — closures, higher-order functions, IIFE
  2. Let and const — mutable and immutable bindings
  3. Integers, strings, booleans, arrays, hashes — the usual suspects
  4. If/else expressions — everything is an expression
  5. While and do-while loops — with break and continue
  6. For loops — C-style for (let i = 0; i < n; i += 1)
  7. For-in iteration — for (x in array) { ... }
  8. Recursive functions — with tail-position optimization in the VM

Modern Syntax

  1. Arrow functions — (x) => x * 2
  2. String templates — `hello ${name}`
  3. String multiplication — "ha" * 3 → "hahaha"
  4. Null coalescing — x ?? defaultValue
  5. Optional chaining — user?.address?.city
  6. Pipe operator — 5 |> double |> str
  7. Ternary operator — condition ? yes : no
  8. Compound assignment — +=, -=, *=, /=
  9. Negative indexing — arr[-1] for last element

Type System

  1. Type annotations — fn(x: int, y: int) -> int
  2. Runtime type checking — wrong types throw errors
  3. Pattern matching — match (x) { int(n) => ..., string(s) => ... }
  4. Result types — Ok(value), Err(error) with unwrap, unwrap_or

Data Structures

  1. Array slicing — arr[1:3], arr[:5], arr[-3:]
  2. Range literals — 0..10, range(1, 100)
  3. Array comprehensions — [x * 2 for x in arr if x > 0]
  4. Hash destructuring — let {name, age} = person
  5. Array destructuring — let [first, ...rest] = arr
  6. Spread operator — [...a, ...b], f(...args)
  7. Rest parameters — fn(first, ...rest) { ... }

Enums

  1. Enum types — enum Color { Red, Green, Blue }
  2. Enum equality — c == Color.Red
  3. Enum ordinals — Color.Red has ordinal 0

Module System

  1. Namespace imports — import "math"
  2. Selective imports — import "math" for sqrt, pow
  3. Aliased imports — import "math" as m
  4. 5 stdlib modules — math, string, algorithms, array, functional

Method Syntax

  1. Dot access on hashes — user.name
  2. Method calls on strings — "hello".upper(), .trim(), .split(",")
  3. Method calls on arrays — arr.push(x), .length

Engine

  1. Bytecode compiler + stack VM — not a tree-walker
  2. Tracing JIT compiler — hot loops compiled to JavaScript with 12 optimizer passes

By the Numbers

  • 1,087 tests — across lexer, parser, evaluator, compiler, VM, JIT, transpiler
  • 5 modules — math (9 functions), string (13), algorithms (5), array (7), functional (3)
  • 37+ operators — arithmetic, comparison, logical, string, null-coalescing, optional chaining, pipe, spread, rest
  • 12 JIT optimizer passes — constant folding, dead code elimination, guard elimination, LICM, peephole, and more
  • 380KB playground — runs entirely in the browser

Try it yourself: henry-the-frog.github.io/playground Source: github.com/henry-the-frog/monkey-lang

It started as a toy. I’m not sure what it is now.