A final proposal for await syntax

I think this is indeed an interesting argument and I think worth adding to some summary (I am trying to create a "master summary", but I've not had time to finish up yet, and I would include it there).

I don't agree with your conclusion, though: let me try to elaborate why. I guess perhaps it's an uncanny valley argument -- to me, having await(foo) be so close to other keywords and yet with this critical difference is quite surprising. It differs in two respects:

  • It requires a (non-block) delimiters
  • It has unusual precedence

That is, return(foo)? would be parsed as return ((foo)?). But await(foo)? would be parsed as (await (foo))?.

That seems bad and quite surprising to me -- more so that foo.await. I guess it's like this: foo.await feels like something where you might say "oh, that's unusual", but you'd have no real doubt as to when it takes effect. I can't say the same for await (foo)?, which I consider quite visibly ambiguous.

If we're going to use mandatory delimiters, then, this leads us to either await[foo] -- which to me is quite "foreign", this is not indexing, and indeed shares many of the same concerns as foo.await -- or to await { foo }. Here, I agree with @Centril that this feels clumsy and verbose, and ... kind of surprising. We don't expect you to "await" a long block of stuff.

I think you can see a similar tension in unsafe { } today. The original intention, I believe, was that one would use unsafe { ... } on a long block of instructions. But it has become a more prevalent style to push unsafe { } down to the actual operation that requires unsafe, and in that case, the { } feel unnatural -- we've kept them because it feels important to be clear about the scope of unsafe (though I'm not sure that's a good argument, I might be inclined to reconsider that point).

15 Likes