curayious Language Lab

The Method — Ten Questions, One Program

The mistake most "learn N languages" projects make is to let the language set the agenda. You end up with a Rust note about ownership, a Go note about goroutines, and an Erlang note about supervision trees — three good notes that cannot be compared to one another, because each was written in the shape its language suggested.

This series inverts that. The questions are fixed and the language is the variable. Every track answers the same ten questions, under the same ten headings, in the same order. What changes is the answer.

The payoff is the comparison matrix: because question 5 is always "the error model", you can read every language's answer to it in one column, side by side, and see the design space rather than eleven unrelated facts.


The ten questions

Q1 · Origin and niche

What problem was it invented for, by whom, and in what year? Who pays for it today? A language's design only makes sense against the constraint it was built under — COBOL's verbosity against 1959 punched cards and non-programmer readers, Go's austerity against Google's compile times, Erlang's process model against a telephone switch that may not stop.

Q2 · Hello, build

Not "hello world" — hello, build. What is the toolchain, how do you compile and run, what is the dependency manager, and what does shipping actually look like? This is where most of the day-to-day friction of a language lives and where tutorials are least honest.

Every track ends this section with a working build script, on this machine, with real paths.

Q3 · Type and memory model

Static or dynamic, strong or weak, inferred or declared, nominal or structural. Manual, GC, ownership, or refcount. And the underneath question: what is a variable? A name for a memory cell (C), a name for an object reference (Java), a name bound to a value in a namespace (Python), a name that owns a value (Rust), an immutable binding (Erlang).

Q4 · The unit of abstraction

What does this language think a program is made of? Functions and structs? Classes? Modules? Processes? Traits? Packages? This is the question that determines what large codebases in the language look like, and it is almost never what the tutorial leads with.

Q5 · The error model

Return codes, errno, checked exceptions, unchecked exceptions, Option/Result, multiple return values, let-it-crash. The biggest single difference between languages, the one that shapes the most code, and the one most tutorials cover last and briefly.

Concretely: what does logagg do when line 31 has a status of 20x?

Q6 · The concurrency model

Threads and locks, green threads, goroutines and channels, actors and mailboxes, async/await, a GIL, or nothing at all. And the honest follow-up: what does the language make easy to get wrong?

Q7 · The idiom test — logagg

Write the benchmark program, idiomatically, and make it produce byte-identical output to every other track. Then write the walkthrough: which lines are this language being itself, and which are the spec forcing your hand?

This is the heart of every track. If you only do one thing, do this.

Q8 · How it fails

The classic footguns, with a real example of each, ideally one you hit yourself while doing Q7. Not a list of trivia — the failures that cost professionals days. Buffer overrun and use-after-free in C. NullPointerException and equals/hashCode in Java. Mutable default arguments and the GIL in Python. Nil-interface-is-not-nil in Go.

Q9 · Read real code

Pick one file from a real, well-regarded open-source project in this language. Read it properly and annotate it. Not a framework's hello-world — a file that a professional wrote for production, where you can see the conventions, the defensive habits, and the parts that exist only because of something that went wrong once.

Q10 · What transfers

The single idea worth carrying to the next language. RAII from C++. Ownership from Rust. "Errors are values" from Go. Supervision from Erlang. Fixed-point decimal from COBOL.

This is the section the series exists for. Everything else is scaffolding for it.


The shape of a track

tracks/NN-<language>/
  README.md        the ten questions, answered
  NOTES.md         the annotated walkthrough of the code, line by line
  logagg.<ext>     the program
  build.ps1        one command, from nothing to a running binary
  build/           gitignored

README.md is what gets published. NOTES.md is the working file — the place for the wrong turns, the compiler errors with the fix that worked, the thing that took two hours. Those are worth more on re-read than the polished version, and they are what the COBOL track's lab notes turned out to be.

On pacing

The original plan was a language a week. Drop that. A track is done when python bench/verify.py <track> prints PASS and the ten headings have something honest under them — which for C might be three evenings and for Python might be one. Calendar pressure on a personal knowledge base produces thin notes, and thin notes are worse than no notes, because you trust them later.

The minimum viable track is Q1, Q2, Q5, Q7, Q10 plus a passing logagg. Everything else can be filled in on a second pass. Publish the minimum; go back when the language comes up at work and you suddenly care about question 6.