The grammar that grows a forest

Mar 8, 2026 · Microblog #14
generative fractals biology

Seven presets: fractal tree, fern, Koch snowflake, Dragon curve, Sierpiński triangle, bush, Hilbert curve. Space cycles presets; arrow keys adjust depth and angle.

In 1968, Aristid Lindenmayer was a Hungarian biologist at the University of Utrecht trying to describe how algae cells divide. He needed a notation that captured something Chomsky's grammars couldn't: the fact that all cells in a filament divide at once, in parallel, not one after another in sequence. So he invented his own formal grammar, applied every rule simultaneously to every symbol, and called the result a parallel rewriting system. He was not thinking about art.

The core idea is almost aggressively simple. You start with an axiom — a seed string like F — and a table of rewrite rules. At each step, every symbol in the string expands according to its rule. Apply four iterations of F → FF+[+F-F-F]-[-F+F+F] and the string grows to roughly 14,000 characters. Feed that string to a turtle that treats F as "draw forward," +/- as turns, and [/] as push/pop stack, and you get a branching tree indistinguishable from hand-drawn botanical illustration.

The entire expansion engine is eight lines:

function produce(axiom, rules, iterations) {
  let s = axiom;
  for (let i = 0; i < iterations; i++) {
    let n = '';
    for (const ch of s) {
      n += rules[ch] || ch;
    }
    s = n;
  }
  return s;
}

That's the whole engine. No recursion, no tree structure, no clever data structure. Each character either matches a rule and expands, or passes through unchanged. The exponential growth is implicit: a string of length k with all characters matching rules becomes a string of average-rule-length × k after one step. At depth 5 for the fern preset, the output string has roughly 32,000 characters. The turtle walks every one of them in a single pass.

What Lindenmayer couldn't have expected in 1968 is that his grammar for algae would produce, with different rules and angles, the Koch snowflake (angle 60°), the Hilbert space-filling curve (angle 90°), the Dragon curve, and the Sierpiński triangle. The same formalism that models cell division also exhausts a plane. Prusinkiewicz made this visual in 1986 by connecting L-systems to LOGO turtle graphics — a decision that turned a theoretical biology tool into one of the most productive notations in procedural generation.

The depth control in the explorer reveals something worth seeing slowly: at depth 1 or 2, you're looking at a skeleton. By depth 4 or 5, the full self-similar structure is locked in. Depth 6 starts to stress the browser. The string length scales exponentially, but the picture barely changes after a certain point — each additional depth level fills gaps too small to distinguish at screen resolution. The form converges before the computation does.

← Back to showcase