On Sun, Oct 20, 2013 at 9:38 PM, Patrick Walton <[email protected]> wrote:

> I guess I just don't see the value in requiring imports of names when
> there can be no ambiguity and they're defined in one place (the impl of the
> type, defined in the same place as the type itself). One person's "magic"
> is another person's "smart compiler".
>

A big part of the motivation would be to allow declaring methods anywhere,
without using traits, and then "they're defined in one place" stops being
true. For that to be workable you need to have control over imports.
(Luckily with top-level functions, you already do.)



> I'm not convinced that this is solving a real problem.
>

It's not "solving a real problem" so much as simplifying the whole thing.
Despite having used the word, my beef with the current system is not so
much that it's magical. It's that it's completely unnecessary. With nothing
more than a simple syntax rule and the existing module system, you can
recover all of the expressive power of the current system, and more.

Compare:


-- Design 1 --

 - You can declare functions using `fn`.

 - Functions in the current scope can be called using dot syntax with the
first argument as the receiver. (Optionally: only if the first argument is
named `self`.)

 - The module system can be used to group types, functions, and other
items, import them together, selectively, or under different names, and
resolve ambiguities between them.


-- Design 2 --

 - Anonymous `impl` blocks can be used to associate methods with a type.

 - Methods are scoped under and imported together with their type or trait.

 - Because of this, an anonymous `impl` can only be declared in the same
module as its type.

 - If you want to declare a method somewhere else, declare an auxiliary
trait and implement it for that type.

 - For a method to be called with dot syntax, it has to be declared using
special `self`, `&self`, `~self`, (or so forth) syntax, which only works
with the built-in pointer types. Such a method can't be called with
function syntax.

 - If you want a self-type other than one of the built-in pointers, write
an `impl` specifically for that type.

 - Types and traits are like modules in some ways (you can use them in a
path), but not others (you can't `use` from them).

 - There are special rules and/or syntax for dealing with traits, generic
types, and optionally their type arguments in paths.

 - In addition to methods, you can also declare top-level functions with
`fn`. These can only be called with function syntax.

 - The module system can be used to group, import, rename, and resolve
ambiguities between types, functions, and other items except for methods.

Which one feels like the tighter design?

With some extensions (methods can be called with function syntax, in-scope
functions are also considered during method lookup), Design 2 could close
the expressiveness gap versus Design 1. But the simplicity gap would remain.



> The "search all traits in scope" behavior strikes me as far more magical
> than this.
>

All of that said, maybe I'm insufficiently worked up about the method
lookup rules. :) Searching trait impls does sound a little bit scary. What
about, as a less scary in-between solution, while not throwing the baby out
with the bathwater, attempting to unify the type of the receiver with the
types of the first (`self`) arguments of the functions of the given name in
the current scope, but *not* looking at trait impls? And if there's a
unique match (modulo autoborrowing and such) it's selected, otherwise an
error is reported. Whether appropriate trait impls exist would be checked
after a method is selected. This means that if you have a trait method or
function in scope which is generic in its self-type, and any other function
which also matches the type of the receiver, it would lead to ambiguity.
But as (in my proposal) you would no longer have to use traits to implement
extension methods, this would hopefully be a less common occurrence.

Again though, I think this can and should be considered as a separate
matter. It could be done inside the current system, I think, if you wanted
to. The differences in the context of my proposal are the aforementioned
not having to use traits for extension methods, and that you would have
more ways to resolve an ambiguity.


It's probably easier to list languages that *don't* have this feature in
> some form than to list languages that do, honestly...
>

That's because all of the mainstream languages follow misguided OO ideas,
and most of the others copy them. :-)


-- 
Your ship was destroyed in a monadic eruption.
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to