Agreed. Every keyword adds complexity to the language; the fewer your language needs, the better. If your language has first-class functions and polymorphism (and any serious language does these days), there's no need for special-case control flow keywords; better to have a design like e.g. Smalltalk, where if/while/... are just normal functions.
> The control flow that try/catch creates has never been surprising or invisible in my experience.
One of the biggest production bugs I saw happened because of removing an unused variable (the function looked correct, but actually the unused variable right at the top of the function was throwing an exception; the fallback code path was correct, but the function itself was implemented wrong). It's the same problem as https://glyph.twistedmatrix.com/2014/02/unyielding.html - you can't tell which function calls might throw by looking at them, and most of them don't, but some of them do. And on top of that you have the goto-like "action at a distance": starting from a given catch there's no way to find the corresponding throw (or vice versa). You can't even tell when a catch is completely unused.