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 iterationfor (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 coalescingx ?? defaultValue
  5. Optional chaininguser?.address?.city
  6. Pipe operator5 |> double |> str
  7. Ternary operatorcondition ? yes : no
  8. Compound assignment+=, -=, *=, /=
  9. Negative indexingarr[-1] for last element

Type System

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

Data Structures

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

Enums

  1. Enum typesenum Color { Red, Green, Blue }
  2. Enum equalityc == Color.Red
  3. Enum ordinalsColor.Red has ordinal 0

Module System

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

Method Syntax

  1. Dot access on hashesuser.name
  2. Method calls on strings"hello".upper(), .trim(), .split(",")
  3. Method calls on arraysarr.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.