10,000 Lines Later: When a Tool Became a Compiler - Rob Durst - Gleam Gathering 2026

Lobsters Hottest Events

Summary

At Gleam Gathering 2026, Rob Durst shared how he rewrote a YAML-to-Terraform configuration tool as a compiler using Gleam, and how he came to appreciate the power of type-driven design and the decoder pattern.

<p><a href="https://lobste.rs/s/snppmc/10_000_lines_later_when_tool_became">Comments</a></p>
Original Article
View Cached Full Text

Cached at: 05/24/26, 02:58 PM

**TL;DR:** Rob Durst shares how he rewrote a YAML-to-Terraform configuration tool into a real compiler using Gleam, transitioning from a Ruby programmer to a Gleam advocate along the way, and experiencing the power of type-driven design and the decoder pattern. ## Introduction: Becoming a Gleam Programmer "What makes someone a Gleam programmer?" The talk kicked off with an interactive question. Someone shouted "big eyebrows," "static types," "sponsors," drawing laughs. But Rob believes that becoming a Gleam programmer might just mean writing Gleam. And Gleam itself — is it a programming language, a community, a conference, or its documentation? He hopes the audience will ponder that question throughout the talk. Rob is a Site Reliability Engineer (SRE) from Salt Lake City, Utah, USA. To set the context, he briefly introduces what SREs do. The core idea: he's building a tool — the specifics of the tool don't matter as much as how it evolved into a compiler. ## Background: SLOs and the Button-Clicking Dilemma In his daily work, Rob helps teams implement what's called "Service Level Objectives" (SLOs) — a tool to answer "Is the running system working as expected?" By measuring observable metrics of critical user journeys, you ensure that user expectations are met a certain percentage of the time. Initially, implementing SLOs meant clicking buttons in a monitoring tool. But buttons kept multiplying, and the process wasn't scalable. Users had to click to create configurations, so Rob's team decided to change approach: put the "E" back in SRE (engineering) and build some automation. They discovered that setting up an SLO required answering about 20 questions, but only 5 actually mattered. So they established a specification, aiming to create a "pit of success" — where success is the default outcome. ## When a Tool Becomes a Compiler The team wrote a Ruby tool: it took a YAML specification, generated Terraform configuration, and applied labels. The best practices that were previously documented but never read were now baked into code — once committed, they took effect automatically. After running Terraform, the results were consistent, but you could directly write and commit code. That's when Rob realized: **they had accidentally built a compiler!** The front end was YAML specs, there was a processing layer in between, and the back end generated output. This tool was an attempt to create a simple UI and keep it maintained. But maintaining this Ruby tool became a burden. The problem wasn't Ruby; it was the way they built it. The tool needed maintenance, but Rob wanted it to empower success, not become a liability. ## Choosing Gleam: a Functional, Typed Language Rob told his boss: "I love programming languages — can I just write a language?" He'd written toy languages before, but no one had used them. This time, people actually had to work with his language. He created an open-source compiler called **Caffeine**: it generates reliability artifacts (SLOs) from service level/expectation definitions (untyped declarative YAML). Since it was built in his spare time, what language to use? Rob wanted something functional, because compilers have many stages best kept isolated and pure; he needed types, because types make compilers easier to write; he especially wanted algebraic data types and pattern matching. One day while running, he listened to the podcast *Type Theory for All*, specifically an episode with Ryan Brewer on learning programming languages by yourself. Halfway through, a language called **Gleam** was mentioned: "functional, typed, algebraic data types, good pattern matching." Rob thought: "That hits all the marks." ## Rewriting: YAML Parsing, Testing, and Type Enforcement Why stick with YAML? Because people like YAML. More practical reasons: readability is decent, most languages have YAML parsers, and if you wanted syntax highlighting on GitHub you'd need 200+ repositories, and writing your own front end would take forever. One point worried Rob: Gleam was less than two years old at the time; the first YAML library he found had only 7 stars and 11 commits. But Gleam can interoperate with Erlang, and that library actually wrapped the mature Erlang library Yamerl — it was just Rob's "Ruby brain" that felt uneasy. Everything worked out fine, and he ended up loving that library. For the back end, he found no one had written a Terraform generator library — it seems to be a universal problem, not just Ruby. On testing: As a Ruby programmer, Rob was used to BDD style (`describe`/`it`). He wrote a test helper and asked on Discord: "Why isn't anyone doing this?" Within 7 minutes someone replied — also a Ruby convert — who empathetically said: "I get you, but don't do that." Excellent advice. Rob dramatically switched to "table-driven tests" (originating from the Go world, with Dave Cheney's great article): tuples of (test name, input, output) in an array, plus extractors. Ugly but effective — maybe a micro-pattern worth developing in the community. In the end, **Rob finished the compiler in one week using Gleam**. The tool isn't in production but is close to it; people have to use it because that's how the company does reliability. ## Type-Driven Design: From Extractors to Decoders Now that he had a compiler, it was time to do compiler things. Initially there were 20 clicks, then the specification language had only 5 questions. Rob came across an article on "type-driven design," whose core idea is "make illegal states unrepresentable." He wanted to bring types into the previously untyped specification language. For example, a threshold should be a float, but in the old language you could give it an apple, a pear, or even your favorite café list — not good. How to implement? At first Rob used `panic` (it was his third day using Gleam). He formed an "extractor pattern" using the Glamour library: get a node and assert it's a float. He thought this was the greatest, so he forked Glamour, convinced the whole world should use these extractors. But soon there was a combinatorial explosion: every possible combination required writing an extractor — so bad that even he didn't want to use his own library. He looked at how others did it. Gleam compiles to Erlang, runs on the BEAM, many people build web services and like JSON. There's a Gleam JSON library with more stars and activity. In the Ruby/Rails world we often say "convention over configuration" — same applies here: follow the common path, more people have walked it. Scrolling down on the JSON library page, he saw "decoders." Extractors existed, but decoders were better. The standard library provides a mechanism to decode from the `dynamic` type. You could replace `extract_float` with `decode_float` and fix the `panic` to properly return `Result`. Now with more idiomatic Gleam, sacrificing YAML for JSON (actually "equally ugly"). With type enforcement, he started adding more types, making the language a "pit of success." From the parsing stage to semantic analysis, everything relied on a globally acceptable type. Anywhere you needed to convert to string or parse a type, you used this type — so pattern matching became exhaustive, giving you a to-do list. Awesome. **Adding a type only takes about 100 lines of code.** In the Ruby world (poorly modeled), a similar change would require five times the difference. Eventually Rob added his own front end, using the `result.try` pattern, which was very helpful in a recursive descent parser. ## Lessons and Achievements This compiler, though modest in scale, marks Rob's transition from Ruby to Gleam. Through building a compiler, he learned type-driven design, the decoder pattern, and truly understood what "pit of success" means. He ends the talk with a lighthearted remark: "I hope every future Gleam conference quotes me on that." **Source:** https://www.youtube.com/watch?v=wVQLEAHrwrI

