Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-04 Thread Niko Matsakis
On Sun, Feb 02, 2014 at 10:30:51AM +0100, Benjamin Herr wrote:
> ... while C# apparently compromises and puts the type parameters between
> the function name and value parameter list, but leaves the bounds for
> later:
> 
>  public static bool Contains(IEnumerable collection, T item) 
>where T : IComparable;

I have actually been meaning to suggest this for Rust, most likely as
an addition to the current syntax. The reasoning is that if we were to
generalize our traits into the equivalent of Haskell's
"multi-parameter type classes", there are things that the current
syntax cannot express. Also I think it reads better if there are many
bounds. But I'll expand in a separate e-mail, rather than tying the
discussion to this thread, which is about Corey's proposal.


Niko
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-03 Thread Gábor Lehel
On Mon, Feb 3, 2014 at 11:20 PM, Eric Reed  wrote:

> Actually this isn't the case.
>
> fn foo(t: T) -> TypeId {
> t.get_type_id()
> }
>
> compiles just fine, but
>
> fn bar(t: T) -> TypeId {
> t.get_type_id()
> }
>
> fails with "error: instantiating a type parameter with incompatible type
> `T`, which does not fulfill `'static`". Just  does not imply  'static>, so parametricity is not violated.
>

'static is not even a trait per se (as far as I understand it), it merely
states the lifetime which data must be valid for. I would not expect this
to imply "oh, and you can also try casting it to any type". I'm not sure
what a precise definition of parametricity is that we could apply here, but
I'd be very surprised if this flies. It should mean something like "only
information that is provided may be used", not "if no information is
provided, nothing may be assumed, but if even a little information is
provided, well feel free to do whatever you like".


