That said, switching from C++ to Go made my life so much easier and more enjoyable that I do not see myself going back to that language ever again.
That said, switching from C++ to Go made my life so much easier and more enjoyable that I do not see myself going back to that language ever again.
But that's probably due to past experience and personality type. I mostly enjoy working in powerful and expressive languages: e.g. Rust, Scala, C++.
// edit: oh, someone have already said that: can't love Rust and Go at the same time ;)
Can you share some practical use cases where the sum type has an advantage? Personally I find go's explicit error type, along with the convention of it being called err everywhere to be really helpful and clear when working through the control flow of a program.
What does a more "powerful and expressive" language give you day to day that golang doesn't? (Generics being the first obvious example, but I have to agree that there are a handful of use cases where they're useful)
A product type also allows returning weird states: no error and no value, or both error and value. I strongly believe that invalid states should be unrepresentable, rather than allowed by the type system and then fought by discipline and tooling.
Rust for example promises that Option<NonZeroU32> is the same size (four bytes) as u32, even though it has much more appropriate semantics for some cases. I can't accidentally end up with a zero where I wanted anything else, and I can't easily forget to handle the None case where there wasn't a non-zero answer.
However, I've heard, but can't confirm so don't quote me that it is impossible to appreciate Go and Rust at the same time.
C++ has the distinct ad/disadvantage that it inherited 15-20 years of baggage from C, as well as carrying 20-30 years of its own.
There's plenty of people that will argue that Go's historical baggage is in the form of being primitive, and Rust already is a large language. That's the fun thing about these design discussions.
Just an example of a possible C# pub quizz question, I have other possible ones.
I'm not arguing that you don't need to think about your code. The early behaviour was what I would have expected, the change was sensible but it's a long way from what you have to deal with in C++.
My experience with C++ was a lot of study and practice before I started my first project whereas with C# I was able to dive right in to a substantial piece of work and learn the language along the way.
For some reason this truth seems to escape most new language fanboys, in particular; the Rust crowd on HN.
The biggest reason C++ and Java accumulate historical baggage is fixation on near 100% backwards compatibility. E.g. Java 5 added generics, but had to allow using non-generic erasures (List instead of List<T>) so older programs could still compile and run. And now we have to live with this ugliness even in Java 16.
Of course dropping backwards compatibility causes a bunch of problems of their own and it is better to try to minimize the impact (Rust editions, Scala 3 vs 2) rather than do a big bang (Python 3 vs 2).
Rust's "raw" way to spell all symbols is clever. Maybe some day my function named weigh will be a problem because of a new "weigh" keyword. Rust gets to add the keyword but still talk about my function in new editions by just spelling the symbol awkwardly, as r#weigh. This forbids Rust from reserving such spellings (e.g. "r#weigh") as keywords themselves, but that would be so ugly nobody would want to do it. Overall the result is Rust 2021 could even make "new" a keyword if it wanted to, and the old code which uses that symbol name everywhere still works, it's just a little clumsy to talk to it from next edition code.
Still, I think it's worth remembering that the edition changes in Rust so far have been much smaller than many changes contemplated for C++ Epochs (or any hypothetical actual C++ feature similar to Vittorio's proposal in spirit).
C++ has a lot of problems, and understandably Epoch proponents want to do stuff like ban implicit narrowing coercions, or change how overflow works. Because of how sprawling C++ is these are surprisingly big changes to the whole language, and I don't think that you could pull off something like that with editions.
I have a hopeful note though. Maybe C++ can inspire a much more powerful tool than editions, somehow enabling backward compatibility for C++ while also allowing new C++ to be written exclusively in Stroustrup's "subset of a superset" that keeps most of C++'s strengths but loses so much baggage like implicit coercions everywhere. If it's possible, the C++ community have the right people.
Exactly! My argument is that once a language becomes "successful", whether it is designed in or not, it is an inevitability. As an example all my code/knowledge/skill of pre-C++11 is still valid with any C++ compiler toolchain today. This allows me to accumulate new knowledge at a sustainable pace as my needs and applications demand it; the language adapts to my need rather than the other way around.
Rust has some weird corners, but it seems they're good at explaining things.
Go tries to make some things easier (though, sure, still easier than C++) but they make it in a opaque or weird way.
Some changes also seem to change too fast, but that might just be me looking from the outside