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
[email protected]
https://mail.mozilla.org/listinfo/rust-dev
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev