Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upIntroduce `dyn` keyword #1603
Conversation
ticki
force-pushed the
ticki:dyn
branch
from
663bd75
to
0b8a1c7
May 1, 2016
ticki
force-pushed the
ticki:dyn
branch
from
0b8a1c7
to
dee35d9
May 1, 2016
This comment has been minimized.
This comment has been minimized.
KalitaAlexey
commented
May 1, 2016
|
@ticki Rendered link is invalid. |
This comment has been minimized.
This comment has been minimized.
|
Fixed. |
This comment has been minimized.
This comment has been minimized.
KalitaAlexey
commented
May 1, 2016
|
Is dyn keyword is reserved? |
This comment has been minimized.
This comment has been minimized.
|
No, it's not. It need to be context dependent. I added a new commit explaining that. |
This comment has been minimized.
This comment has been minimized.
KalitaAlexey
commented
May 1, 2016
|
Why can't we make warning about dyn will become reserved keyword in two release loops? |
This comment has been minimized.
This comment has been minimized.
|
Why should we? Adding it as context-dependent keyword won't cause breakage. |
This comment has been minimized.
This comment has been minimized.
KalitaAlexey
commented
May 1, 2016
|
@ticki Is it any harder to make it context-dependent? |
This comment has been minimized.
This comment has been minimized.
|
Yes, but it is inevitable. At least two RFCs introducing context dependent keywords have been accepted. Adding a third one won't increase the complexity. |
This comment has been minimized.
This comment has been minimized.
|
I’m theoretically in favour of this, but it seems kinda late to be doing this. I agree that the trait object syntax is too easy and implicit, and I’ve seen a fair few newcomers make the understandable mistake that trait objects are the way of writing functions that accept any value that implements a trait (rather than using generics, which is much more common), but this would cause an enormous amount of breakage (in Rust 2.0, when presumably the deprecation warning would be promoted to an error). |
This comment has been minimized.
This comment has been minimized.
Deprecation doesn't require breakage. |
This comment has been minimized.
This comment has been minimized.
|
I see way too many people doing e.g. I agree, that ideally this should have been done originally, but I don't think it is too late. I think that this is worth the turbulence, it will entail. |
This comment has been minimized.
This comment has been minimized.
|
Although, ideally it shall be made into an error after several release cycle, but this RFC has no such requirement. It is also worth noting that the "private in public" RFC caused severe breakage, but the ecosystem seemed to handle it well, by simply keeping it a warning in several release cycles. |
This comment has been minimized.
This comment has been minimized.
KalitaAlexey
commented
May 1, 2016
|
As I said, I want to be that error in several release cycle. |
This comment has been minimized.
This comment has been minimized.
|
I don't disagree with that, but as an initial point, this RFC suggest no such action. We can amend it later, if the consensus is positive to that. |
This comment has been minimized.
This comment has been minimized.
|
@kennytm @jonas-schievink, you -1'd this. Could you elaborate on why? I guess it is the stability issues? |
This comment has been minimized.
This comment has been minimized.
|
+ to @P1start |
This comment has been minimized.
This comment has been minimized.
|
Yes, I'm not in favor of adding another way to express the same thing we already can, with no chance of removing the "old" way (since it's used so heavily). Pre-1.0, sure. I don't think the idea of making the dynamic dispatch cost explicit is bad in itself, but I don't think the current way is too implicit (for example, when seeing traits as generic parameters you know there's dynamic dispatch involved - or are there exceptions to this?). |
This comment has been minimized.
This comment has been minimized.
|
I disagree. I see newcommers make the mistake all the time. There is a quite severe It is certainly not obvious that wrapping a trait in some pointer will allow values tos That a trait (which isn't even a type) can coerce into a trait object (an usized type) can |
This comment has been minimized.
This comment has been minimized.
|
@ticki Fair enough. It's been a while since I learned Rust, and now it seems obvious to me how it works, but you're right that it might be hard to learn at first. What's interesting, though, is that I've lately been actively avoiding generics in order to keep compile times low, so maybe using trait objects by default isn't too bad. Certainly, benchmarking is required before making this decision (which I admittedly didn't do, but I do think Breeze's <10 second compile time on core changes speaks for itself). |
This comment has been minimized.
This comment has been minimized.
Agreed. It is obvious to me as well, but I fairly often recieve PRs containing these kind of mistakes. The IRC contains lots of people asking about trait objects.
I find this rather strange. A system languages ought to focus on the runtime performance, more than the compile time performance. |
nrc
added
the
T-lang
label
May 2, 2016
This comment has been minimized.
This comment has been minimized.
peschkaj
commented
May 2, 2016
|
Wouldn't it be better/more appropriate to provide better material in the book and other tutorials to ensure that newcomers to Rust are aware of the cost of specific activities? For a new user, I don't know that a Further, wouldn't it also be more appropriate to add a lint to clippy and inform users what they're doing and why it's (potentially) a badness? |
This comment has been minimized.
This comment has been minimized.
Changing the syntax would be far more effective.
These simply looks like normal pointers, but they're not.
Such a clippy lint wouldn't make much sense. You want it to show up on every case of trait objects? |
This comment has been minimized.
This comment has been minimized.
You could lint functions that take a trait object when the implementation could be written generically. |
oli-obk
referenced this pull request
May 2, 2016
Closed
lint uses of dynamic dispatch where static dispatch would be possible #892
This comment has been minimized.
This comment has been minimized.
bluss
commented
May 2, 2016
|
This is how Rust is today: “Every object compatible trait It sounds so confusing. From the pedagogical point of view, I very much agree that naming those two differently is a big win! |
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
|
@ticki if the main argument against doing this is that it doesn't feel like a minor version bump, maybe it should just be proposed as a major version bump. Bumping the major version of the language doesn't mean that the compiler will break the world. Crates compiled in Rust 2.y mode will be able to use Rust 1.x crates, and the opposite can be probably achieved as well (at least until Rust 2.y gains a new feature that Rust 1.x doesn't have). One would just need to choose the Rust version to be used at the crate level and be done with it. |
This comment has been minimized.
This comment has been minimized.
stratact
commented
Sep 2, 2016
|
You know, thinking about it, the whole point of including this feature as a minor version bump, is to prepare Rust programmers for when Rust 2.0 eventually exists in the long run. As an example, that's why when you guys deprecate calls or items and introduce new stuff in the All @ticki is advocating for is to have it there, while not absolutely mandatory to use in Rust 1. With enough compiler warnings to help further drill the awareness of The problem I see here is and what concerns me the most, is that with enough breaking changes only isolated to be introduced for Rust 2.0 only, that it will create a community split and divide between two versions of the compiler. I don't want Rust to repeat the same mistakes that Python and D did. The reason to close this RFC based on the thought "it definitely doesn't feel to me like a minor version bump" seems like an unusual reason to decline this. |
This comment has been minimized.
This comment has been minimized.
golddranks
commented
Sep 2, 2016
|
The problem, or one of the problems, as I see it, is that |
This comment has been minimized.
This comment has been minimized.
J-F-Liu
commented
Feb 7, 2017
|
Use a keyword is not a good idea, I support the alternate |
This comment has been minimized.
This comment has been minimized.
|
@J-F-Liu I'm against |
This comment has been minimized.
This comment has been minimized.
J-F-Liu
commented
Feb 8, 2017
|
@ticki Yes, unless
Thus to allow trait name to appear in all type positions. Benefits are:
This is a great breaking change of Rust 1.x, hopefully can be adopted in Rust 2.0. |
This comment has been minimized.
This comment has been minimized.
I thought this issue was already closed. IIRC the consensus was that:
This particular issue can be solved mechanically, and for this reason it might encourage people to discuss a future Rust 2.x in which we can just break the world (and fix it mechanically). But this is not the only "imperfect language decision" in Rust 1.x, not all of them can be solved mechanically, and arguably we would like to solve most of them in Rust 2.x. So while it is interesting to consider how to break the language, it doesn't really move this discussion forward. Those wanting to move this feature forward should attempt to do so in a backwards compatible way. I think that the fundamentals issues that this RFC raises (that the dynamic costs of trait objects are "too implicit") can be mostly solved in a backwards compatible way by two small incremental backwards additions to the Rust 1.x language:
These can be pursued in 2 small RFCs or combined into one small RFC, and will result in:
Whether consensus can be gathered about this changes being worth it or not, that's a different issue. But for those RFCs to be successful they should probably stay as far away from Rust 2.0 as possible. |
This comment has been minimized.
This comment has been minimized.
We knew, but nobody listened |
This comment has been minimized.
This comment has been minimized.
|
@gnzlbg Thank god for semver. In 2.0.0, we can break all the shit we want to. |
This comment has been minimized.
This comment has been minimized.
|
My guess is that a significant portion of the |
This comment has been minimized.
This comment has been minimized.
|
@ticki |
This comment has been minimized.
This comment has been minimized.
|
My point in a nutshell was that there won't be a rust 2.0. I am not saying
it is not worth it to discuss about "what it could have been" but rather
that if we want to get things done we should focus more on "this is how
things actually are and how do we incrementally improve them" :/ it's
extremely unsatisfying to not be able to make it perfect, worse is better I
guess.
…On Sat, 11 Feb 2017 at 22:00, Vadim Petrochenkov ***@***.***> wrote:
@ticki <https://github.com/ticki>
No large scale breakage (like this one) will be possible regardless of
semver if Rust actually becomes a widely used language.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1603 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AA3NpgAoJKo4739FQYYh-UsQ1oZAhlf4ks5rbiF4gaJpZM4IUAR3>
.
|
This comment has been minimized.
This comment has been minimized.
golddranks
commented
Feb 12, 2017
|
I'd love to see the ideas from this RFC to go forward in a similar vein to the path RFC #1685 (comment) is now moving along. Yes, this is a bigger change, but I and many others think that the lack of syntactic difference between types and traits (in the context of trait objects) is a wart. It's possible to improve the situation without breaking compatibility by introducing a new more explicit syntax, utilizing rustfmt and the official documentation in the future to slowly change the the perceived "standard" and then in a long timescale, softly depreciate the old syntax with a lint. No need to break stuff. Basically I just restated what @gnzlbg said :D Just butted in to show my support. |
This comment has been minimized.
This comment has been minimized.
gurry
commented
Feb 16, 2017
|
One comment on the comparison with the Python 3 fiasco. By the time Python 3 came out, Python 2 was widely used in production. This is currently not true for Rust 1.x. In fact (assuming things go well), a vast majority of Rust's users are yet to come. Therefore, any fears of users shunning Rust 2.x should be tempered by this fact. |
This comment has been minimized.
This comment has been minimized.
|
@gurry Very few were using D when they switched standard library breaking backwards compatibility. 10 years later you can still see people asking around whether D is stable yet. |
This comment has been minimized.
This comment has been minimized.
gurry
commented
Feb 17, 2017
|
@gnzlbd Hmm. I didn't know about that. Thanks. So you imply that D's breaking change was early enough and yet they don't have much traction today. But are we sure the said breaking change is to blame? It's also possible D didn't catch on for other reasons. |
This comment has been minimized.
This comment has been minimized.
|
I still see people asking if Rust is stable enough for production use, or saying that they heard we "recently reworked our entire threading model" or some other thing from pre-1.0, so I'm not sure how much that sort of anecdata really applies. And there are definitely other reasons D didn't catch on. I'd also like to see this keyword introduced even though we probably can't ever get rid of the keyword-less option, but until Rust 2.0 is actually likely to happen I don't feel that strongly about it. |
This comment has been minimized.
This comment has been minimized.
|
@gurry A different way to put it is like this. Rust has many language features: memory safety, data-race freedom, generics, ... Notice that memory safety and data-race freedom are promises: we do not have a formal proof of this. Rust 1.0 added a new feature: "from now on, if your code compiles, it will compile with the latest compiler forever". This feature is also just a promise from everybody evolving Rust to everybody using it. It only works if those that use Rust trust those that evolve it. The moment you loose that trust, that feature is gone forever and it will never come back. Does this mean that we cannot ever break this promise? No. Imagine we find out that some other promise Rust makes does not hold, like for example, we discover that safe rust is not memory safe. That is also a promise our users rely on. If we need to break the language to fix it, we probably will. But that is a damn good reason to break the language, since otherwise our users cannot trust Rust anyways. We are trading one promise for another here, but our intention is to keep the promises we made. We would probably retain some of our users trust after doing something like this. Now think about breaking the language to fix a minor stylistic change (like this one). We can either have this breaking change, or we can keep our users trust on stability, but we cannot have both. Do you think it is worth it to sacrifice "stability" for this minor stylistic change? Most people think it is not worth it. Some people think it is. We are a diverse group of people, and not everybody can always get exactly what they want; we must compromise on consensus, that's just how big groups work. I actually would like something like this to eventually happen in some form, but I can empathize with the majority here, and even though I want this, I know that they are right: for the Rust language community as a whole, stability is a way more important feature to have than "more clear syntax" for feature X, in particular when even though the syntax is not the clearest that one could have, it is still clear enough in practice. |
This comment has been minimized.
This comment has been minimized.
gurry
commented
Feb 17, 2017
•
|
@gnzlbg I fully appreciate what you say and do not take lightly the costs associated. I'm just trying to understand how high those costs truly are, especially at the present point of time.
I feel it's not a minor change. It itself and all the changes it enables further down make the language a lot easier to use and teach. Generics are everywhere in Rust. So anything that simplifies them has a major impact on the whole language. The number one complaint about Rust today is it's hard to learn. Therefore, anything that addresses that has somewhat of a disproportionate importance at this particular juncture in time IMHO. |
This comment has been minimized.
This comment has been minimized.
golddranks
commented
Feb 21, 2017
•
|
Another vague idea for soft-deprecating "plain" trait object syntax gracefully: Have At some point, Especially now with the discussion about having unsized rvalues and passing unsized values to functions, a new syntax would be important to have, as pointed out in #1909 (comment) |
aturon
referenced this pull request
Apr 13, 2017
Open
Language ergonomic/learnability improvements #17
Ixrec
referenced this pull request
Aug 16, 2017
Merged
`dyn Trait` Syntax for Trait Objects: Take 2 #2113
This comment has been minimized.
This comment has been minimized.
vi
commented
Oct 18, 2017
|
Shall |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
vi
commented
Oct 18, 2017
|
Anyway such label would be here even more on-topic compared to |
This comment has been minimized.
This comment has been minimized.
vi
commented
Oct 18, 2017
|
Maybe someone should edit "#2113" into the opening comment, so one can find the "take two" RFC more easily? (Google search of "rust dyn keyword" ends up here) |
This comment has been minimized.
This comment has been minimized.
|
@vi Done. |
ticki commentedMay 1, 2016
•
edited by cramertj
Introduce a keyword,
dyn, for denoting dynamic dispatch, with the motivationof avoid "accidental overhead" and making the costs more explicit, along with
deprecation of the old syntax.
Rendered.
@cramertj Edit: A variation on this RFC was merged in #2113.