I used to love C++, template wrangling :-P aah, but pretty much gave up after C++11. Right about the time when Scott Meyers also said: "enough" (paraphrasing).
My biggest issue for giving up was the ever growing list of "don't"-s, its not fun to write in language where the design is so "loose" that to get reasonably correct/predictable code you always have to reference the list of "don't"-s.
And then having been a build maintainer on various projects the build and package management was a nightmare. Still vividly remember the first time I looked at Rust's cargo - mind blown :-)
IMHO C++11 changes (and many of the later ones too) make the language substantially better than it was prior.
I do personally hate the package management story which is why I try to only use single header libraries (I only use C++ for personal projects so I have control over what I use). I absolutely despise cmake, but Rust’s cargo is fantastic.
This "delightful" experience is not just Amazon. Its what happens when large tech. companies play "who blinks first". Apple has a fair share of blame here, with their cut of 30%/15% from digital content they did not help to produce.
As someone who enjoys reading on my Kindle and as an early Audible customer, the crap in app browsing and purchasing experience was one of the reasons I put off having an iPhone.
After years of complaints, now at least in app Audible books browsing and purchasing works on iPhone, sigh ...
Now having an iPhone, I have simply traded one set of bad experiences for another, as currently the set of bad experiences on an iPhone, is less important than the on an Android.
Elixir is functional and immutable first, (and structs) - that alleviates somewhat the pain of not having a strong type system. I really like the architecture of OTP, but I still find myself using Elixir in anger.
Especially, if I'm trying to bring and old(er) codebase (Elixir 1.9) up to the newest release... and upgrading packages, checking if things are likely to brake etc.
I constantly find myself realising that I cannot trust the compiler, which means more defensive coding, more tests, more time spent...
As an example, upgraded postgrex. The return tuple of one its functions had changed from 2 elements to 3 elements. Did the compiler caught it? No.
Had I had dialyzer type spec-s on my private function, I would at least gotten a warning. Thus, morale of the story: always type spec even your private functions , especially if they use 3rd party code.
Ah memories... I once had 100K Python 2.x codebase to maintain. No docs, no tests and then being required to add features. Had to use the debugger[1] to make sense of the codebase and types, formats etc. Sheer madness and
such a waste of time...
To this day, I'm baffled by the dynamic language folks who cannot get their head around how strictness/rigor (via a good expressive type system) actually makes maintenance easier and more importantly: cheaper.
Same for me, learned to properly touch type with my language layout and with the help of notches on 'f' and 'j' to help me find home row. Being able to keep my eyes on the screen while typing catches a lot of mistakes.
When travelling I still like to bring the old trusty Microsoft Bluetooth Mobile Keyboard 6000 [1] (phew :), even though the laptop is a Mac.
I found it rather annoying that you cannot organise your code to be readable from top-to-bottom in a file, going from the big picture to finer details. Which, I think is much easier for humans.
That is a matter of habit and not something that is "easier for humans", I think. I've written enough OCaml, which also enforces linear dependence of modules and definitions, that I often find it jarring to read code the other way around and I'd be lost without an IDE that lets me jump to definitions.
I'm not particularly attached to order of definitions within a module, but I definitely like the linear ordering of modules. Without the compiler enforcing that you always end up with cross dependencies between modules, which I think makes it much harder for humans to read the code.
I've had similar conversations about variable shadowing. I find it natural and it bothers me when I can't do it, especially in functional languages, but I have a friend who really doesn't like it and finds it jarring. I think his dislike stems from having learned Erlang before any language that has shadowing, because in Erlang when you reuse a variable name it'll be checking for equality with the value you're "assigning" it to.
I have not found that to be an issue at all. Most F# modules are just types at the top and then functions. This generally does mean that F# modules start with the big picture (i.e., the types) and then move to the details (i.e., functions). If a module is doing something more complicated than that, then I think it's a problem of the module's design likely being too broad.