Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Change DST syntax to T: Sized? #490

Merged
merged 3 commits into from
Dec 6, 2014
Merged

Conversation

ftxqxd
Copy link
Contributor

@ftxqxd ftxqxd commented Nov 29, 2014

Change the syntax for dynamically sized type parameters from Sized? T to T: Sized?, and change the syntax for traits for dynamically sized types to trait Foo: Sized?. Extend this new syntax to work with where clauses.

cc #357

Rendered view

@arcto
Copy link

arcto commented Nov 29, 2014

+1. Looks coherent.

So with this syntax one could also use these specifications?
T: !Sized Exclusively unsized T.
T: Sized Exclusively sized T.

What about Sized? vs. ?Sized.

@japaric
Copy link
Member

japaric commented Nov 29, 2014

@arcto You can already type T: Sized (Sized is just a normal trait) but that's an implicit bound for any type T that's not marked as Sized? T.

When we get negative bounds you should be able to type T: !Sized (and that will be possible even without this RFC).

@nrc
Copy link
Member

nrc commented Nov 29, 2014

I'm weakly in favour of this - I originally liked the Sized? Foo syntax, but now I agree it looks a little inconsistent.

I would be wary of having Foo? for an un-bound and !Foo for a negative bound because that is again inconsistent. So it should probably be ?Foo, and I think that makes un-bounds easier to distinguish from normal bounds in any case.

Another worry is that this is churn for not very much benefit. It should be easy to implement, but there will be a lot of fallout.

@liigo
Copy link
Contributor

liigo commented Nov 30, 2014

Nice! ?T and !T
2014年11月30日 上午4:37于 "Nick Cameron" notifications@github.com写道:

I'm weakly in favour of this - I originally liked the Sized? Foo syntax,
but now I agree it looks a little inconsistent.

I would be wary of having Foo? for an un-bound and !Foo for a negative
bound because that is again inconsistent. So it should probably be ?Foo,
and I think that makes un-bounds easier to distinguish from normal bounds
in any case.

Another worry is that this is churn for not very much benefit. It should
be easy to implement, but there will be a lot of fallout.


Reply to this email directly or view it on GitHub
#490 (comment).

@ftxqxd
Copy link
Contributor Author

ftxqxd commented Nov 30, 2014

So it should probably be ?Foo, and I think that makes un-bounds easier to distinguish from normal bounds in any case.

I like that idea in general and I did consider it when making the RFC, but it simply looks a bit weird: in English, ‘?’s come after things, not before. (The same argument could be applied to !, and yet somehow that looks OK; I guess I’m just used to it.) However, Sized? really is quite inconsistent: not only does it differ from !Sized, but it also is the only postfix ‘operator’ in the entire Rust language (that I can think of). With a prefix ?, there is indeed a nice symmetry with negative bounds, as @arcto noted.

If enough people like the ?Sized syntax then I’ll probably adjust the RFC to propose that instead. I’ll add it as an alternative for now.

Another worry is that this is churn for not very much benefit. It should be easy to implement, but there will be a lot of fallout.

I don’t think DST is used too much yet outside the standard library, so I don’t think this will turn out to be a hugely problematic change. We could allow the old syntax with a warning for some time, anyway.

@nrc nrc self-assigned this Nov 30, 2014
@nrc
Copy link
Member

nrc commented Nov 30, 2014

(assigning myself to shepherd this - we should discuss it pretty soon, I don't think we need to wait for a triage meeting to assign a shepherd)

@jfager
Copy link

jfager commented Nov 30, 2014

Just to throw it out there, T: MaybeSized instead of the random-seeming ?? Unless there are big plans to start using ? for a bunch of other things...

@pkondzior
Copy link

Is there any reason why we would not name negative bounds with exclamation mark on the end ? ie Sized! ?

@ftxqxd
Copy link
Contributor Author

ftxqxd commented Nov 30, 2014

Just to throw it out there, T: MaybeSized instead of the random-seeming ?? Unless there are big plans to start using ? for a bunch of other things...

MaybeSized looks exactly like a normal bound in that context, but would actually do the opposite of a normal bound, extending the number of things that the T can represent instead of limiting it. It also wouldn’t make sense to be a normal trait, and so a whole bunch of problems would arise from that. I’ve seen a few ideas about other default trait bounds, so having a generalised ? symbol is useful.

Is there any reason why we would not name negative bounds with exclamation mark on the end ? ie Sized! ?

The imaginary (for now) !Trait syntax comes from using ! as a boolean ‘not’ operator, which you can do in Rust expressions today ((!true) == false), and is very common in other languages for the same purpose. Moving the ! afterwards would remove this similarity, thus removing the primary hint to what it does. Also, Sized! looks like a macro invocation, and ideally we’d allow macros in trait bound position, too, so ideally it would be parsed as such, too.

@gifnksm
Copy link

gifnksm commented Nov 30, 2014

How about - operator?
In the DST syntax, T: Foo means T is implements Sized + Foo implicitly.
So, T: Foo - Sized means T implements Sized + Foo - Sized = Foo.
T: -Sized means T is unsized.

@arcto
Copy link

arcto commented Nov 30, 2014

@gifnksm: Using a minus sign to negate an implicit bound goes well with using a plus sign to add a bound, but how would one specify the case of "possibly unsized"?

@gifnksm
Copy link

gifnksm commented Nov 30, 2014

@arcto I wrote "T: -Sized means T is unsized", but this is not correct.
The following holds in my proposal (with negative bound).

  • T or T: Sized -> T is sized.
  • T: -Sized -> T is sized or unsized.
  • T: !Sized -> T is unsized.

@tomjakubowski
Copy link
Contributor

I don't see a problem with Sized? and !Sized being inconsistent. !x is the long-standing prefix notation in programming for logical negation and is read as "not x"; prefix ? reads somewhat strangely to me as a reader of English, at least compared to x? where its meaning is a little clearer.

I do like -Trait to mean unbounding a default bound.

@ftxqxd
Copy link
Contributor Author

ftxqxd commented Dec 1, 2014

I’m not a huge fan of -Sized for removing default bounds. Given that + adds a positive bound, it makes sense for - to add a negative one (the - symbol indicates negative numbers, so it makes sense to represent a negative bound as well). I’d expect something like T: Foo + -Bar to mean T: Foo + !Bar (i.e., T must implement Foo but explicitly must not implement Bar). Sure, when it’s a default bound it makes some sense for it to remove a default bound (because the bound is already there, and the - removes it). However, I would expect -Foo where Foo is not a default bound to act as a negative bound, and that is inconsistent with the behaviour for default bounds.

Regarding Sized? v.s. ?Sized, I agree that ?Sized looks rather strange. However, Sized? is inconsistent with the entire language in that ? would be the only suffix operator. The real question is which of aesthetics and consistency we value more in this particular case.

@Ericson2314
Copy link
Contributor

I like c best -- consistency over familiarity at first glance. Either T: ?Sized or T: Sized? would certainly be an improvement.

@reem
Copy link

reem commented Dec 2, 2014

Moving to T: Sized? also generalizes to future possible improvements, like T: Drop? for implementing linear types.

@nrc
Copy link
Member

nrc commented Dec 2, 2014

All schemes generalise, the current scheme would be Drop? T and Drop + Sized? T. One reason I mildly prefer the scheme proposed in the RFC is because I think T: ?Drop + ?Sized or T: Drop? + Sized? is clearer because the ? is on every bound.

@UtherII
Copy link

UtherII commented Dec 2, 2014

I support the T: ?Sized syntax too.

@tikue
Copy link
Contributor

tikue commented Dec 3, 2014

The gain in consistency across the board wins me over. I prefer changing to ? to a prefix operator, as well, also for the consistency gain.

@canndrew
Copy link
Contributor

canndrew commented Dec 4, 2014

Can't we just get rid of this freaky Sized? syntax altogether and make all trait bounds positive? I don't, for example, have to write T: Reader? to say that T may or may not be a Reader.

If I want to define a trait for types that must be Sized I can write:

trait Foo: Sized { ... }

If I want to define a trait for types that may or may not be Sized I should just be able to write:

trait Foo { ... }

The obvious downside to this is that it will require a lot of extra typing to add + Sized to most trait bounds. But this could be fixed in a backwards-compatible way later by adding a form of trait inference. The compiler could tell that T is implictly Sized if, for example, it's used on a local variable. And if the user tries to use str for T the compiler could point them to the exact piece of code that caused it to infer T: Sized. You could then use a similar scheme to infer Copy, Send and maybe some other kinds aswell.

Even without trait inference, the upside to this is that it would keep the trait system sane and consistent.

Is there something wrong with this plan that I'm not seeing?

@arcto
Copy link

arcto commented Dec 4, 2014

Only the last member of a struct may be unsized, at the moment, I believe. Without the Sized?/?Sized syntax any generic member may seem to implicitly allow unsized types.

@Ericson2314
Copy link
Contributor

@canndrew I would prefer making all traits op in too, but I'm not sure your inference system is a good idea.

The precedent in most languages is to just infer types where there is no annotation. I.e. all annotated bindings have exactly the type the user specified. Where you can infer part of the type, one explicitly shows what should be filled in with e.g. an underscore (Agda, Rust), or the "diamond operator" (Java).

The only time rust violates this principle is inferring lifetimes, I am not sure even sure that is a good idea. (Consider a : &_ T as an alternative syntax.) The argument in it's favor is that the choice of lifetime hardly effects the semantics of the program (only exception I can think of is controlling when drops are run), whereas the inferred trait definitely would.

Also, opinions aside, I am not sure it is possible. Consider that multiple traits with the same method names can be in scope at the same time.

Considering these things, I think &trait is the least evil. Hopefully one could eventually specify which traits they want to be opt-in by default. Besides the theoretical feel-good of making Sized less special, this might be of practical use once we have GC: see @glaebhoerl's comments in #415

@nrc
Copy link
Member

nrc commented Dec 6, 2014

We (the Rust team) discussed this RFC today. We are generally in favour of the changes, we would like to take an adjusted RFC where the question mark comes before Sized for consistency with future negative bounds (i.e., T: ?Sized) and without the change to for clauses in traits, i.e., trait T for ?Sized (note that the question mark is before Sized for consistency with where clauses, but we use for rather than :).

The reason for keeping for is that : for super traits causes super traits to be inherited, e.g.,

trait A {}
trait B: A {}
trait C: B {}

here, C has bounds B + A + Sized. However the optionality of Sized is not inherited, e.g.,

trait B for ?Sized {}
trait C: B {}

here, C has bounds B + Sized - it has the Sized bound even though B does not.

@P1start, if you are willing, could you make these changes to the RFC please? Then ping me and I will merge it. If you don't have time, let me know and I can take care of the changes too. Thanks!

This adjusts the proposal to propose `T: ?Sized` instead of `T: Sized?`, and
changes the syntax for traits to `trait Trait for ?Sized` instead of `trait
Trait: Sized?`.
@ftxqxd
Copy link
Contributor Author

ftxqxd commented Dec 6, 2014

@nick29581 OK, I’ve updated the RFC with those changes.

@nrc nrc merged commit 2e74f61 into rust-lang:master Dec 6, 2014
@nrc
Copy link
Member

nrc commented Dec 6, 2014

Tracking issue: rust-lang/rust#19607

@Centril Centril added A-syntax Syntax related proposals & ideas A-traits Trait system related proposals & ideas A-typesystem Type system related proposals & ideas A-dst Proposals re. DSTs labels Nov 23, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-dst Proposals re. DSTs A-syntax Syntax related proposals & ideas A-traits Trait system related proposals & ideas A-typesystem Type system related proposals & ideas
Projects
None yet
Development

Successfully merging this pull request may close these issues.