Pre-RFC: Catching Functions

This is a pretty heavy thread, and I’ve gone through and I don’t think I’ve seen this exact point made, so I’m going to try to voice and justify it here:

I agree with @chriskrycho and am broadly skeptical of this proposal, I also would be a lot more comfortable with this proposal if it were implemented not with new syntax, but with some kind of macro or compiler plugin. In fact, I’d go so far as to say that I’d have a more positive reaction to this proposal if it were implemented with keywords that just looked like macros, even if there was still compiler-specific magic used to implement it!

A few points about why:

  1. It’s pretty clear even to Rust learners that names that end with ! are sort-of-special but always desugar down to something else. I can look at a macro like println! or vec! and know, “This can’t necessarily be expressed as a function for whatever reason, but under this surface it’s still built of the same Rust building blocks.” This is one way to address learnability concerns: with throw and catch, there’s the danger (described by @chriskrycho and @regexident above) that learners will think that Rust has some weird special-cased errors system where you have to manually propagate exceptions, but names like throw! and #[catch] emphasize that the error system is still built of Rust values and expressions, and that these constructs are here to ease the burden of writing repetitive code, not because they’re compiler-sanctioned magic.

  2. Implementing these features as macros would also clearly signify the degree to which they’re experimental: people expect macros, especially ones that might require a feature flag to import, to be more changeable and less stable than new built-in syntax, which means there’d be more freedom to notice problems and change them. A lot of the bikeshedding that’s happening in this thread could be resolved by saying, “Well, let’s just implement them all and then squint around the punctuation for a bit, and see what people like best.” I for one would be far more comfortable with an experimental macro than with syntax that could change on a new nightly!

  3. Implementing these features as macros won’t introduce new syntactic features: this is good for people’s intuitions about Rust, as it simply says, “Ah, and these mark that something special happens to this declaration, or this expression.” As a nice side effect, the fact that totally new syntax is not introduced would also would play nicely with existing syntax highlighters or other tooling that would otherwise need to be updated to support new keywords and constructs.

  4. There’s precedent for doing this kind of thing in a macro-like way: the async syntax is already written as #[async] and await!, which also has the advantages I’ve described here: it can be easily experimented with and iterated on, it doesn’t break existing non-rustc tooling (which is aware of macro-like items and where they can appear) and it’s also a way of communicating to the user that async code isn’t “magical”, it’s simply built out of tedious-to-write-and-read assemblages of Rust expressions.

  5. With the try! macro in particular, we also have a precedent for building an abstraction as a macro, nailing down the exact semantics, and after it has become clear that the macro has desirable semantics but undue syntactic burden blessing it with built-in syntax. I would suspect (and probably prefer, for the reasons I describe in the first point above) that the abstractions proposed here could remain as macros indefinitely without too much burden, but it’s possible that I’m wrong, and that these features are indeed so useful and widespread that the !s and #[]s are too heavyweight: in that case, you’d still derive advantages from building these out as macros first, because it would give the entire community time to experiment with the semantics and bikeshed keywords and whatnot before settling on a concrete syntax that’s more pleasing to people.

I say all that with the caveat that I still don’t feel sold on the underlying idea: but, to the extent that I and others aren’t sold on them, I feel like building these features as macros would help sell me on them by demonstrating in a clear-but-not-committed way the advantages we’d get from this proposal.

11 Likes