That is, I am not aware of any specific goals or milestones that where targeted.
I think you meant to use "were" instead of "where"
The blocker here is design work. There was a Pre-RFC about inline asm a while back, but there was still some discussion to be had and somebody needs to champion and implement the ideas.
Given the huge number of bugs inline ASM has and the difficulty of calling such a thing stable, I think it would be a huge project to stabilize inline assembly. I think that isn't compatible with another year of maturity.
The blocker is not just design work, but also agreement that we should have inline assembly on stable at all. For example, here are some notable objections to it:
- In particular, I wouldn't want inline assembly on stable without having it implemented in Cranelift and the text above suggests that is not reasonable.
With these in mind I would actually prefer to remove
asm!from nightly but I suspect that won't happen either.
Also, why is inline assembly a blocker for kernel development? Can't you link in assembly blobs?
Another approach would be Cargo-side improvements, e.g.
asm_dir = "foo" and
asm = "cc" in
Cargo.toml which would result in taking the files in
foo, feeding them to
cc, and linking in the object files (credit due to @oli-obk for the idea).
Technical Debt and Measurable Progress
@mark-i-m Remember how I was arguing that maturity / sustainability isn't necessary? I take it all back. Despite having had a "year of maturity", there's still loads of things to finish. I do think we should continue next year with "Implement all the things; Be extremely conservative with accepting new RFCs if we don't have people lined up to implement and review them and if we don't think they are readily implementable."
It seems clear that a lot of good work was done by a lot of people.
Here's some more:
We should pick a few milestones and put active focus on achieving them. This applies even to technical debt work: we should explicitly choose certain technical debt items, make a big list, and actively work through it in a measurable way.
I think we can reasonably maintain a list of high level goals, but I think we should also avoid micro-management. At the end of the day, Rust is an open source project, not a company. I wouldn't want to feel like an employee.
Making a new edition just because it has been 3 years doesn't make sense to me. Indeed, I think we should make a new edition only when needed to reduce churn and overhead on the users.
I agree with this punchline.
We could collect things we want to change, perhaps even eagerly gate them under a new
edition_next feature gate and then one day, when we think there's enough things in there we can RFC a proposal to stabilize set editions and its contents.
I'm not terribly enthusiastic about the idea of
edition_next, since it reflects a perpetually moving target which gives no information regarding the actual edition of the compiler once it comes time to stabilize the next edition.
Perhaps something like
edition = "2018+" would contain all the stuff stabilized after the 2018 edition, up to the next editions release, and after the next edition is released the
2018+ edition can be deprecated in favor of whatever the next edition becomes.
That at least to me would seem more palatable than a blanket
edition_next devoid of any context.
Is that just a question of renaming? If so I'm fine with whatever name.
Yep, just a question of renaming to avoid ambiguity after the
next_edition is released and there is a new
This "2018+" syntax seems more prudent to me than the "c++0x"-style syntax that most C++ compilers adopt when they try to address a closely related problem.
After all, edition release years are just arbitrary deadlines that can be pushed back indefinitely (like C++11 was), whereas the year where the previous edition was released is a known fact.
Technical Debt and Measurable Progress
I'm not sure because of the wording (or perhaps my not necessarily great reading comprehension abilities ), but does this mean that you are not counting the reduction of technical debt towards measurable progress? I think it's an enormously important and very real kind of progress. (If that's not what you meant, sorry for bringing it up!)
I also think that in the current state of all things, the ideal amount of new features vs getting rid of tech debt (and properly finishing off things we began) is
epsilon to 1 – epsilon.
Perhaps "(externally) observable progress" would be a better wording? Part of the reason why technical debt reduction is often insufficiently prioritized is that it has little user-visible effects, as the effects of technical debt are usually only observed indirectly by users via crashes, limitations, slowness, etc. that are hard to attribute back to this cause.
This suggests that there are enough places where either the language is underspecified, or the compiler is lax enough that non-deterministic compiles are possible. More than anything else, I'd like to see Rust be fully specified and unambiguous. This would allow formal methods to be applied to a program, and it would allow others to develop their own compilers for rust.
It is the former. For incremental compilation, almost everything is deterministic.
No, I agree with you that it is important and is progress. I don't agree that it is measurable. That is, if one asks "how much progress have we made towards the 2019 roadmap goals?", there is no well-defined answer. Suppose we accomplished some set S of tech debt items. Is that success or not? Nobody can answer because there was no predefined set of concrete items that would be the measure of success.
I'm not opposed to paying down more debt. I think that might even be the right thing to do. But I think we should set milestones and actively work towards them. For example, for technical debt, we could use a lot of different measures (not sure which ones are good ideas though):
- Accomplish major refactoring X, where X is a specific change
- Unblock or finish major RFC or desired feature X, where X is a specific feature or rfc
- Resolve N github issues
- Resolve all github issues older than 2016
- Have a design in place for feature X, where X is a specific thing that needs design
- Resolve N% of the FIXMEs in the compiler
I would also argue that the list of goals should be conservative, something we can actually do.
Your points about inline asm are fair. I agree that it would take concerted effort, though I'm not sure how much of a blocker the cranelift backend should be. It seems like we could just emit an error if you try to use inline asm with cranelift, and it's not clear to me how common this usecase is.
Yes, but it costs a lot: all of a sudden you need a c compiler or assembler, you need to figure out the right linker magic to get your assembly in the right places, and you probably need a build system around xargo/xbuild, which is itself already a wrapper around cargo.
Also, maybe I am just warped by C/C++ but I can't imagine a self-respecting systems language that doesn't easily support low-level programming.
Since the post specifically mentions I still want all of the things that I wanted last year, just wanted to second this from your 2019 wishlist:
I would like to see a short
impl periodtime set aside where no RFCs are merged and the focus is on visiting every accepted-but-not-stable RFC and evaluating it. For each one, either it should be stabilized or work items should be identified. If the feature is just not getting usage, it should be un-RFC-ed.
Rust, as a systems language, has quite a footprint already and without some sort of pause and reflection — may be even a policy — on the amount of RFCs accepted, the cognitive overhead caused by the bloat may lead to the language tripping on it's own feet.
I was actually just looking at C++20. The pace of change in the language is so fast that people who know C++11 like me are quickly finding their knowledge obsolete. Even though I like the direction the language is going as a whole (more static checks, more helpful compiler), I am unmotivated to learn a new C++20 every few years.
I don't want rust to be like that.
As a counter-anecdote, almost every major change in C++20 is something I've wanted for a long time, and I'm eagerly waiting for them to actually be implemented. (Especially since a lot of them boil down to "this thing that was an error before is no longer an error", e.g. allowing more things in constexpr context.) I'm also looking forward to bigger features which might be in the next standard, such as reflection and metaclasses.
On the other hand, I think C++ in general is an excellent example of how not to design features – they tend to be rather non-orthogonal, making them confusing and overcomplicated, yet ironically limited in power.
In many cases, the language keeps adding newer better ways to perform the same task, while the old ways stick around for backwards compatibility's sake, leading to layers and layers of redundant functionality. I don't blame the backwards compatibility, which is a great service to developers. And with how old C++ is, to some extent it's inevitable that some features would turn out badly in practice. But not quite as many as C++ has ended up with...
The lesson to learn: measure twice, cut once. Make features as simple as possible, but also as complete and powerful as possible, so that they do what people need. Pick the right design, not the design that's easiest to implement in the short term. And in Rust's case, stop rushing half-baked things to stable just because 'nobody will test them otherwise'!