
Stroustrup's Rule and Layering Over Time in Rust - qznc
https://thefeedbackloop.xyz/stroustrups-rule-and-layering-over-time/
======
AceJohnny2
Change takes time! This is a great example, as he has specific instances of
evolving syntax to describe the same thing, semantically.

The big problem, of course, is that code hangs around. Can you evolve your
syntax as people get used to it? Not only are you adding work to your parser,
but people who use your language also have to deal with the multiple
iterations of the syntax that linger in various codebases. This is one reason
I detest dealing with Perl codebases.

Anyhow, as an exercise of evolving syntax while keeping the underlying
semantics, I find Reason [1], a new syntactic layer over OCaml, particularly
interesting.

[1] [https://facebook.github.io/reason/](https://facebook.github.io/reason/)

~~~
stymaar
> Can you evolve your syntax as people get used to it? Not only are you adding
> work to your parser, but people who use your language also have to deal with
> the multiple iterations of the syntax that linger in various codebases.

Clippy[1] helps a lot in this case, it helps people writting idiomatic Rust
and it's updated when new syntaxes introduces new ways to do stuff, so the old
one is deprecated _de facto_.

[1] [https://github.com/Manishearth/rust-
clippy](https://github.com/Manishearth/rust-clippy)

~~~
Manishearth
There's actually some interesting discussion about making Clippy suggest ?
instead of try: [https://github.com/Manishearth/rust-
clippy/issues/1361](https://github.com/Manishearth/rust-clippy/issues/1361)

~~~
kazagistar
It would make sense to leave some time for the documentation to stabilize and
usage to spread a little before pushing hard in that direction I think.

------
akkartik
Fascinating example of the Overton Window
([https://en.wikipedia.org/wiki/Overton_window](https://en.wikipedia.org/wiki/Overton_window))
and Milo Criterion ([http://www.ribbonfarm.com/2011/09/23/the-milo-
criterion](http://www.ribbonfarm.com/2011/09/23/the-milo-criterion)) in action
in software.

~~~
agumonkey
Reading about Milo reminded me of MSOffice Ribbon. And now I wonder if there
are reflection or theories about social fluid dynamics and how to redirect a
flow of people into something radical-looking without creating turmoil.

~~~
akkartik
The same site has this later post about the transition _process_ for a big
change, which partially answers your question:
[http://www.ribbonfarm.com/2014/09/24/the-rhythms-of-
informat...](http://www.ribbonfarm.com/2014/09/24/the-rhythms-of-information-
flow-pacing-and-spacetime). It's a very alien worldview for most developers,
who tend to focus all their attention on designing a feature and _none_ on
designing the transition process for the feature.

~~~
agumonkey
What a long article, I am thrilled (no sarcasm, I love everything about
rhythm).

------
Teckla
I often feel like I'm the only software developer in the world that thinks
most programming languages are evolving in the wrong direction.

Our civilization is going to end up with countless dead languages -- dead
programming languages, that is -- because future generations won't know how to
read the increasingly terse and arcane syntax that is all the rage these days.
Either that, or the investment necessary to read these crazy languages will be
considered an ill advised investment in resources. We'll end up recreating the
wheel indefinitely, but in different languages.

I would like to see much, much simpler programming languages, even if they're
more verbose, as long as the result is improved readability and longevity of
the code written in said languages. I think some of the older languages are
far superior in many ways, if only because, with some of them, you can
actually read and understand the code without even any formal training in the
language.

~~~
stymaar
> I would like to see much, much simpler programming languages, even if
> they're more verbose, as long as the result is improved readability and
> longevity of the code written in said languages.

I'm really sad to see this misconseption over and over on HN. Verbosity is so
much worst than syntax complexity because you ends up having dozens of
different patterns that do the same thing overall but with subtile differences
on edge cases.

If you look at JavaScript pre-ES6, you had at least 10 ways of doing OOP with
really different behaviors when it came to inheritence or encapsulation. This
makes the code so hard to understand.

ES6 formalizing a specific semantic for OOP was godsend.

As long as you introduce syntax to help with what people are actually doing
(and not juste because it looks cool) syntax addition __enhance __the code
readability.

~~~
Teckla
_I 'm really sad to see this misconseption over and over on HN._

Please don't be rude.

 _Verbosity is so much worst than syntax complexity because you ends up having
dozens of different patterns that do the same thing overall but with subtile
differences on edge cases._

There's a level of verbosity/terseness that's ideal for (your average) human.
I don't know precisely what that level is, but I think many programming
languages, such as C++ and Rust, have stepped way past that line.

 _If you look at JavaScript pre-ES6, you had at least 10 ways of doing OOP
with really different behaviors when it came to inheritence or encapsulation.
This makes the code so hard to understand._

The problem with JavaScript OO was, in my opinion, the use of prototypes.

 _As long as you introduce syntax to help with what people are actually doing
(and not juste because it looks cool) syntax addition enhance the code
readability._

This is simply an unsupported claim.

~~~
Daishiman
> I don't know precisely what that level is, but I think many programming
> languages, such as C++ and Rust, have stepped way past that line.

There are no languages in the same domain that don't have a comparable level
of syntax and semantic complexity given the intrinsic nature of the
information they want to encode.

And I would make rather take sigils than using a bunch of different keywords
every time I need to talk about lifetimes and pointers.

To date I have not seen languages with comparable complexity expressed with
more elegant syntax. Some domains just have irreducible complexity.

------
Too
Following this rule, maybe it's time to add a shorthand for std::unique_ptr<>
to c++ already. I'm not really a fan of asterixes or ampersands either but 17
characters, 5 of them requiring shift modifier, for something you write that
often quickly becomes annoying.

~~~
alfanick
Usually I define new types, when I use them a lot like:

    
    
        class Something {
          typedef std::unique_ptr<Something> unique;
          typedef std::shared_ptr<Something> shared;
          typedef std::weak_ptr<Something> weak;
            
        };
    
        // ...
        // later in the code
        
        Something::unique a;
        // instead of std::unique_ptr<Something> a;

~~~
eropple
That's a neat way of handling it. I wouldn't have considered it. I think I'm
gonna steal it.

------
sfilargi
What I really appreciate in a language, especially when I am starting out with
it, is the Python's slogan "only one way to do it".

~~~
ajross
Which doesn't work, even in Python. Python 1.0 could iterate over various
collections with straightforward syntax that still works. No such programmer
would recognize the functional style that's taken over for iteration in the
modern language.

Likewise the evolution from list comprehensions to generators left us with
some terribly overlapping syntax.

~~~
sfilargi
Can't argue with that, but what I really said was that in contrast to the
article, and Stroupstrup's rule, if I was to design a language I would put the
"one way to do it" very high in my priorities.

Going with let's have "explicit syntax" now until the users get familiar with
it and we will make it more terse later, is not a good idea IHMO.

But I do understand and appreciate that sometimes evolutionary changes will
bring in duplication, so I am in no way attacking Rust and the specific
example of the evolution of the error handling syntax.

~~~
kibwen

      > Going with let's have "explicit syntax" now until the 
      > users get familiar with it and we will make it more 
      > terse later is not a good idea IHMO.
    

I don't think this is a conscious decision. IMO, when you're first designing a
language, you don't necessarily _know_ what idioms are going to be most
common, so you use special syntax sparingly, and force users to be explicit
everywhere else. Then, once you have experience with how people use the
language and can empirically observe what idioms are popular, you favor those
idioms with shorthand syntax.

Getting back to the specific example in the OP, for a _long_ time there was a
discussion on whether Rust should use the question mark for some dedicated
syntax (having removed the C-style ternary operator in 2012 as redundant with
`if`). But people disagreed on what to use it for: some wanted to use it to
designate functions that return booleans (like Ruby does); others wanted to
use it to designate functions that return Option (my original stance, way back
when); others wanted it as sugar for constructing and typing Options (as Swift
eventually did); some wanted a C#-style coalescing operator. But after years
of experience it turns out that none of the above are especially prevalent in
Rust, especially once the community embraced the Result type (which matured
relatively late in Rust's development) for most of what Option had originally
been used for. In retrospect having a terse way to handle Results is an
obvious win and I absolutely adore the new `?` operator, but it takes time to
produce the evidence that such things are truly worth their weight.

~~~
sfilargi
Ack.

Maybe I misunderstood the article then! When I read:

    
    
            For new features, people insist on LOUD explicit syntax.
    
            For established features, people want terse notation.
    

I understood, keep it explicit to begin with, and make it terse when users get
familiar. Probably I got it wrong.

~~~
kibwen
I don't think you're wrong, I just think that you're overlooking that not all
features eventually receive terse notation. Some stay loud and explicit
forever! Only a few, relatively important features receive terse notation, and
_knowing_ which features those are requires observing how the language is
used.

------
EugeneOZ
It only works when your function returns error of the same type as expression
inside 'try!' or '?' macros. So in a lot of cases it doesn't work or forces
programmer to return underlying type of error, instead of error which belongs
to current level of visibility (in other words, it provokes programmer to
violate encapsulation for the sake of lazyness). Also it means we have 2 ways
to do same thing and users have to know this small trick even to read code (so
it raises entry level).

I love Rust language and feel sorry for this criticism. But small things are
important.

~~~
cfallin
> It only works when your function returns error of the same type as
> expression inside 'try!' or '?' macros.

The language has actually thought of this case -- it turns out you can map
lower-level errors into your higher-level error type by implementing the
`From<E>` trait. E.g.:

    
    
        use std::io;
        pub enum MyErr { Io(io::Error), Custom(String) }
    
        impl From<io::Error> for MyErr {
            fn from(err: io::Error) -> MyErr { MyErr::Io(err) }
        }
    
        fn do_stuff() -> Result<(), MyErr> {
            let f = try!(File::open(...));
            // ...
        }

~~~
mastax
The error-chain [0] crate helps to reduce this boilerplate. I usually don't
like macro magic like this, but the code is so straightforward that you can
trust the macro to work as expected.

[0]: [https://github.com/brson/error-chain](https://github.com/brson/error-
chain)

------
dtheodor
I really don't see Rust as a good example of a language getting its syntax
right. It reads like Perl. You know what's good syntax? The one that reads
like pseudocode (Python is the closest to that).

~~~
Daishiman
Perl has infinity ways of describing the same computation with no clear best
practices in many cases.

Rust's problem is the same that any language in its domain encounters: it must
encode a lot more information than similar scripting languages in order to
describe the semantics of this program.

It most certainly does not read like Perl. The sigils are weird but there's
few of them and they're used consistently and without overloaded meaning. And
unless you want to make a horrendously verbose language by assigning keywords
to stuff related to lifetimes, pointers and references, it attempts to strike
the balance between readability and compactness for the experienced developer.

Rust used to have a lot more sigils. Its syntax and semantics are nowadays a
lot simpler than languages in the same domain (C++ I'm looking at you) and a
lot of the complexity has been pushed into the traits system, IMO for the
better.

------
FrancoDiaz
"syntax doesn't matter, only semantics!" is what I classify as geek machismo.
I used to see a lot of that over at [http://lambda-the-
ultimate.org](http://lambda-the-ultimate.org) in its heyday.

~~~
Retra
It's basically a pedant's creed. I really wish everyone who desired to express
that point would translate it into some forgotten language first, just to
drive the irony deep.

------
smegel
This is worse than Perl.

