First, thanks to everyone that has been involved in the discussion and the lang team for all their hard work up to this point!
After reading the final proposal, I’m in the camp of being really exited about the decision even though it’s not the idea that I previously advocated. The reason for this is the potential of making the “dot” operator much more general and powerful in the future.
I see discomfort from people thinking about .field as “field access” and .method() as “method access”, leaving .await as “magic keyword”, and I’m sympathetic.
What changed my mind is thinking about the . not as a delimiter like , but as a powerful operator in itself - one that evaluates its operand in a special scope that has the following bindings:
- All of the fields of the $self object
- All of the impls of the $self object, curried with $self as the first parameter
- All of the impls of the traits of the $self object, curried with $self as the first parameter
(I hope I’m using the correct terminology here)
The final await syntax proposal adds the following to the scope:
- The keyword
await, curried with $self as the first parameter
And other potential additions I’ve seen discussed are:
- The keywords
ifandmatch(among others), curried with $self as the first parameter - Macros (either all macros or ones specially constructed), curried with $self as the first parameter, allowing
$self.dbg!()
These changes potentially make Rust a lot more expressive for authors writing in the method-chaining style. At the same time, they are straightforward extensions to the . operator.
As with all changes, there’s the potential for misuse, but in general Rust’s philosophy on stylistic matters is to trust the author to make the decision as best seen fit.
(As an aside, wouldn’t it be great to have an operator such as -> which could do the same currying but in the enclosing scope, allowing $self->Ok() to be transformed to Ok($self)?)