[rust-dev] RFC: Method call syntax as sugar

Niko Matsakis niko at alum.mit.edu
Mon Dec 10 08:15:32 PST 2012


I am a fan of this idea.



Niko

Patrick Walton wrote:
> Hi everyone,
>
> This has been proposed in some form several times by different people, 
> and I think we could possibly make it work now. It would be a 
> low-priority, backwards-compatible change that would make the language 
> somewhat simpler.
>
> Today, there is the distinction between static methods (invokable as 
> functions, but not using dot notation) and non-static methods 
> (invokable using dot notation, but not as functions). This proposal 
> would unify the two.
>
> Briefly, suppose that we have a method call like:
>
>     a.foo(b, ...)
>
> Assuming `a` does not have object type, this would be equivalent to this:
>
>     NAMESPACE::foo(OPERATION(a), b...)
>
> Where `NAMESPACE` is one of:
>
> 1. The anonymous trait associated with the type of `a`, if `a` is an 
> enum or struct (or coercible to one, or a pointer to one) and has an 
> anonymous trait defined for it. (Note on terminology: the "anonymous 
> trait" is the new name for a "trait-less impl" or "an inherent 
> implementation".)
>
> 2. The traits in scope at the call site.
>
> And `OPERATION` is one of:
>
> 1. One or more dereference operations (`*a`).
>
> 2. An address-of operation (`&a`, `&const a`, `&mut a`).
>
> 3. A coercion from `~[T]` or `@[T]` to `&[T]` (or the mutable variants 
> to the corresponding mutable slice) followed by an address-of 
> operation. (This is probably the ugliest rule here, but it seems 
> necessary to allow `for [ 1, 2, 3 ].each |x| { ... }` to work.)
>
> So, in our example above, if `a` had type `T`, we might transform 
> `a.foo(b)` to `T::foo(&a, b)`.
>
> The other change that needs to happen is that what we've been calling 
> "explicit self" needs to become syntactic sugar for an explicit first 
> argument. For instance:
>
>     struct T { ... }
>
>     impl T {
>         fn foo(&self, b: int) { ... }
>     }
>
> Is exactly the same as:
>
>     struct T { ... }
>
>     impl T {
>         /*static*/ fn foo(self: &T, b: int) { ... }
>     }
>
> (The keyword `static` is commented out because, while it is necessary 
> today for backwards compatibility, it will not be necessary, and in 
> fact will likely be removed, in the near future.)
>
> The most immediate practical benefit of this would be that methods 
> that today must be invoked with dot notation would become useful as 
> arguments to higher-order functions. The other main benefit is that 
> the language design becomes simpler and tidier. We no longer need to 
> think of the method call as a core construct in the language (except 
> for objects) but rather as a form of sugar guided by scope and type 
> information.
>
> Again, none of this is particularly high-priority, as I don't think 
> it'll have much immediate practical impact, but I do think it's a 
> simplification worth considering.
>
> Thoughts?
>
> Patrick
> _______________________________________________
> Rust-dev mailing list
> Rust-dev at mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev


More information about the Rust-dev mailing list