After sleeping on it I'm not convinced that this would be a net improvement over our current situation. With a few caveats I'm really rather happy with the syntax as it is.
On Sun, Feb 2, 2014 at 8:55 AM, Jason Fager <jfa...@gmail.com> wrote: > I'm not a huge fan of this proposal. It makes declarations longer, and it > removes the visual consistency of Foo<T,U> everywhere, which I think > introduces its own pedagogical issue. > > The recent addition of default type parameters, though, makes me think > there's a reasonable change that increases consistency and shortens > declarations in a few common cases. > > From what I understand, the reason we can't just have > > impl Trait<T> for Foo<T,U> > > is because it's ambiguous whether T and U are intended to be concrete or > generic type names; i.e., > > impl<T> Trait<T> for Foo<T,U> > > tells the compiler that we expect U to be a concrete type name. > > Our new default type parameter declarations look like: > > struct Foo<T,U=Bar> > > So what if to actually make generic types concrete, we always used the '='? > > struct Foo<T,U=Bar> > impl Trait<T> for Foo<T, U=Derp> > > This saves a character over 'impl<T> Trait<T> for Foo<T, Derp>', solves > the greppability problem, and makes intuitive sense given how defaults are > declared. > > It also has a nice parallel with how ':' is used - ':' adds restrictions, > '=' fully locks in place. So what is today something like > > impl<T:Ord> Trait<T> for Foo<T, Derp> > > would become > > impl Trait<T:Ord> for Foo<T, U=Derp> > > The rule would be that the first use of a type variable T would introduce > its bounds, so for instance: > > impl Trait<T:Ord> for Foo<Z:Clone, U=Derp> > > would be fine, and > > impl Trait<T> for Foo<T:Clone, U=Derp> > > would be an error. > > More nice fallout: > > struct Foo<A,B> > impl Foo<A,B=Bar> { > fn one(a: A) -> B > fn two(a: A) -> B > fn three(a: A) -> B > } > > means that if I ever want to go back and change the name of Bar, I only > have to do it in one place, or if Bar is actually some complicated type, I > only had to write it once, like a little local typedef. > > I'm sure this has some glaring obvious flaw I'm not thinking of. It would > be nice to have less syntax for these declarations, but honestly I'm ok > with how it is now. > > > > > > > > > > > > > > > On Sat, Feb 1, 2014 at 5:39 PM, Corey Richardson <co...@octayn.net> wrote: > >> Hey all, >> >> bjz and I have worked out a nice proposal[0] for a slight syntax >> change, reproduced here. It is a breaking change to the syntax, but it >> is one that I think brings many benefits. >> >> Summary >> ======= >> >> Change the following syntax: >> >> ``` >> struct Foo<T, U> { ... } >> impl<T, U> Trait<T> for Foo<T, U> { ... } >> fn foo<T, U>(...) { ... } >> ``` >> >> to: >> >> ``` >> forall<T, U> struct Foo { ... } >> forall<T, U> impl Trait<T> for Foo<T, U> { ... } >> forall<T, U> fn foo(...) { ... } >> ``` >> >> The Problem >> =========== >> >> The immediate, and most pragmatic, problem is that in today's Rust one >> cannot >> easily search for implementations of a trait. Why? `grep 'impl Clone'` is >> itself not sufficient, since many types have parametric polymorphism. Now >> I >> need to come up with some sort of regex that can handle this. An easy >> first-attempt is `grep 'impl(<.*?>)? Clone'` but that is quite >> inconvenient to >> type and remember. (Here I ignore the issue of tooling, as I do not find >> the >> argument of "But a tool can do it!" valid in language design.) >> >> A deeper, more pedagogical problem, is the mismatch between how `struct >> Foo<...> { ... }` is read and how it is actually treated. The >> straightforward, >> left-to-right reading says "There is a struct Foo which, given the types >> ... >> has the members ...". This might lead one to believe that `Foo` is a >> single >> type, but it is not. `Foo<int>` (that is, type `Foo` instantiated with >> type >> `int`) is not the same type as `Foo<unit>` (that is, type `Foo` >> instantiated >> with type `uint`). Of course, with a small amount of experience or a very >> simple explanation, that becomes obvious. >> >> Something less obvious is the treatment of functions. What does `fn >> foo<...>(...) { ... }` say? "There is a function foo which, given types >> ... >> and arguments ..., does the following computation: ..." is not very >> adequate. >> It leads one to believe there is a *single* function `foo`, whereas there >> is >> actually a single `foo` for every substitution of type parameters! This >> also >> holds for implementations (both of traits and of inherent methods). >> >> Another minor problem is that nicely formatting long lists of type >> parameters >> or type parameters with many bounds is difficult. >> >> Proposed Solution >> ================= >> >> Introduce a new keyword, `forall`. This choice of keyword reads very well >> and >> will not conflict with any identifiers in code which follows the [style >> guide](https://github.com/mozilla/rust/wiki/Note-style-guide). >> >> Change the following declarations from >> >> ``` >> struct Foo<T, U> { ... } >> impl<T, U> Trait<T> for Foo<T, U> { ... } >> fn foo<T, U>(...) { ... } >> ``` >> >> to: >> >> ``` >> forall<T, U> struct Foo { ... } >> forall<T, U> impl Trait<T> for Foo<T, U> { ... } >> forall<T, U> fn foo(...) { ... } >> ``` >> >> These read very well. "for all types T and U, there is a struct Foo ...", >> "for >> all types T and U, there is a function foo ...", etc. These reflect that >> there >> are in fact multiple functions `foo` and structs `Foo` and >> implementations of >> `Trait`, due to monomorphization. >> >> >> [0]: >> http://cmr.github.io/blog/2014/02/01/polymorphic-declaration-syntax-in-rust/ >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev@mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> > > > _______________________________________________ > Rust-dev mailing list > Rust-dev@mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > >
_______________________________________________ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev