
Principle of Least Astonishment - geerlingguy
https://wiki.c2.com/?PrincipleOfLeastAstonishment
======
threatofrain
Yukihiro Matsumoto, creator of Ruby:

> Everyone has an individual background. Someone may come from Python, someone
> else may come from Perl, and they may be surprised by different aspects of
> the language. Then they come up to me and say, 'I was surprised by this
> feature of the language, so Ruby violates the principle of least surprise.'

> Wait. Wait. The principle of least surprise is not for you only. The
> principle of least surprise means principle of least my surprise. And it
> means the principle of least surprise after you learn Ruby very well. For
> example, I was a C++ programmer before I started designing Ruby. I
> programmed in C++ exclusively for two or three years. And after two years of
> C++ programming, it still surprises me.

~~~
edbrown23
For what it's worth, I don't think ruby achieves this goal either. I've been
programming full time in Ruby for nearly three years and things like this [1]
still surprise me. Ruby feels less surprising than C++, sure, but that's a
pretty low bar to clear.

[1] [https://makandracards.com/makandra/46939-ruby-a-small-
summar...](https://makandracards.com/makandra/46939-ruby-a-small-summary-of-
what-return-break-and-next-means-for-blocks)

~~~
loopz
Principles of least surprise (or astonishment), is one of cornerstones of
Ruby. However, the language itself is dynamic, so take the end result with a
pinch of salt: The language's OO syntax is beautifully simple, incredibly easy
to structure into classes/mixins and have tons of useful libraries, _to write
code_ with. Not always so much for reading code, refactoring or discerning
what REALLY goes on in a Rails application..

~~~
gregkerzhner
I think there is a great middle line for a language that is easy to work with,
and provides enough safety to be maintainable for a long time. Environments
like C++ and enterprise Java miss this middle line by being too cumbersome.
However, Ruby equally misses this middle line, just in the other direction -
it's too simple and dynamic leading to lack of maintainability in the long
run. The best solution will be somewhere in between.

~~~
skrebbel
In my opinion, Kotlin, C#, and TypeScript all come pretty close.

------
afarrell
I think the responses of "Well, it doesn't astonish me" and "principle least
my surprise" point to something deep about how to write code for other humans:

As a field, we would benefit greatly from learning more cognitive science.

A core suggestion of John Osterhout's book A Philosophy of Software Design is
to have well-named modules with 'thin' interfaces which accomplish a
reasonably-deep set of responsibilities. But...why?

Working Memory -- Humans have limited Working Memory.

If you give a function:

\- A clear name.

\- Few simple parameters.

\- No side-effects not in the name.

\- No GOTOs or exceptions.

then a human can glance at it, put the name and parameters into working
memory, and carry on.

But if you split up a namable responsibility across multiple files, then a
human reading the codebase to understand data flow would need many more open
editor windows or to hold much more info in working memory.

------
enraged_camel
This is why I am a fan of long function names, like
openUpgradeDowngradeSubscriptionDialog(). Even though they add a bit of
verbosity to the code, I can immediately tell what they do without having to
scroll to the function definition, and there is zero astonishment when they
are called from elsewhere. To a lesser extent, same with variable names:
speaking for myself (and perhaps only myself), I _like_ long variable names --
as the saying goes, code is read many more times than it is written, so saving
a few keystrokes just to shorten a variable name tends to carry a high cost
that is paid down the line.

~~~
jasonpeacock
You're describing self-documenting code. Well written code shouldn't require
any "what" comments, only "why" comments.

Too often you see code with a generically-named function/variable, and a
comment next to it describing what it does. Why not just name the
function/variable correctly?!

There's a strong cargo-cult idea that "real" programmers use short/abbreviated
names, and yet there's absolutely no value to using "idx" over "index", or a
more appropriately named "last_name_index".

~~~
jbay808
Naming is always hard, but sometimes the "what" requires a full paragraph, and
even very long variable names shouldn't exceed 80 characters all on their own.

torque_aux_motor_braking_only_safety_threshold_nm is a good variable name, but
I wouldn't want to let them get much longer than that.

