I would like to offer a slightly different perspective from what I have seen here so far: which variants were chosen only for the sake of being ānot like all the other featuresā?
Iāll start with the obvious contenders for that category:
result.await!
result#
result@
result@await
result!await
None of those are likely to ever be used anywhere else, they honestly look ridiculous, and if you show them to someone who has zero knowledge of why they were chosen, youāll likely get a well-earned confused stare.
To make it even less compatible with the rest of the language, may I suggest using a Unicode symbol like U+2A20 Z NOTATION SCHEMA PIPING
?
Next: āmacro impostorsā
await!(result)
result.await!()
As far as Iāve heard, a) await can never be an actual macro and b) postfix macros are not even a thing yet. The latter is kind of a minor point given that itās never going to be a macro anyway, so why dress it up line one? I believe the standard macro-like syntax has only been accepted as a suggestion because of the āgood old timesā with try!()
and should not be stabilised like this.
Now we are left with somewhat sensible proposals, so letās look at the remaining postfix variants next:
result.await
result.await()
Iāll sort out the field access syntax first. Field accesses are at worst hidden behind a Deref chain, but NEVER activate any sophisticated mechanism themselves, so this syntax is a bad idea because it breaks that behaviour.
Then we have the method call syntax, and Iāve seen some people ask why await
is not a method of Future
in the first place. Regardless of the reason, itās currently not, so this syntax should probably not be added until that changes. (Were it not for the ādishonestyā, the method call syntax would probably be my favourite.)
The last remaining candidates are:
await result
await { result }
At this point, itās mostly a matter of personal taste. Me, I am a fan of only putting parentheses around things if absolutely necessary, so I would vote for the first one. It is less cluttered in all the common scenarios mentioned by other people like loops and generators, and await (result?)
looks less visually disturbing than (await result)?
, so I would also vote for await
having a higher precedence than ?
. Optimise for the simple case, because the complicated one will be cluttered anyway.
On the other hand, I can see why await { result }
may be preferred. It is visually more in line with the rest of the language (think if statements and unsafe) and sidesteps the precedence battle entirely.
A perceived problem they both share is method chaining, e.g. (await (await x).y().z()).a().b()
. While this is a valid concern, I donāt think facilitating a point-free programming style to this extent is worth accepting the inconsistencies in language design outlined by both others and myself in this thread.
I feel like a decision between the last two syntaxes cannot lead to a bad result, but all the other contenders have serious problems and while I probably have no authority whatsoever in this discussion, I would strongly advise against considering any of them for stabilisation.