Stroustrop's Rule
Beginners need explicit syntax, experts want terse syntax.
Just finished two weeks of workshops and am exhausted, so this one will be light.
Hanuka Sale
Logic for Programmers is on sale until the end of Chanukah! That's Jan 2nd if you're not Jewish. Get it for 40% off here.
Stroustrop's Rule
I first encountered Stroustrop's Rule on this defunct webpage:
One of my favorite insights about syntax design appeared in a retrospective on C++1 by Bjarne Stroustrup:
- For new features, people insist on LOUD explicit syntax.
- For established features, people want terse notation.
The blogger gives the example of option types in Rust. Originally, the idea of using option types to store errors was new for programmers, so the syntax for passing an error was very explicit:
let file = match File::open("file.txt") {
Ok(file) => file,
Err(err) => { return err; }
}
Once people were more familiar with it, Rust added the try!
macro to reduce boilerplate, and finally the ?
operator to streamline error handling further.
I see this as a special case of mental model development: when a feature is new to you, you don't have an internal mental model so need all of the explicit information you can get. Once you're familiar with it, explicit syntax is visual clutter and hinders how quickly you can parse out information.
(One example I like: which is more explicit, user_id
or user_identifier
? Which do experienced programmers prefer?)
What's interesting is that it's often the same people on both sides of the spectrum. Beginners need explicit syntax, and as they become experts, they prefer terse syntax.
The rule applies to the overall community, too. At the beginning of a language's life, everybody's a beginner. Over time the ratio of experts to beginners changes, and this leads to more focus on "expert-friendly" features, like terser syntax.
This can make it harder for beginners to learn the language. There was a lot of drama in Python over the "walrus" assignment operator:
# Without walrus
val = dict.get(key) # `None` if key absent
if val:
print(val)
# With walrus
if val := dict.get(key):
print(val)
Experts supported it because it made code more elegant, teachers and beginners opposed it because it made the language harder to learn. Explicit syntax vs terse notation.
Does this lead to languages bloating over time?
In Teaching
I find that when I teach language workshops I have to actively work against Strousup's Rule. The terse notation that easiest for me to read is bad for beginners, who need the explicit syntax that I find grating.
One good example is type invariants in TLA+. Say you have a set of workers, and each worker has a counter. Here's two ways to say that every worker's counter is a non-negative integer:
\* Bad
\A w \in Workers: counter[w] >= 0
\* Good
counter \in [Workers -> Nat]
The first way literally tests that for every worker, counter[w]
is non-negative. The second way tests that the counter
mapping as a whole is an element of the appropriate "function set"— all functions between workers and natural numbers.
The function set approach is terser, more elegant, and preferred by TLA+ experts. But I teach the "bad" way because it makes more sense to beginners.
-
Starts minute 23. ↩
If you're reading this on the web, you can subscribe here. Updates are once a week. My main website is here.
My new book, Logic for Programmers, is now in early access! Get it here.