Similar Articles

Reasons and Resources for Learning The Gleam Programming Language

Lobsters Hottest

Introduces five major reasons to learn the Gleam programming language (cross-platform, type safety, concise design, functional paradigm, active ecosystem) along with practical introductory resources, from an official website tour to Exercism.

@GitHub_Daily: When developing a project with Claude Code, if the codebase is large, every exploration of the code structure requires scanning a bunch of files, resulting in many tool calls, slow speed, and heavy token usage. So I found CodeGraph, an open-source tool that pre-builds a semantic knowledge graph for the codebase, allowing Claude Code to query the graph directly instead of scanning files one by one...

X AI KOLs Timeline

CodeGraph is an open-source tool that pre-builds a semantic knowledge graph for codebases, allowing Claude Code to query the graph instead of scanning files one by one, thereby significantly reducing tool calls (by 92%) and improving exploration speed (by 71%). It supports 19 programming languages and 13 frameworks.

@axichuhai: Found an open-source tool that makes Claude even better — just a 65-line Markdown file, already reached 130k+ stars on GitHub. Inspired by Karpathy's observation that models like to guess when uncertain, write overly complex code, and quietly change things they shouldn't touch...

X AI KOLs Timeline

An open-source 65-line Markdown file that summarizes 4 programming rules for Claude to improve code quality and save tokens. It has garnered 130k+ stars on GitHub, inspired by Karpathy.

OTP and Gleam

Lobsters Hottest

Gleam language creator Louie deeply explains the core concepts of OTP, and how Gleam works with OTP in a type-safe manner, achieving fully compatible inter-process communication and supervisor building blocks with Erlang/Elixir.

@dongxi_nlp: https://x.com/dongxi_nlp/status/2065200644802101633

X AI KOLs Timeline

The article proposes that in a Coding Agent, tool invocations should be treated as contracts rather than simple functions, emphasizing the Harness's adjudication role in verification, permissions, lifecycle management, and others, and discusses in detail the composition and lifecycle of tool contracts.