Rust's Golden Rule: The Signature Is the Contract (opens in new tab)

Mar 27, 2023

I find myself thinking about a particular design principle of Rust today. I’m not sure I’ve ever seen it named specifically before, but it gets referred to from time to time, and I think it’s an under-rated but very important aspect of why Rust works so well. I was going to refer to it as “the signature is the contract” today, but then I ended up changing it. Regardless of that, if someone else has already written this out somewhere, and used a different name, please let me know!

Magic: the Gathering is a really interesting project. I say “project” rather than “card game” because while it is a card game, it also pioneered a whole bunch of incedental other things that had big effects on related hobbies.

I learned MtG in the late 90s. The rules were a bit different then, but many of them are the same. The very first rule I was taught was sort of the “Magic Golden Rule,” though in today’s Comprehensive Rulebook, there are four of them. This one is still the first, though:

  1. The Magic Golden Rules

101.1. Whenever a card’s text directly contradicts these rules, the card takes precedence. The card overrides only the rule that applies to that specific situation. The only exception is that a player can concede the game at any time (see rule 104.3a).

This rule is the most important rule because it kind of creates the spaces of possibilities for cards: many cards exist to tweak, modify, or break some sort of fundamental rule.

That being said, all these years later, this idea is so pervasive in games like this that it’s barely even considered an actual rule. It’s just part of the physics of the genre, it’s how these games work. Yet it’s critical to the entire enterprise.

Rust also has a rule. It’s kinda funny, because in some senses, this rule is almost the opposite of Magic’s, if you can even stretch the comparison this far. Here it is:

Whenever the body of a function contradicts the function’s signature, the signature takes precedence; the signature is right and the body is wrong.

This rule is also so pervasive in Rust that we take it for granted, but it is really, truly important. I think it is also important for Rust users to internalize the implications of this rule, so that they know why certain things work the way that they do.

Here is the most famous implication of this rule: Rust does not infer function signatures. If it did, changing the body of the function would change its signature. While this is convenient in the small, it has massive ramifications.

Consider this example program:

fn foo(x: i32) -> i32 {
dbg!(x);

x
}

This function prints out x, and then returns it. Nothing fancy going on here, this is just random stuff to make an example. This compiles just fine. But let’s imagine that we have a version of Rust that infers our signatures. So we could type this instead:

fn foo(x) {
Loading more...

Keyboard Shortcuts

Navigation
Next / previous item
j/k
Open post
oorEnter
Preview post
v
Post Actions
Love post
a
Like post
l
Dislike post
d
Undo reaction
u
Save / unsave
s
Recommendations
Add interest / feed
Enter
Not interested
x
Go to
Home
gh
Interests
gi
Feeds
gf
Likes
gl
History
gy
Changelog
gc
Settings
gs
Browse
gb
Search
/
General
Show this help
?
Submit feedback
!
Close modal / unfocus
Esc

Press ? anytime to show this help