------
jameson
In JavaScript, "0 < -1 < 2" evaluates to true.

The coercion rules were a big surprise to me when I first started to work in
JS. Sometimes codes were obvious but the underlying interpretation is a
surprise call.

~~~
skrebbel
_0 < -1 < 2_

To be fair, is there any mainstream language other than Python where that
expression makes sense at all?

And even Python had to make explicit, syntactical support for it, and IMO it's
a pretty non-obvious language hack. I mean, there's an invisible AND in there,
that's pretty astonishing to me at least :-)

~~~
ghettoimp
Works beautifully in Common Lisp. Of course, it is not mainstream.

? (< 0 1 2)

T

? (< 0 -1 2)

NIL

~~~
jdminhbg
In Clojure:

    
    
       user=> (< 0 1 2)
       true
    

And

    
    
       user=> (< 0 -1 2)
       false

------
projektfu
There is one in Excel VBA (I assume the Behavior is still the same) where IIRC
“Sort” called from code leaves its criteria in the dialog box and if those
parameters are omitted on a second sort, the previous ones are used unless
cleared. This can make previously working code stop working when someone works
on an unrelated part of the app.

------
reallydontask
I once had an argument about usage of exceptions for flow control and I
mentioned this principle.

The developer replied, mostly tongue in cheek to be fair:

Well, it doesn't astonish me

~~~
ArnoVW
subjectiveness aside, exceptions generally are relatively expensive..

In Java : [http://java-performance.info/throwing-an-exception-in-
java-i...](http://java-performance.info/throwing-an-exception-in-java-is-very-
slow/)

In C# : [https://docs.microsoft.com/en-
us/dotnet/standard/exceptions/...](https://docs.microsoft.com/en-
us/dotnet/standard/exceptions/best-practices-for-exceptions)

In C++ : [https://pspdfkit.com/blog/2020/performance-overhead-of-
excep...](https://pspdfkit.com/blog/2020/performance-overhead-of-exceptions-
in-cpp/)

~~~
reallydontask
That's one of the arguments I used. We used C# and he actually did some noddy
perf tests the conclusion of which where:

It's slower but only adds 0.01 s as compared to the a version not using
exceptions. This was about 3 orders of magnitude slower (probably more under
load would be my guess)

+1 for all the extra work to prove to himself that he had taken the right
approach.

-10 For refusing to listen, ignoring data and cherry picking articles on C about exception handling (Of course they're not going to use exceptions, they don't exist)

------
fallingfrog
I think the time I’ve been most astonished recently by an api was asp.net.
They map http parameters onto function parameters by _name_ , using
reflection. One of the first things you’ll read in any introductory
programming textbook is that function parameter names don’t matter; only the
type and order matters. When the light went off and I figured out what they
had done, I swore out loud at my desk..

------
einpoklum
I often use this principle when explaining my code review objections: "I am
slightly astonished that this code does X." If someone asks me if it's really
astonishing, or what I mean by that, I explain the principle to them.

~~~
Ididntdothis
To be honest the word “astonished” comes across a little weird in a code
review. I think it’s better to say “I don’t understand” or ask “why is it this
way”?”

~~~
einpoklum
> the word “astonished” comes across a little weird

... this is what gives me an opportunity to describe the principle :-)

and for those who know it - they already know what I mean.

------
Waterluvian
I wish languages more clearly distinguished between functions that produce
values and functions that have effects (and ones that do both, but discourage
that).

------
saagarjha
I like how this ends up on the topic of efficient encoding of an x86
instruction that zeroes the accumulator.

~~~
juped
xor reg, reg is the best because it's such an ancient idiom that processors
recognize it as a zeroing idiom, enabling some processor-level optimizations.

~~~
saagarjha
Now you need to decide whether to use opcode 0x31 or 0x33…

~~~
juped
Which one weighs less?

~~~
saagarjha
0x33 I think, by a minuscule amount, since it has fewer “on” bits?

------
stcredzero
Coding to impress your coworkers often results in a prioritization of most
astonishment.

~~~
eeZah7Ux
Same for CV-driven work: the adoption of modern "devops" tools is an endless
bad surprise.

