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

Reply via email to