>
> I had the same thought about making size_of and friends unsafe functions.
> I think that might be a reasonable idea.
>
>
> On Mon, Feb 3, 2014 at 5:35 AM, Gábor Lehel  wrote:
>
>> Just because Any is a trait doesn't mean it doesn't break parametricity.
>> Look at this:
>>
>>
>> http://static.rust-lang.org/doc/master/src/std/home/rustbuild/src/rust-buildbot/slave/doc/build/src/libstd/any.rs.html#37-63
>>
>> Because we have `impl Any for T`, it can be used with *any
>> type* (except borrowed data), including type parameters, whether or not
>> they declare the `T: Any` bound explicitly (which is essentially redundant
>> in this situation).
>>
>> The proper thing would be for the compiler to generate an `impl Any for
>> MyType` for each individual type separately, rather than a single generic
>> impl which is valid for all types.
>>
>> I also think we should guarantee parametricity for safe code and make
>> `size_of` an unsafe fn. Its legitimate uses in unsafe code (e.g. smart
>> pointers) are well encapsulated and don't expose parametricity violations,
>> and I don't believe safe code has a legitimate reason to use it (does it?).
>>
>>
>> On Sun, Feb 2, 2014 at 3:27 AM, Eric Reed wrote:
>>
>>> I'm going to respond to Any and size_of separately because there's a
>>> significant difference IMO.
>>>
>>> It's true that Any and trait bounds on type parameters in general can
>>> let function behavior depend on the passed type, but only in the specific
>>> behavior defined by the trait. Everything that's not a trait function is
>>> still independent of the passed type (contrast this with a setup where this
>>> wasn't true. `fn foo() -> int' could return 2i for int and spin up a
>>> tetris game then crash for uint). Any just happens to be powerful enough to
>>> allow complete variance, which is expected since it's just dynamic typing,
>>> but there's an important distinction still: behavior variance because of
>>> Any *is* part of the function because you need to do explicit type tests.
>>>
>>> I wasn't aware of mem::size_of before, but I'm rather annoyed to find
>>> out we've started adding bare A -> B functions since it breaks
>>> parametricity.
>>> I'd much rather put size_of in a trait, at which point it's just a
>>> weaker version of Any.
>>> Being able to tell how a function's behavior might vary just from the
>>> type signature is a very nice property, and I'd like Rust to keep it.
>>>
>>> Now, onto monomorphization.
>>> I agree that distinguishing static and dynamic dispatch is important for
>>> performance characterization, but static dispatch != monomorphization (or
>>> if it currently does, then it probably shouldn't) because not all
>>> statically dispatched code needs to be monomorphizied. Consider a function
>>> like this:
>>>
>>> fn foo(ox: Option<~A>, f: |~A| -> ~B) -> Option<~B> {
>>> match ox {
>>> Some(x) => Some(f(x)),
>>> None => None,
>>> }
>>> }
>>>
>>> It's quite generic, but AFAIK there's no need to monomorphize it for
>>> static dispatch. It uses a constant amount of stack space (not counting
>>> what `f' uses when called) and could run the exact same code for any types
>>> A or B (check discriminant, potentially call a function pointer, and
>>> return). I would guess most cases require monomorphization, but I consider
>>> universal monomorphization a way of implementing static dispatch (as
>>> opposed to partial monomorphization).
>>> I agree that understanding monomorphization is important for
>>> understanding the performance characteristics of code generated by *rustc*,
>>> but rustc != Rust.
>>> Unless universal monomorphization for static dispatch makes its way into
>>> the Rust language spec, I'm going to consider it an implementation detail
>>> for rustc.
>>>
>>>
>>>
>>> On Sat, Feb 1, 2014 at 3:31 PM, Corey Richardson wrote:
>>>
 On Sat, Feb 1, 2014 at 6:24 PM, Eric Reed 
 wrote:
 > Responses inlined.
 >
 >>
 >> Hey all,
 >>
 >> bjz and I have worked out a nice proposal[

Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-03 Thread Daniel Micay
On Mon, Feb 3, 2014 at 5:20 PM, Eric Reed  wrote:
> Actually this isn't the case.
>
> fn foo(t: T) -> TypeId {
> t.get_type_id()
> }
>
> compiles just fine, but
>
> fn bar(t: T) -> TypeId {
> t.get_type_id()
> }
>
> fails with "error: instantiating a type parameter with incompatible type
> `T`, which does not fulfill `'static`". Just  does not imply  'static>, so parametricity is not violated.
>
> I had the same thought about making size_of and friends unsafe functions. I
> think that might be a reasonable idea.

The 'static bound is there as a workaround for an implementation
limitation. In all likelihood, it will no longer be required in the
future as it has no fundamental relation to reflection.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-03 Thread Eric Reed
Actually this isn't the case.

fn foo(t: T) -> TypeId {
t.get_type_id()
}

compiles just fine, but

fn bar(t: T) -> TypeId {
t.get_type_id()
}

fails with "error: instantiating a type parameter with incompatible type
`T`, which does not fulfill `'static`". Just  does not imply , so parametricity is not violated.

I had the same thought about making size_of and friends unsafe functions. I
think that might be a reasonable idea.


On Mon, Feb 3, 2014 at 5:35 AM, Gábor Lehel  wrote:

> Just because Any is a trait doesn't mean it doesn't break parametricity.
> Look at this:
>
>
> http://static.rust-lang.org/doc/master/src/std/home/rustbuild/src/rust-buildbot/slave/doc/build/src/libstd/any.rs.html#37-63
>
> Because we have `impl Any for T`, it can be used with *any
> type* (except borrowed data), including type parameters, whether or not
> they declare the `T: Any` bound explicitly (which is essentially redundant
> in this situation).
>
> The proper thing would be for the compiler to generate an `impl Any for
> MyType` for each individual type separately, rather than a single generic
> impl which is valid for all types.
>
> I also think we should guarantee parametricity for safe code and make
> `size_of` an unsafe fn. Its legitimate uses in unsafe code (e.g. smart
> pointers) are well encapsulated and don't expose parametricity violations,
> and I don't believe safe code has a legitimate reason to use it (does it?).
>
>
> On Sun, Feb 2, 2014 at 3:27 AM, Eric Reed wrote:
>
>> I'm going to respond to Any and size_of separately because there's a
>> significant difference IMO.
>>
>> It's true that Any and trait bounds on type parameters in general can let
>> function behavior depend on the passed type, but only in the specific
>> behavior defined by the trait. Everything that's not a trait function is
>> still independent of the passed type (contrast this with a setup where this
>> wasn't true. `fn foo() -> int' could return 2i for int and spin up a
>> tetris game then crash for uint). Any just happens to be powerful enough to
>> allow complete variance, which is expected since it's just dynamic typing,
>> but there's an important distinction still: behavior variance because of
>> Any *is* part of the function because you need to do explicit type tests.
>>
>> I wasn't aware of mem::size_of before, but I'm rather annoyed to find out
>> we've started adding bare A -> B functions since it breaks parametricity.
>> I'd much rather put size_of in a trait, at which point it's just a weaker
>> version of Any.
>> Being able to tell how a function's behavior might vary just from the
>> type signature is a very nice property, and I'd like Rust to keep it.
>>
>> Now, onto monomorphization.
>> I agree that distinguishing static and dynamic dispatch is important for
>> performance characterization, but static dispatch != monomorphization (or
>> if it currently does, then it probably shouldn't) because not all
>> statically dispatched code needs to be monomorphizied. Consider a function
>> like this:
>>
>> fn foo(ox: Option<~A>, f: |~A| -> ~B) -> Option<~B> {
>> match ox {
>> Some(x) => Some(f(x)),
>> None => None,
>> }
>> }
>>
>> It's quite generic, but AFAIK there's no need to monomorphize it for
>> static dispatch. It uses a constant amount of stack space (not counting
>> what `f' uses when called) and could run the exact same code for any types
>> A or B (check discriminant, potentially call a function pointer, and
>> return). I would guess most cases require monomorphization, but I consider
>> universal monomorphization a way of implementing static dispatch (as
>> opposed to partial monomorphization).
>> I agree that understanding monomorphization is important for
>> understanding the performance characteristics of code generated by *rustc*,
>> but rustc != Rust.
>> Unless universal monomorphization for static dispatch makes its way into
>> the Rust language spec, I'm going to consider it an implementation detail
>> for rustc.
>>
>>
>>
>> On Sat, Feb 1, 2014 at 3:31 PM, Corey Richardson wrote:
>>
>>> On Sat, Feb 1, 2014 at 6:24 PM, Eric Reed 
>>> wrote:
>>> > Responses inlined.
>>> >
>>> >>
>>> >> 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 { ... }
>>> >> impl Trait for Foo { ... }
>>> >> fn foo(...) { ... }
>>> >> ```
>>> >>
>>> >> to:
>>> >>
>>> >> ```
>>> >> forall struct Foo { ... }
>>> >> forall impl Trait for Foo { ... }
>>> >> forall 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

Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-03 Thread Gábor Lehel
Just because Any is a trait doesn't mean it doesn't break parametricity.
Look at this:

http://static.rust-lang.org/doc/master/src/std/home/rustbuild/src/rust-buildbot/slave/doc/build/src/libstd/any.rs.html#37-63

Because we have `impl Any for T`, it can be used with *any
type* (except borrowed data), including type parameters, whether or not
they declare the `T: Any` bound explicitly (which is essentially redundant
in this situation).

The proper thing would be for the compiler to generate an `impl Any for
MyType` for each individual type separately, rather than a single generic
impl which is valid for all types.

I also think we should guarantee parametricity for safe code and make
`size_of` an unsafe fn. Its legitimate uses in unsafe code (e.g. smart
pointers) are well encapsulated and don't expose parametricity violations,
and I don't believe safe code has a legitimate reason to use it (does it?).


On Sun, Feb 2, 2014 at 3:27 AM, Eric Reed  wrote:

> I'm going to respond to Any and size_of separately because there's a
> significant difference IMO.
>
> It's true that Any and trait bounds on type parameters in general can let
> function behavior depend on the passed type, but only in the specific
> behavior defined by the trait. Everything that's not a trait function is
> still independent of the passed type (contrast this with a setup where this
> wasn't true. `fn foo() -> int' could return 2i for int and spin up a
> tetris game then crash for uint). Any just happens to be powerful enough to
> allow complete variance, which is expected since it's just dynamic typing,
> but there's an important distinction still: behavior variance because of
> Any *is* part of the function because you need to do explicit type tests.
>
> I wasn't aware of mem::size_of before, but I'm rather annoyed to find out
> we've started adding bare A -> B functions since it breaks parametricity.
> I'd much rather put size_of in a trait, at which point it's just a weaker
> version of Any.
> Being able to tell how a function's behavior might vary just from the type
> signature is a very nice property, and I'd like Rust to keep it.
>
> Now, onto monomorphization.
> I agree that distinguishing static and dynamic dispatch is important for
> performance characterization, but static dispatch != monomorphization (or
> if it currently does, then it probably shouldn't) because not all
> statically dispatched code needs to be monomorphizied. Consider a function
> like this:
>
> fn foo(ox: Option<~A>, f: |~A| -> ~B) -> Option<~B> {
> match ox {
> Some(x) => Some(f(x)),
> None => None,
> }
> }
>
> It's quite generic, but AFAIK there's no need to monomorphize it for
> static dispatch. It uses a constant amount of stack space (not counting
> what `f' uses when called) and could run the exact same code for any types
> A or B (check discriminant, potentially call a function pointer, and
> return). I would guess most cases require monomorphization, but I consider
> universal monomorphization a way of implementing static dispatch (as
> opposed to partial monomorphization).
> I agree that understanding monomorphization is important for understanding
> the performance characteristics of code generated by *rustc*, but rustc !=
> Rust.
> Unless universal monomorphization for static dispatch makes its way into
> the Rust language spec, I'm going to consider it an implementation detail
> for rustc.
>
>
>
> On Sat, Feb 1, 2014 at 3:31 PM, Corey Richardson  wrote:
>
>> On Sat, Feb 1, 2014 at 6:24 PM, Eric Reed 
>> wrote:
>> > Responses inlined.
>> >
>> >>
>> >> 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 { ... }
>> >> impl Trait for Foo { ... }
>> >> fn foo(...) { ... }
>> >> ```
>> >>
>> >> to:
>> >>
>> >> ```
>> >> forall struct Foo { ... }
>> >> forall impl Trait for Foo { ... }
>> >> forall 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.)
>> >
>> >
>> > I think what I've done in the past was just `grep impl | grep Clone'.
>> >
>> >>
>> >> A deeper, more pedagogical problem, is the mismatch between how `struct
>> >> Foo<...> { ... }` is read and how it 

Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-02 Thread Corey Richardson
Also after sleeping on it I'm not as big of a fan of this proposal.
But, I find the idea raised earlier of having "generic blocks" to
group implementations etc that have the same implementation nice.
Fully backwards compat though, so I'm not going to worry about it.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-02 Thread Matthieu Monrocq
On Sun, Feb 2, 2014 at 6:08 PM, Benjamin Striegel wrote:

> 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  wrote:
>
>> I'm not a huge fan of this proposal.  It makes declarations longer, and
>> it removes the visual consistency of Foo 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 for Foo
>>
>> is because it's ambiguous whether T and U are intended to be concrete or
>> generic type names; i.e.,
>>
>> impl Trait for Foo
>>
>> tells the compiler that we expect U to be a concrete type name.
>>
>> Our new default type parameter declarations look like:
>>
>> struct Foo
>>
>> So what if to actually make generic types concrete, we always used the
>> '='?
>>
>> struct Foo
>> impl Trait for Foo
>>
>> This saves a character over 'impl Trait for Foo', 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 Trait for Foo
>>
>> would become
>>
>> impl Trait for Foo
>>
>> The rule would be that the first use of a type variable T would introduce
>> its bounds, so for instance:
>>
>> impl Trait for Foo
>>
>> would be fine, and
>>
>> impl Trait for Foo
>>
>> would be an error.
>>
>> More nice fallout:
>>
>> struct Foo
>> impl Foo {
>> 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 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 { ... }
>>> impl Trait for Foo { ... }
>>> fn foo(...) { ... }
>>> ```
>>>
>>> to:
>>>
>>> ```
>>> forall struct Foo { ... }
>>> forall impl Trait for Foo { ... }
>>> forall fn foo(...) { ... }
>>> ```
>>>
>>>
>From a readability point of view, I am afraid this might be awkward though.

Coming from a C++, I have welcome the switch from `typedef` to `using`
(aliases) because of alignment issues; consider:

typedef std::map MapType;
typedef std::vector> VectorType;

vs

using MapType = std::map;
using VectorType = std::vector>;

In the latter, the entities being declared are at a constant offset from
the left-hand margin; and close too; whereas in the former, the eyes are
strained as they keep looking for what is declared.


And now, let's look at your proposal:

fn foo(a: int, b: int) -> int { }

fn foo(a: T, b: U) -> T { }

forall fn foo(a: T, b: U) -> T { }

See how "forall" causes a "bump" that forces you to start looking where
that name is ? It was so smooth until then !


So, it might be a net win in terms of grep-ability, but to be honest it
seems LESS readable to me.

-- Matthieu


> 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` (that is, type `Foo` instantiated with
>>> type
>>> `int`) is not the same type as `Foo` (that is, type `Foo`
>>> instantiated
>>> with type `uint`). Of course, with a small amount of experience or a very
>>> simple explanation, that becomes obvious.
>>>
>>> S

Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-02 Thread Benjamin Striegel
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  wrote:

> I'm not a huge fan of this proposal.  It makes declarations longer, and it
> removes the visual consistency of Foo 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 for Foo
>
> is because it's ambiguous whether T and U are intended to be concrete or
> generic type names; i.e.,
>
> impl Trait for Foo
>
> tells the compiler that we expect U to be a concrete type name.
>
> Our new default type parameter declarations look like:
>
> struct Foo
>
> So what if to actually make generic types concrete, we always used the '='?
>
> struct Foo
> impl Trait for Foo
>
> This saves a character over 'impl Trait for Foo', 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 Trait for Foo
>
> would become
>
> impl Trait for Foo
>
> The rule would be that the first use of a type variable T would introduce
> its bounds, so for instance:
>
> impl Trait for Foo
>
> would be fine, and
>
> impl Trait for Foo
>
> would be an error.
>
> More nice fallout:
>
> struct Foo
> impl Foo {
> 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  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 { ... }
>> impl Trait for Foo { ... }
>> fn foo(...) { ... }
>> ```
>>
>> to:
>>
>> ```
>> forall struct Foo { ... }
>> forall impl Trait for Foo { ... }
>> forall 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` (that is, type `Foo` instantiated with
>> type
>> `int`) is not the same type as `Foo` (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 { ... }
>> impl Trait for Foo { ... }
>> fn foo(...) { ... }
>> ```
>>
>> to:
>>
>> ```
>> forall struct Foo { ... }
>> forall impl Trait for Foo { ... }
>

Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-02 Thread Jason Fager
I'm not a huge fan of this proposal.  It makes declarations longer, and it
removes the visual consistency of Foo 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 for Foo

is because it's ambiguous whether T and U are intended to be concrete or
generic type names; i.e.,

impl Trait for Foo

tells the compiler that we expect U to be a concrete type name.

Our new default type parameter declarations look like:

struct Foo

So what if to actually make generic types concrete, we always used the '='?

struct Foo
impl Trait for Foo

This saves a character over 'impl Trait for Foo', 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 Trait for Foo

would become

impl Trait for Foo

The rule would be that the first use of a type variable T would introduce
its bounds, so for instance:

impl Trait for Foo

would be fine, and

impl Trait for Foo

would be an error.

More nice fallout:

struct Foo
impl Foo {
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  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 { ... }
> impl Trait for Foo { ... }
> fn foo(...) { ... }
> ```
>
> to:
>
> ```
> forall struct Foo { ... }
> forall impl Trait for Foo { ... }
> forall 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` (that is, type `Foo` instantiated with type
> `int`) is not the same type as `Foo` (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 { ... }
> impl Trait for Foo { ... }
> fn foo(...) { ... }
> ```
>
> to:
>
> ```
> forall struct Foo { ... }
> forall impl Trait for Foo { ... }
> forall 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/
> __

Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-02 Thread György Andrasek

On 02/01/2014 11:39 PM, Corey Richardson wrote:

```
forall struct Foo { ... }
forall impl Trait for Foo { ... }
forall fn foo(...) { ... }
```


Why not

```
fn foo: pub unsafe  => (f: |T| -> U, arg: T) -> U { f(arg) }
struct foo:  => { ... }
impl Foo:  => Trait { ... }
```

Can we please not put more stuff in front of the identifier? Have we ran 
out of space after it?  What will this look like once the types start 
looking like `templatePred, typename SuperMeta,typename TagList, typename Category> class 
hashed_index`? Do we really need all that in front of a function name?



The immediate, and most pragmatic, problem is that in today's Rust one cannot
easily search for implementations of a trait. Why?


Because the only existing Rust parser is geared towards a native Rust 
compiler, not a non-Rust IDE. That's the problem, not `grep`, and syntax 
changes won't help unless you want to redesign the language to be 
completely regex-compatible. Write a C-bindable parser, plug it into 
`ack`, `ctags` and a couple of IDEs, and everyone will be happy.



(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.)


Then why have such a parsing-oriented grammar in the first place? 
Following this logic, Rust should look more like Haskell, with a Hello 
Kitty binop `(=^.^=)`. (I swear I've seen this in real code somewhere)



___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-02 Thread Benjamin Herr

On Sun, 2014-02-02 at 14:45 +1300, Nick Cameron wrote:

> - The change adds boilerplate and nomenclature that is likely
> unfamiliar to our target audience - 'for all' is well known to
> functional programmers, but I believe that is not true for most users
> of C++ (or Java). Being closer to the C++/Java syntax for generics is
> probably more 'intuitive


So instead of 'for all', use 'template', and we're closer to C++ syntax
than ever!

template
struct Foo { ... }

template
impl Trait for Foo { ... }

template
fn foo(...) { ... }

;-)

fwiw, like C++, Java generic methods also put the <> type parameter list
in front of the function signature rather than behind the function name:

public static >
int countGreaterThan(T[] anArray, T elem) { ... } 

... while C# apparently compromises and puts the type parameters between
the function name and value parameter list, but leaves the bounds for
later:

 public static bool Contains(IEnumerable collection, T item) 
   where T : IComparable;

Neither approach translates too well into Rust, but that Rust is almost
the odd one out here makes me sympathetic to the desire to avoid
breaking up particularly function declarations between the name and the
value parameter list too much, in spite of the familiarity argument.

Of course, like everything else, that has to be balanced with avoiding
superficial but far-reaching overhauls of the language at the eleventh
hour. Alas!


-benh




___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Huon Wilson

On 02/02/14 14:18, Daniel Micay wrote:

On Sat, Feb 1, 2014 at 10:12 PM, Eric Reed  wrote:

Well there's only 260 uses of the string "size_of" in rustc's src/ according
to grep and only 3 uses of "size_of" in servo according to GitHub, so I
think you may be overestimating its usage.

The number of calls to `size_of` isn't a useful metric. It's the
building block required to allocate memory (vectors, unique pointers)
and in the slice iterators (to perform pointer arithmetic). If it
requires a bound, then so will any code using a slice iterator.


Either way, I'm not proposing we get rid of size_of. I just think we should
put it in an automatically derived trait instead of defining a function on
all types.
Literally the only thing that would change would be code like this:

fn foo(t: T) {
 let size = mem::size_of(t);
}

would have to be changed to:

fn foo(t: T) {
 let size = SizeOf::size_of(t); // or t.size_of()
}

Is that really so bad?

Yes, it is.


Now the function's type signature documents that the function's behavior
depends on the size of the type.
If you see a signature like `fn foo(t: T)', then you know that it
doesn't.
There's no additional performance overhead and it makes size_of like other
intrinsic operators (+, ==, etc.).

The operators are not implemented for every type as they are for `size_of`.


I seriously don't see what downside this could possibly have.

Using unique pointers, vectors and even slice iterators will require a
semantically irrelevant `SizeOf` bound. Whether or not you allocate a
unique pointer to store a value internally shouldn't be part of the
function signature.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


To add to this, a SizeOf bound would be essentially equivalent to the 
Sized bound from DST, and I believe experimentation a while ago decided 
that requiring Sized is the common case (or, at least, so common that it 
would be extremely annoying to require it be explicit).



Huon
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Daniel Micay
On Sat, Feb 1, 2014 at 10:12 PM, Eric Reed  wrote:
> Well there's only 260 uses of the string "size_of" in rustc's src/ according
> to grep and only 3 uses of "size_of" in servo according to GitHub, so I
> think you may be overestimating its usage.

The number of calls to `size_of` isn't a useful metric. It's the
building block required to allocate memory (vectors, unique pointers)
and in the slice iterators (to perform pointer arithmetic). If it
requires a bound, then so will any code using a slice iterator.

> Either way, I'm not proposing we get rid of size_of. I just think we should
> put it in an automatically derived trait instead of defining a function on
> all types.
> Literally the only thing that would change would be code like this:
>
> fn foo(t: T) {
> let size = mem::size_of(t);
> }
>
> would have to be changed to:
>
> fn foo(t: T) {
> let size = SizeOf::size_of(t); // or t.size_of()
> }
>
> Is that really so bad?

Yes, it is.

> Now the function's type signature documents that the function's behavior
> depends on the size of the type.
> If you see a signature like `fn foo(t: T)', then you know that it
> doesn't.
> There's no additional performance overhead and it makes size_of like other
> intrinsic operators (+, ==, etc.).

The operators are not implemented for every type as they are for `size_of`.

> I seriously don't see what downside this could possibly have.

Using unique pointers, vectors and even slice iterators will require a
semantically irrelevant `SizeOf` bound. Whether or not you allocate a
unique pointer to store a value internally shouldn't be part of the
function signature.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Eric Reed
Well there's only 260 uses of the string "size_of" in rustc's src/
according to grep and only 3 uses of "size_of" in servo according to
GitHub, so I think you may be overestimating its usage.

Either way, I'm not proposing we get rid of size_of. I just think we should
put it in an automatically derived trait instead of defining a function on
all types.
Literally the only thing that would change would be code like this:

fn foo(t: T) {
let size = mem::size_of(t);
}

would have to be changed to:

fn foo(t: T) {
let size = SizeOf::size_of(t); // or t.size_of()
}

Is that really so bad?
Now the function's type signature documents that the function's behavior
depends on the size of the type.
If you see a signature like `fn foo(t: T)', then you know that it
doesn't.
There's no additional performance overhead and it makes size_of like other
intrinsic operators (+, ==, etc.).

I seriously don't see what downside this could possibly have.



On Sat, Feb 1, 2014 at 6:43 PM, Daniel Micay  wrote:

> On Sat, Feb 1, 2014 at 9:27 PM, Eric Reed 
> wrote:
> >
> > I wasn't aware of mem::size_of before, but I'm rather annoyed to find out
> > we've started adding bare A -> B functions since it breaks parametricity.
> > I'd much rather put size_of in a trait, at which point it's just a weaker
> > version of Any.
>
> You do realize how widely used size_of is, right? I don't this it
> makes sense to say we've *started* adding this stuff when being able
> to get the size/alignment has pretty much always been there.
>
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Patrick Walton

On 2/1/14 6:50 PM, Daniel Micay wrote:

This could be restricted to `unsafe` code by making reflection
features `unsafe` and mandating that safe functions must compile for
types meeting the bounds.

The `size_of` functionality is absolutely required to have any hope of
writing smart pointers and containers in the library, without using ~T
and ~[T] as the sole allocators.


Oh, don't worry, I'm not proposing removing either transmute or sizeof. 
Just saying it bugs the theorist in me. :)


Patrick

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Daniel Micay
On Sat, Feb 1, 2014 at 9:46 PM, Patrick Walton  wrote:
> On 2/1/14 6:43 PM, Daniel Micay wrote:
>>
>> On Sat, Feb 1, 2014 at 9:27 PM, Eric Reed 
>> wrote:
>>>
>>>
>>> I wasn't aware of mem::size_of before, but I'm rather annoyed to find out
>>> we've started adding bare A -> B functions since it breaks parametricity.
>>> I'd much rather put size_of in a trait, at which point it's just a weaker
>>> version of Any.
>>
>>
>> You do realize how widely used size_of is, right? I don't this it
>> makes sense to say we've *started* adding this stuff when being able
>> to get the size/alignment has pretty much always been there.
>
>
> `transmute()` breaks parametricity too, which is annoying to me because you
> can get C++-template-expansion-style errors in translation time ("transmute
> called on types of different sizes"). I proposed changing it to a dynamic
> runtime failure if the types had different sizes, which eliminates ad-hoc
> templates leaking into our trait system, but that met with extremely strong
> objections from pretty much everyone.
>
> Patrick

This could be restricted to `unsafe` code by making reflection
features `unsafe` and mandating that safe functions must compile for
types meeting the bounds.

The `size_of` functionality is absolutely required to have any hope of
writing smart pointers and containers in the library, without using ~T
and ~[T] as the sole allocators.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Patrick Walton

On 2/1/14 6:43 PM, Daniel Micay wrote:

On Sat, Feb 1, 2014 at 9:27 PM, Eric Reed  wrote:


I wasn't aware of mem::size_of before, but I'm rather annoyed to find out
we've started adding bare A -> B functions since it breaks parametricity.
I'd much rather put size_of in a trait, at which point it's just a weaker
version of Any.


You do realize how widely used size_of is, right? I don't this it
makes sense to say we've *started* adding this stuff when being able
to get the size/alignment has pretty much always been there.


`transmute()` breaks parametricity too, which is annoying to me because 
you can get C++-template-expansion-style errors in translation time 
("transmute called on types of different sizes"). I proposed changing it 
to a dynamic runtime failure if the types had different sizes, which 
eliminates ad-hoc templates leaking into our trait system, but that met 
with extremely strong objections from pretty much everyone.


Patrick


___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Daniel Micay
On Sat, Feb 1, 2014 at 9:27 PM, Eric Reed  wrote:
>
> I wasn't aware of mem::size_of before, but I'm rather annoyed to find out
> we've started adding bare A -> B functions since it breaks parametricity.
> I'd much rather put size_of in a trait, at which point it's just a weaker
> version of Any.

You do realize how widely used size_of is, right? I don't this it
makes sense to say we've *started* adding this stuff when being able
to get the size/alignment has pretty much always been there.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Eric Reed
I'm going to respond to Any and size_of separately because there's a
significant difference IMO.

It's true that Any and trait bounds on type parameters in general can let
function behavior depend on the passed type, but only in the specific
behavior defined by the trait. Everything that's not a trait function is
still independent of the passed type (contrast this with a setup where this
wasn't true. `fn foo() -> int' could return 2i for int and spin up a
tetris game then crash for uint). Any just happens to be powerful enough to
allow complete variance, which is expected since it's just dynamic typing,
but there's an important distinction still: behavior variance because of
Any *is* part of the function because you need to do explicit type tests.

I wasn't aware of mem::size_of before, but I'm rather annoyed to find out
we've started adding bare A -> B functions since it breaks parametricity.
I'd much rather put size_of in a trait, at which point it's just a weaker
version of Any.
Being able to tell how a function's behavior might vary just from the type
signature is a very nice property, and I'd like Rust to keep it.

Now, onto monomorphization.
I agree that distinguishing static and dynamic dispatch is important for
performance characterization, but static dispatch != monomorphization (or
if it currently does, then it probably shouldn't) because not all
statically dispatched code needs to be monomorphizied. Consider a function
like this:

fn foo(ox: Option<~A>, f: |~A| -> ~B) -> Option<~B> {
match ox {
Some(x) => Some(f(x)),
None => None,
}
}

It's quite generic, but AFAIK there's no need to monomorphize it for static
dispatch. It uses a constant amount of stack space (not counting what `f'
uses when called) and could run the exact same code for any types A or B
(check discriminant, potentially call a function pointer, and return). I
would guess most cases require monomorphization, but I consider universal
monomorphization a way of implementing static dispatch (as opposed to
partial monomorphization).
I agree that understanding monomorphization is important for understanding
the performance characteristics of code generated by *rustc*, but rustc !=
Rust.
Unless universal monomorphization for static dispatch makes its way into
the Rust language spec, I'm going to consider it an implementation detail
for rustc.



On Sat, Feb 1, 2014 at 3:31 PM, Corey Richardson  wrote:

> On Sat, Feb 1, 2014 at 6:24 PM, Eric Reed 
> wrote:
> > Responses inlined.
> >
> >>
> >> 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 { ... }
> >> impl Trait for Foo { ... }
> >> fn foo(...) { ... }
> >> ```
> >>
> >> to:
> >>
> >> ```
> >> forall struct Foo { ... }
> >> forall impl Trait for Foo { ... }
> >> forall 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.)
> >
> >
> > I think what I've done in the past was just `grep impl | grep Clone'.
> >
> >>
> >> 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` (that is, type `Foo` instantiated with
> >> type
> >> `int`) is not the same type as `Foo` (that is, type `Foo`
> >> instantiated
> >> with type `uint`). Of course, with a small amount of experience or a
> very
> >> simple explanation, that becomes obvious.
> >
> >
> > I strongly disagree with this reasoning.
> > There IS only one type Foo. It's a type constructor with kind * -> *
> (where
> > * means proper type).
> > Foo and Foo are two different applications of Foo and are
> proper
> > types (i.e. *) because Foo is * -> * and both int and uint are *.
> > Regarding people confusing Foo, Foo and Foo, I think the
> proposed
> > forall struct Foo {...} syntax is actually more confusing.
> > With the current syntax, it's never legal to write Foo without type
> > parameters, but with the proposed syntax it would be.
> >
>
> I've yet to see a proposal for HKT

Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Nick Cameron
I prefer the existing syntax.

- As pointed out above, there are solutions to the non-grep-ability.

- The change adds boilerplate and nomenclature that is likely unfamiliar to
our target audience - 'for all' is well known to functional programmers,
but I believe that is not true for most users of C++ (or Java). Being
closer to the C++/Java syntax for generics is probably more 'intuitive'.

- I do not think generics imply polymorphic implementation - C++
programmers are used to generics having monomorphic implementations.

- Starting an item definition with the most important keyword is nice and
we would lose that - currently it is easy to scan down the start of lines
and see that something is a fn, impl, struct, etc. With the change you just
see that something is generic or not, which is not what you are interested
in when scanning. Put another way, I believe this change prioritises
automatic search (grep, which can be fixed) over visual search (which
cannot).

(I do agree that formatting lists of type params is difficult)

Cheers, Nick


On Sun, Feb 2, 2014 at 11:39 AM, Corey Richardson  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 { ... }
> impl Trait for Foo { ... }
> fn foo(...) { ... }
> ```
>
> to:
>
> ```
> forall struct Foo { ... }
> forall impl Trait for Foo { ... }
> forall 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` (that is, type `Foo` instantiated with type
> `int`) is not the same type as `Foo` (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 { ... }
> impl Trait for Foo { ... }
> fn foo(...) { ... }
> ```
>
> to:
>
> ```
> forall struct Foo { ... }
> forall impl Trait for Foo { ... }
> forall 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


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Armin Ronacher

Hi,

On 01/02/2014 22:58, Corey Richardson wrote:

I'd be equally happy with for instead of forall.
+1 on not using forall, it sounds confusing and is actually quite a bit to type 
considering how frequent these things are.


As an alternative to "for" I would want to throw "be" and "use" into the mix. 
"be" is currently already reserved, but not sure how well it sounds.



Regards,
Armin

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Eric Summers

> 
> forall {
>   impl BinaryEncoder for MyStruct { … }
>   impl BinaryDecoder for MyStruct { … }
> }

comex mentioned the idea of a generic module.  That would be interesting.  I 
like that idea better then this.

> 
> I also like how it breaks across lines:
> 
> forall
> struct Foo {
> …
> }
> 

I guess it currently breaks ok for long type params:
impl
Trait 
for Foo {
...
}

I think the grep issue will be solved by libsyntax being integrated in text 
editor plugins.

-Eric
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread comex
On Sat, Feb 1, 2014 at 5:39 PM, Corey Richardson  wrote:
> 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 ...".

I read "struct Foo<...> { ... }" the same way as "fn foo(...) -> ...".
 In the latter case, given some value parameters, I get a return
value; in the former, given some type parameters, I get a struct.  On
the contrary, I would find the idea that "forall fn" is specified
with "fn::", like in C++ (template ) relatively
confusing.

For bulk generics I would rather have the concept of a generic module
than just copy the generic arguments onto each item.  (For that
matter, I think I'd like to have traits on modules or something like
that, so that you can have something like a list trait which comes
with a type for the list and a type for its iterator, without having
to write two generic parameters on everything.  But that's a different
story.)

Also, I think the syntax for generics is verbose enough as it is; I'd
rather see it shortened than lengthened.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Corey Richardson
On Sat, Feb 1, 2014 at 6:31 PM, Corey Richardson  wrote:
> On Sat, Feb 1, 2014 at 6:24 PM, Eric Reed  wrote:
>> Again, I strongly disagree here.
>> There IS only one function foo. Some of it's arguments are types. foo's
>> behavior *does not change* based on the type parameters because of
>> parametricity.
>> That the compiler monomporphizes generic functions is just an implementation
>> detail and doesn't change the semantics of the function.
>>
>
> It can if it uses Any, size_of, etc. eddyb had "integers in the
> typesystem" by using size_of and [u8, ..N]. Anything using the
> "properties" of types or the tydescs *will* change for each
> instantiation.
>

Furthermore, I don't considered monomorphic instantiation to be an
implementation detail. Without it the difference between trait objects
and generics is nonsensical, and iirc there's code that depends on the
addresses of different instantiations being different (though I might
be confusing that with statics). It's also important to understanding
the performance characteristics of Rust, esp binary size and why
metadata is so huge.

It's a vital detail to understanding Rust, and any use of it needs to
consider it. If it is indeed considered an implementation detail, it's
probably the most important implementation detail I've seen in
anything. Given Rust's target market, it'd be irresponsible to ignore
it...
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Brian Anderson

On 02/01/2014 02:59 PM, Benjamin Striegel wrote:

> Yes, and I don't have a solution for that.

Well, it's not like we don't already stumble here a bit, what with 
requiring ::<> instead of just <>. Not sure how much other people 
value the consistency here.


Yeah, the existing solution is bad, and also rare. If changing the 
declaration might happen then you might as well make another minor 
change for consistency, possibly for the better.





On Sat, Feb 1, 2014 at 5:58 PM, Corey Richardson > wrote:


On Sat, Feb 1, 2014 at 5:55 PM, Benjamin Striegel
mailto:ben.strie...@gmail.com>> wrote:
> First of all, why a new keyword? Reusing `for` here would be totally
> unambiguous. :P And also save us from creating the precedent of
multi-word
> keywords.
>

I'd be equally happy with for instead of forall.

> Secondly, currently Rust has a philosophy of
use-follows-declaration (i.e.
> the syntax for using something mirrors the syntax for declaring
it). This
> would eliminate that.
>

Yes, and I don't have a solution for that.




___
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


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Corey Richardson
On Sat, Feb 1, 2014 at 6:24 PM, Eric Reed  wrote:
> Responses inlined.
>
>>
>> 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 { ... }
>> impl Trait for Foo { ... }
>> fn foo(...) { ... }
>> ```
>>
>> to:
>>
>> ```
>> forall struct Foo { ... }
>> forall impl Trait for Foo { ... }
>> forall 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.)
>
>
> I think what I've done in the past was just `grep impl | grep Clone'.
>
>>
>> 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` (that is, type `Foo` instantiated with
>> type
>> `int`) is not the same type as `Foo` (that is, type `Foo`
>> instantiated
>> with type `uint`). Of course, with a small amount of experience or a very
>> simple explanation, that becomes obvious.
>
>
> I strongly disagree with this reasoning.
> There IS only one type Foo. It's a type constructor with kind * -> * (where
> * means proper type).
> Foo and Foo are two different applications of Foo and are proper
> types (i.e. *) because Foo is * -> * and both int and uint are *.
> Regarding people confusing Foo, Foo and Foo, I think the proposed
> forall struct Foo {...} syntax is actually more confusing.
> With the current syntax, it's never legal to write Foo without type
> parameters, but with the proposed syntax it would be.
>

I've yet to see a proposal for HKT, but with them that interpretation
would be valid and indeed make this proposal's argument weaker.

>>
>> 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).
>
>
> Again, I strongly disagree here.
> There IS only one function foo. Some of it's arguments are types. foo's
> behavior *does not change* based on the type parameters because of
> parametricity.
> That the compiler monomporphizes generic functions is just an implementation
> detail and doesn't change the semantics of the function.
>

It can if it uses Any, size_of, etc. eddyb had "integers in the
typesystem" by using size_of and [u8, ..N]. Anything using the
"properties" of types or the tydescs *will* change for each
instantiation.

>>
>> Another minor problem is that nicely formatting long lists of type
>> parameters
>> or type parameters with many bounds is difficult.
>
>
> I'm not sure how this proposal would address this problem. All of your
> proposed examples are longer than the current syntax equivalents.
>

The idea is there is an obvious place to insert a newline (after the
forall), though bjz would have to comment more on that.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Eric Summers

> ```
> forall struct Foo { ... }
> forall impl Trait for Foo { ... }
> forall fn foo(...) { ... }
> ```


I’m new to rust, so maybe this doesn’t make sense, but would it make sense to 
have a variation of this syntax to make implementing related traits and 
functions more DRY?  Essentially allow the for all to be shared.  While I’ve 
been skimming code to learn Rust, I noticed trait restrictions in particular 
seem to be repeated a lot in functions and traits that are related to each 
other.

forall {
impl BinaryEncoder for MyStruct { … }
impl BinaryDecoder for MyStruct { … }
}

I also like how it breaks across lines:

forall
struct Foo {
...
}

It looks like someone else suggested this while I was typing, but I like the 
aesthetics of it.

-Eric
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Eric Reed
Responses inlined.


> 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 { ... }
> impl Trait for Foo { ... }
> fn foo(...) { ... }
> ```
>
> to:
>
> ```
> forall struct Foo { ... }
> forall impl Trait for Foo { ... }
> forall 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.)
>

I think what I've done in the past was just `grep impl | grep Clone'.


> 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` (that is, type `Foo` instantiated with type
> `int`) is not the same type as `Foo` (that is, type `Foo`
> instantiated
> with type `uint`). Of course, with a small amount of experience or a very
> simple explanation, that becomes obvious.
>

I strongly disagree with this reasoning.
There IS only one type Foo. It's a type constructor with kind * -> * (where
* means proper type).
Foo and Foo are two different applications of Foo and are proper
types (i.e. *) because Foo is * -> * and both int and uint are *.
Regarding people confusing Foo, Foo and Foo, I think the
proposed forall struct Foo {...} syntax is actually more confusing.
With the current syntax, it's never legal to write Foo without type
parameters, but with the proposed syntax it would be.


> 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).
>

Again, I strongly disagree here.
There IS only one function foo. Some of it's arguments are types. foo's
behavior *does not change* based on the type parameters because of
parametricity.
That the compiler monomporphizes generic functions is just an
implementation detail and doesn't change the semantics of the function.


> Another minor problem is that nicely formatting long lists of type
> parameters
> or type parameters with many bounds is difficult.
>

I'm not sure how this proposal would address this problem. All of your
proposed examples are longer than the current syntax equivalents.


>
> 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 { ... }
> impl Trait for Foo { ... }
> fn foo(...) { ... }
> ```
>
> to:
>
> ```
> forall struct Foo { ... }
> forall impl Trait for Foo { ... }
> forall 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.
>
>
I don't have a preference between the current syntax or your proposed
syntax, but I generally disagree that what you claim is a problem is in
fact a problem or that your proposal would address it.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Corey Richardson
On Sat, Feb 1, 2014 at 6:12 PM, Vladimir Lushnikov
 wrote:
> Also, reusing 'for' would be confusing as well, because you expect a loop
> there, not a generic type bound. How about 'any':
>

any is a super useful identifier and is already used. I do not want to
reserve it.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Scott Lawrence

It seems to use a '+' instead of ','.

On Sat, 1 Feb 2014, Benjamin Striegel wrote:


How about supporting type aliases as Scala does?


In theory I think that should be achievable today, using trait inheritance:

   trait MyT : Clone, Eq {}

...at least, I *think* we allow multiple trait inheritance. Not sure what
the syntax is!


On Sat, Feb 1, 2014 at 6:12 PM, Vladimir Lushnikov <
vladi...@slate-project.org> wrote:


Placing type bounds before the name of the thing you are trying to declare
feels unnatural to me. And the generic block is far too much boilerplate!

How about supporting type aliases as Scala does? So you write:

  type MyT = Clone + Eq
  fn foo(t: T, u: U) -> ...

and the 'type' is just an alias for any type that has Clone + Eq?

Obviously the above only solves repeating yourself for complex type
constraints.

Also, reusing 'for' would be confusing as well, because you expect a loop
there, not a generic type bound. How about 'any':

any  fn foo (t: T, u: U) -> ...

?


On Sat, Feb 1, 2014 at 11:06 PM, Benjamin Striegel 
wrote:



Another point in favor of this plan is that it would eliminate the need
to put type parameters directly after the `impl`, which to be honest *is*
pretty weird and inconsistent with the rest of the language. But I'm still
not sure how I feel about the look of it:

for  fn foo(t: T, u: U) -> (T, U) {

If you choose *not* to wrap after the type parameters there, you're
really obscuring what the heck you're trying to declare.

Heck, maybe what we're really asking for is for the ability to have
"generic blocks" within which type parameters can be declared once:

for  {
fn foo(t: T, u: U) -> (T, U) {

...but that's even *more* boilerplate!




On Sat, Feb 1, 2014 at 5:59 PM, Benjamin Striegel 
wrote:



Yes, and I don't have a solution for that.


Well, it's not like we don't already stumble here a bit, what with
requiring ::<> instead of just <>. Not sure how much other people value the
consistency here.


On Sat, Feb 1, 2014 at 5:58 PM, Corey Richardson wrote:


On Sat, Feb 1, 2014 at 5:55 PM, Benjamin Striegel
 wrote:

First of all, why a new keyword? Reusing `for` here would be totally
unambiguous. :P And also save us from creating the precedent of

multi-word

keywords.



I'd be equally happy with for instead of forall.


Secondly, currently Rust has a philosophy of use-follows-declaration

(i.e.

the syntax for using something mirrors the syntax for declaring it).

This

would eliminate that.



Yes, and I don't have a solution for that.






___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev








--
Scott Lawrence
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Corey Richardson
Would also need to add an `impl MyT for T`, so we've
gone in a circle.

On Sat, Feb 1, 2014 at 6:16 PM, Benjamin Striegel
 wrote:
>> How about supporting type aliases as Scala does?
>
> In theory I think that should be achievable today, using trait inheritance:
>
> trait MyT : Clone, Eq {}
>
> ...at least, I *think* we allow multiple trait inheritance. Not sure what
> the syntax is!
>
>
> On Sat, Feb 1, 2014 at 6:12 PM, Vladimir Lushnikov
>  wrote:
>>
>> Placing type bounds before the name of the thing you are trying to declare
>> feels unnatural to me. And the generic block is far too much boilerplate!
>>
>> How about supporting type aliases as Scala does? So you write:
>>
>>   type MyT = Clone + Eq
>>   fn foo(t: T, u: U) -> …
>>
>> and the 'type' is just an alias for any type that has Clone + Eq?
>>
>> Obviously the above only solves repeating yourself for complex type
>> constraints.
>>
>> Also, reusing 'for' would be confusing as well, because you expect a loop
>> there, not a generic type bound. How about 'any':
>>
>> any  fn foo (t: T, u: U) -> …
>>
>> ?
>>
>>
>> On Sat, Feb 1, 2014 at 11:06 PM, Benjamin Striegel
>>  wrote:
>>>
>>> Another point in favor of this plan is that it would eliminate the need
>>> to put type parameters directly after the `impl`, which to be honest *is*
>>> pretty weird and inconsistent with the rest of the language. But I'm still
>>> not sure how I feel about the look of it:
>>>
>>> for  fn foo(t: T, u: U) -> (T, U) {
>>>
>>> If you choose *not* to wrap after the type parameters there, you're
>>> really obscuring what the heck you're trying to declare.
>>>
>>> Heck, maybe what we're really asking for is for the ability to have
>>> "generic blocks" within which type parameters can be declared once:
>>>
>>> for  {
>>> fn foo(t: T, u: U) -> (T, U) {
>>>
>>> ...but that's even *more* boilerplate!
>>>
>>>
>>>
>>>
>>> On Sat, Feb 1, 2014 at 5:59 PM, Benjamin Striegel
>>>  wrote:

 > Yes, and I don't have a solution for that.

 Well, it's not like we don't already stumble here a bit, what with
 requiring ::<> instead of just <>. Not sure how much other people value the
 consistency here.


 On Sat, Feb 1, 2014 at 5:58 PM, Corey Richardson 
 wrote:
>
> On Sat, Feb 1, 2014 at 5:55 PM, Benjamin Striegel
>  wrote:
> > First of all, why a new keyword? Reusing `for` here would be totally
> > unambiguous. :P And also save us from creating the precedent of
> > multi-word
> > keywords.
> >
>
> I'd be equally happy with for instead of forall.
>
> > Secondly, currently Rust has a philosophy of use-follows-declaration
> > (i.e.
> > the syntax for using something mirrors the syntax for declaring it).
> > This
> > would eliminate that.
> >
>
> Yes, and I don't have a solution for that.


>>>
>>>
>>> ___
>>> 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


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Benjamin Striegel
> How about supporting type aliases as Scala does?

In theory I think that should be achievable today, using trait inheritance:

trait MyT : Clone, Eq {}

...at least, I *think* we allow multiple trait inheritance. Not sure what
the syntax is!


On Sat, Feb 1, 2014 at 6:12 PM, Vladimir Lushnikov <
vladi...@slate-project.org> wrote:

> Placing type bounds before the name of the thing you are trying to declare
> feels unnatural to me. And the generic block is far too much boilerplate!
>
> How about supporting type aliases as Scala does? So you write:
>
>   type MyT = Clone + Eq
>   fn foo(t: T, u: U) -> ...
>
> and the 'type' is just an alias for any type that has Clone + Eq?
>
> Obviously the above only solves repeating yourself for complex type
> constraints.
>
> Also, reusing 'for' would be confusing as well, because you expect a loop
> there, not a generic type bound. How about 'any':
>
> any  fn foo (t: T, u: U) -> ...
>
> ?
>
>
> On Sat, Feb 1, 2014 at 11:06 PM, Benjamin Striegel  > wrote:
>
>> Another point in favor of this plan is that it would eliminate the need
>> to put type parameters directly after the `impl`, which to be honest *is*
>> pretty weird and inconsistent with the rest of the language. But I'm still
>> not sure how I feel about the look of it:
>>
>> for  fn foo(t: T, u: U) -> (T, U) {
>>
>> If you choose *not* to wrap after the type parameters there, you're
>> really obscuring what the heck you're trying to declare.
>>
>> Heck, maybe what we're really asking for is for the ability to have
>> "generic blocks" within which type parameters can be declared once:
>>
>> for  {
>> fn foo(t: T, u: U) -> (T, U) {
>>
>> ...but that's even *more* boilerplate!
>>
>>
>>
>>
>> On Sat, Feb 1, 2014 at 5:59 PM, Benjamin Striegel > > wrote:
>>
>>> > Yes, and I don't have a solution for that.
>>>
>>> Well, it's not like we don't already stumble here a bit, what with
>>> requiring ::<> instead of just <>. Not sure how much other people value the
>>> consistency here.
>>>
>>>
>>> On Sat, Feb 1, 2014 at 5:58 PM, Corey Richardson wrote:
>>>
 On Sat, Feb 1, 2014 at 5:55 PM, Benjamin Striegel
  wrote:
 > First of all, why a new keyword? Reusing `for` here would be totally
 > unambiguous. :P And also save us from creating the precedent of
 multi-word
 > keywords.
 >

 I'd be equally happy with for instead of forall.

 > Secondly, currently Rust has a philosophy of use-follows-declaration
 (i.e.
 > the syntax for using something mirrors the syntax for declaring it).
 This
 > would eliminate that.
 >

 Yes, and I don't have a solution for that.

>>>
>>>
>>
>> ___
>> 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


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Vladimir Lushnikov
Placing type bounds before the name of the thing you are trying to declare
feels unnatural to me. And the generic block is far too much boilerplate!

How about supporting type aliases as Scala does? So you write:

  type MyT = Clone + Eq
  fn foo(t: T, u: U) -> …

and the 'type' is just an alias for any type that has Clone + Eq?

Obviously the above only solves repeating yourself for complex type
constraints.

Also, reusing 'for' would be confusing as well, because you expect a loop
there, not a generic type bound. How about 'any':

any  fn foo (t: T, u: U) -> …

?


On Sat, Feb 1, 2014 at 11:06 PM, Benjamin Striegel
wrote:

> Another point in favor of this plan is that it would eliminate the need to
> put type parameters directly after the `impl`, which to be honest *is*
> pretty weird and inconsistent with the rest of the language. But I'm still
> not sure how I feel about the look of it:
>
> for  fn foo(t: T, u: U) -> (T, U) {
>
> If you choose *not* to wrap after the type parameters there, you're really
> obscuring what the heck you're trying to declare.
>
> Heck, maybe what we're really asking for is for the ability to have
> "generic blocks" within which type parameters can be declared once:
>
> for  {
> fn foo(t: T, u: U) -> (T, U) {
>
> ...but that's even *more* boilerplate!
>
>
>
>
> On Sat, Feb 1, 2014 at 5:59 PM, Benjamin Striegel 
> wrote:
>
>> > Yes, and I don't have a solution for that.
>>
>> Well, it's not like we don't already stumble here a bit, what with
>> requiring ::<> instead of just <>. Not sure how much other people value the
>> consistency here.
>>
>>
>> On Sat, Feb 1, 2014 at 5:58 PM, Corey Richardson wrote:
>>
>>> On Sat, Feb 1, 2014 at 5:55 PM, Benjamin Striegel
>>>  wrote:
>>> > First of all, why a new keyword? Reusing `for` here would be totally
>>> > unambiguous. :P And also save us from creating the precedent of
>>> multi-word
>>> > keywords.
>>> >
>>>
>>> I'd be equally happy with for instead of forall.
>>>
>>> > Secondly, currently Rust has a philosophy of use-follows-declaration
>>> (i.e.
>>> > the syntax for using something mirrors the syntax for declaring it).
>>> This
>>> > would eliminate that.
>>> >
>>>
>>> Yes, and I don't have a solution for that.
>>>
>>
>>
>
> ___
> 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


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Tim Kuehn
On Sat, Feb 1, 2014 at 3:06 PM, Benjamin Striegel wrote:

> Another point in favor of this plan is that it would eliminate the need to
> put type parameters directly after the `impl`, which to be honest *is*
> pretty weird and inconsistent with the rest of the language. But I'm still
> not sure how I feel about the look of it:
>
> for  fn foo(t: T, u: U) -> (T, U) {
>
> If you choose *not* to wrap after the type parameters there, you're really
> obscuring what the heck you're trying to declare.
>
> Heck, maybe what we're really asking for is for the ability to have
> "generic blocks" within which type parameters can be declared once:
>
> for  {
> fn foo(t: T, u: U) -> (T, U) {
>
> ...but that's even *more* boilerplate!
>
> It'd mirror how impls work, though, which would be nice. It could be
optional.









>
> On Sat, Feb 1, 2014 at 5:59 PM, Benjamin Striegel 
> wrote:
>
>> > Yes, and I don't have a solution for that.
>>
>> Well, it's not like we don't already stumble here a bit, what with
>> requiring ::<> instead of just <>. Not sure how much other people value the
>> consistency here.
>>
>>
>> On Sat, Feb 1, 2014 at 5:58 PM, Corey Richardson wrote:
>>
>>> On Sat, Feb 1, 2014 at 5:55 PM, Benjamin Striegel
>>>  wrote:
>>> > First of all, why a new keyword? Reusing `for` here would be totally
>>> > unambiguous. :P And also save us from creating the precedent of
>>> multi-word
>>> > keywords.
>>> >
>>>
>>> I'd be equally happy with for instead of forall.
>>>
>>> > Secondly, currently Rust has a philosophy of use-follows-declaration
>>> (i.e.
>>> > the syntax for using something mirrors the syntax for declaring it).
>>> This
>>> > would eliminate that.
>>> >
>>>
>>> Yes, and I don't have a solution for that.
>>>
>>
>>
>
> ___
> 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


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Benjamin Striegel
Another point in favor of this plan is that it would eliminate the need to
put type parameters directly after the `impl`, which to be honest *is*
pretty weird and inconsistent with the rest of the language. But I'm still
not sure how I feel about the look of it:

for  fn foo(t: T, u: U) -> (T, U) {

If you choose *not* to wrap after the type parameters there, you're really
obscuring what the heck you're trying to declare.

Heck, maybe what we're really asking for is for the ability to have
"generic blocks" within which type parameters can be declared once:

for  {
fn foo(t: T, u: U) -> (T, U) {

...but that's even *more* boilerplate!




On Sat, Feb 1, 2014 at 5:59 PM, Benjamin Striegel wrote:

> > Yes, and I don't have a solution for that.
>
> Well, it's not like we don't already stumble here a bit, what with
> requiring ::<> instead of just <>. Not sure how much other people value the
> consistency here.
>
>
> On Sat, Feb 1, 2014 at 5:58 PM, Corey Richardson  wrote:
>
>> On Sat, Feb 1, 2014 at 5:55 PM, Benjamin Striegel
>>  wrote:
>> > First of all, why a new keyword? Reusing `for` here would be totally
>> > unambiguous. :P And also save us from creating the precedent of
>> multi-word
>> > keywords.
>> >
>>
>> I'd be equally happy with for instead of forall.
>>
>> > Secondly, currently Rust has a philosophy of use-follows-declaration
>> (i.e.
>> > the syntax for using something mirrors the syntax for declaring it).
>> This
>> > would eliminate that.
>> >
>>
>> Yes, and I don't have a solution for that.
>>
>
>
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Vladimir Lushnikov
I like the idea (grepability) in theory, but 'for all' to me means that you
do *not* monomorphise the type immediately. This is especially obvious when
considering single function bounds and not trait bounds (but I guess there
are no plans to support HoF so it does not matter anyway).


On Sat, Feb 1, 2014 at 10:59 PM, Benjamin Striegel
wrote:

> > Yes, and I don't have a solution for that.
>
> Well, it's not like we don't already stumble here a bit, what with
> requiring ::<> instead of just <>. Not sure how much other people value the
> consistency here.
>
>
> On Sat, Feb 1, 2014 at 5:58 PM, Corey Richardson  wrote:
>
>> On Sat, Feb 1, 2014 at 5:55 PM, Benjamin Striegel
>>  wrote:
>> > First of all, why a new keyword? Reusing `for` here would be totally
>> > unambiguous. :P And also save us from creating the precedent of
>> multi-word
>> > keywords.
>> >
>>
>> I'd be equally happy with for instead of forall.
>>
>> > Secondly, currently Rust has a philosophy of use-follows-declaration
>> (i.e.
>> > the syntax for using something mirrors the syntax for declaring it).
>> This
>> > would eliminate that.
>> >
>>
>> Yes, and I don't have a solution for that.
>>
>
>
> ___
> 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


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Benjamin Striegel
> Yes, and I don't have a solution for that.

Well, it's not like we don't already stumble here a bit, what with
requiring ::<> instead of just <>. Not sure how much other people value the
consistency here.


On Sat, Feb 1, 2014 at 5:58 PM, Corey Richardson  wrote:

> On Sat, Feb 1, 2014 at 5:55 PM, Benjamin Striegel
>  wrote:
> > First of all, why a new keyword? Reusing `for` here would be totally
> > unambiguous. :P And also save us from creating the precedent of
> multi-word
> > keywords.
> >
>
> I'd be equally happy with for instead of forall.
>
> > Secondly, currently Rust has a philosophy of use-follows-declaration
> (i.e.
> > the syntax for using something mirrors the syntax for declaring it). This
> > would eliminate that.
> >
>
> Yes, and I don't have a solution for that.
>
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Scott Lawrence

On Sat, 1 Feb 2014, Corey Richardson wrote:


On Sat, Feb 1, 2014 at 5:53 PM, Scott Lawrence  wrote:

and so the syntax was quite obvious for beginners. The extra complexity of
forall kills this. Of course, one could write

forall struct Foo {

but that's just ugly.



Unrelated but struct declarations can't have bounds.


Bah of course. Just trying to point out that the bounds would only need to be 
used in the first parameter set.


I think it's a pretty good idea anyway, if the loss of concision is considered 
acceptable.



I don't have a
good way to re-unify the syntax declaration and use..



--
Scott Lawrence
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Corey Richardson
On Sat, Feb 1, 2014 at 5:55 PM, Benjamin Striegel
 wrote:
> First of all, why a new keyword? Reusing `for` here would be totally
> unambiguous. :P And also save us from creating the precedent of multi-word
> keywords.
>

I'd be equally happy with for instead of forall.

> Secondly, currently Rust has a philosophy of use-follows-declaration (i.e.
> the syntax for using something mirrors the syntax for declaring it). This
> would eliminate that.
>

Yes, and I don't have a solution for that.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Corey Richardson
On Sat, Feb 1, 2014 at 5:53 PM, Scott Lawrence  wrote:
> and so the syntax was quite obvious for beginners. The extra complexity of
> forall kills this. Of course, one could write
>
> forall struct Foo {
>
> but that's just ugly.
>

Unrelated but struct declarations can't have bounds. I don't have a
good way to re-unify the syntax declaration and use..
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Benjamin Striegel
First of all, why a new keyword? Reusing `for` here would be totally
unambiguous. :P And also save us from creating the precedent of multi-word
keywords.

Secondly, currently Rust has a philosophy of use-follows-declaration (i.e.
the syntax for using something mirrors the syntax for declaring it). This
would eliminate that.

Thirdly, I've actually been thinking about something like this for quite a
while. The reason is that our function signatures are LOOONG, and I've
always thought that it would be great to be able to declare the type
parameters above the function, in an attribute or something. But you could
just as easily split after your closing > for the same effect. If people
are fine with ditching use-follows-declaration, then this could be pretty
nice.


On Sat, Feb 1, 2014 at 5:39 PM, Corey Richardson  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 { ... }
> impl Trait for Foo { ... }
> fn foo(...) { ... }
> ```
>
> to:
>
> ```
> forall struct Foo { ... }
> forall impl Trait for Foo { ... }
> forall 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` (that is, type `Foo` instantiated with type
> `int`) is not the same type as `Foo` (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 { ... }
> impl Trait for Foo { ... }
> fn foo(...) { ... }
> ```
>
> to:
>
> ```
> forall struct Foo { ... }
> forall impl Trait for Foo { ... }
> forall 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


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Corey Richardson
On Sat, Feb 1, 2014 at 5:54 PM, Kevin Ballard  wrote:
> On Feb 1, 2014, at 2:39 PM, Corey Richardson  wrote:
>
>> 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.)
>
> Putting your other arguments aside, I am not convinced by the grep argument.
> With the syntax as it is today, I use `grep 'impl.*Clone'` if I want to find 
> Clone
> impls. Yes, it can match more than just Clone impls. But that's true too even 
> with this
> change. At the very least, any sort of multiline comment or string can 
> contain text that
> matches even the most rigorously specified grep. The only way to truly 
> guarantee you're
> only matching real impls is to actually parse the file with a real parser.
>

Sure. I find the monomorphization and formatting arguments to be more
compelling, personally, but I was initially motivated by a failed
grep.

grep can't find derived implementations, either.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Scott Lawrence

May as well throw my 2 cents in.

This is a pretty nice idea (I've always found 'impl' to be particularly 
confusing anyway). It does loose a nice property, though. Previously, there 
was a nice parallelism between


struct Foo

and

let foo: Foo

and so the syntax was quite obvious for beginners. The extra complexity of 
forall kills this. Of course, one could write


forall struct Foo {

but that's just ugly.

On Sat, 1 Feb 2014, Corey Richardson 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 { ... }
impl Trait for Foo { ... }
fn foo(...) { ... }
```

to:

```
forall struct Foo { ... }
forall impl Trait for Foo { ... }
forall 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` (that is, type `Foo` instantiated with type
`int`) is not the same type as `Foo` (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 { ... }
impl Trait for Foo { ... }
fn foo(...) { ... }
```

to:

```
forall struct Foo { ... }
forall impl Trait for Foo { ... }
forall 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



--
Scott Lawrence
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax

2014-02-01 Thread Kevin Ballard
On Feb 1, 2014, at 2:39 PM, Corey Richardson  wrote:

> 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.)

Putting your other arguments aside, I am not convinced by the grep argument.
With the syntax as it is today, I use `grep 'impl.*Clone'` if I want to find 
Clone
impls. Yes, it can match more than just Clone impls. But that's true too even 
with this
change. At the very least, any sort of multiline comment or string can contain 
text that
matches even the most rigorously specified grep. The only way to truly 
guarantee you're
only matching real impls is to actually parse the file with a real parser.

-Kevin
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev