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

Reply via email to