Read that quote again: I say "add" because I mean it; I would never argue that a C developer does not like abstraction at all because that is obviously false (functions, control flow, text macros). You can't say that I "literally" said you don't like abstraction at all, as that's not what I am arguing: if anything, I am arguing that, due to the blub paradox, seeing the difference between the automation you encourage and the automation you have a distaste for is complex at best and impossible at worst; I look at your article and, as I have every other time I have examined Rust, am left wanting for more abstraction and automation when it comes to errors.

Your argument that you do not want error propagation to be implicit is strange to me, as a developer who is used to this being automatic, because it is does not affect safety to automate and is effectively nothing but boilerplate. There is nothing different in the form of your argument against exceptions from the form of the arguments made by developers of C or Go or Java against adding features like templates or optionals or macros. It isn't that Java developers hate abstraction in all forms (that would be an absurd argument that I would need to pull from an AbsurdArgumentFactory ;P), it is that the form of argument that we often hear from all of these developers about the features we like in languages like C++ or Rust or D has the same core structure :(.

On pcwalton's notes on exceptions, I already responded to him in my comment that started my involvement in this thread, and went further in my first reply this morning: his mental model seems stuck in the implementation of exceptions as defined by Java and as used by Java developers. His datapoint for why they are so slow is from an old story about gcj: the Java exception model requires a stacktrace reification, and you would not be able to replicate that kind of performance loss in C++, even though they share the same implementation of propagation. His API issues are all (as argued by others) based on the awkward way that Java developers have made exceptions used for things that aren't really errors.

Have you developed in Erlang? This is a language that considers errors and failures to be the core problem faced by developers, and which has structured almost all other decisions surrounding that core premise. After spending a lot of time coding in Erlang a few years ago, it fundamentally changed the way I think about errors, and that was after over 20 years of software development in languages like C++ and Java. When I was (comparatively) green and naive, back in 2001, I even made an argument for checked exceptions to Microsoft in C# (it was partly my argument for RAII in that same thread that got us the using syntax sugar for IDisposable): that is how far I had to come in the subsequent decade.

Erlang has the right abstraction: a mechanism for exceptions that is designed somewhat similarly to panic, in that it encourages you to structure your code in ways that isolate failures behind processes and avoid ever "handling" errors, but which lets you propagate and augment rich error context through multiple process layers implicitly, making error propgation automatic and without boilerplate. Once you "get it", you can do this easily in any language that has unchecked exceptions (even Java, using RuntimeException as the new exception root, but you have to really hate Java to pull his off ;P), as function calls can be mentally modeled as calls through process linkages (though you sadly then can't use the standard libraries provided by any of these languages, as they are all built with a broken model :().

Given how many other amazing things that Rust got uniquely right, it is somewhere between disappointing and devastating that error propagation, something which is so important, only seems to be competing with languages (like C, Go, or Java) where errors are almost unworkable :(.