Half-baked idea: postfix/monadic `unsafe`

Two things come to mind for that:

  1. Because it's affecting a block, not a value. This is the same way that it's async { ... }, not { ... }.async -- it's telling you context you need to understand the block. Similarly, { ... break x ... }.loop would be surprising because there wasn't the signpost warning you that the break was coming the way there is in loop { ... break x ... }. (And though I'm probably not in favour of actually doing this for break, note that loop { ... x.break ... } doesn't have the same "surprise" factor, the same way that async { ... x.await ... } doesn't.)

  2. Because async/await is a delayable effect, but unsafe isn't. With async/await, you can call the function to get the impl Future outside an async block, then later choose whether or not to call .await on it. Similarly, you can get your Result, put it in a Vec, and later decide to ? on it. On the contrary, unsafe needs to be "proven" before the call -- you of course can't call the unsafe function from safe code then later somehow only use the result if it was sound. (const also happens like this, where you can't make something const later; it has to be const from the beginning.)

9 Likes