Rust seems to change constantly, because it's changing so slowly. The 1.0 release has held back a lot of stuff to avoid stabilizing wrong things, and it's now slowly backfilling the missing features bit by bit.
Instead of starting with a fat standard library, it started with minimal one and now each release adds 2-3 functions that could have been there in 2015. But none of it is idiom-changing revolution. These are mostly convenience functions, and you don't have to use them all just because they're there.
Every addition to the language is bikeshedded to death, goes through betas, revisions, refinements, before being stabilized years later. The first experimental release of async was 4 years ago and it has landed last November. So you may hear about new features a lot and they churn in nightlies, but actual big changes reach stable rarely.
Apart from async/await, since 2015 Rust made only 2 changes to how idiomatic code looks like (? for errors, and 2018 modules), and both of them can be applied to code automatically. I maintain over 60 Rust crates, some of them as old as Rust itself. All work fine as they are, and running `cargo fix` once was enough to keep them looking idiomatic.
> it's now slowly backfilling the missing features bit by bit
This isn't slow.
Java went three years, from December 1998 to February 2002, without any language changes. And to be honest, even that wasn't that slow!
> Every addition to the language is bikeshedded to death
Not to death, because many of them don't die!
What i find annoying about Rust's changes is that some of them are so trivial - they change the language for such small improvements. async/await is not in that category, for sure. But Ok-wrapping actually is. The need to Ok-wrap results is a minor annoyance at most. Ditto a bunch of the problems solved by match ergonomics changes.
I think the root of the problem is that the changes are driven by a small core of Rust programmers - many working on Rust itself or some of its flagship projects - who are actively involved in the discussions around Rust. They tend to view change as natural, and the cost of change as low. I believe there is a larger group of Rust programmers who are not actively involved in these discussions, and are maybe not spending 100% of their time on Rust, for who the cost is higher. But we don't hear as much from them.
I _really_ felt that in JavaScript, especially es2015. So many updates came out at once, that people didn't realize many of the benefits they received from new features were now much less important because of other features that were included around the same time.
There was a huge rush to use classes, which was sugar around the prototype system, but happened when we also got spread operators, Object.assign, and property name shorthand. We could already easily express the concept of a class far more easily than we were doing before, but because it all came out at the same time it didn't really click for the community at large and a lot of what became idiomatic didn't really feel important enough for a language update.
Ditto with generators and async functions, which while merely a very specific application of a generator is far better known. Again, not sure we needed all this extra syntax so you can say `async function foo() { await bar()`, when `co(function* foo() { yield bar()` was already available (if co were simply added to the Promise object). We're also now tying the language to a very specific implementation, when the co approach is explicit about saying what's responsible for taking control from the yielded function (a Promise).
I spent today updating some production Rust code from 2016. This was a partly automated process thanks to 'cargo fix'.
Some thoughts:
1. Most of the superficial changes, like 'dyn' and Rust 2018, are easily handled using automatic tools.
2. The original Rust 'Error' trait was clunky, and it lacked useful features like backtrace support. This led to a series of experiments and fads in error handling (e.g., error-chain, failure), which are only starting to calm down after recent enhancements to 'Error'. More conservative Rust users avoided this by sticking with 'Error' and living with the limitations.
3. Updating depencies has been surprisingly easy, with several notable exceptions. Very early adopters of 'tokio' 0.1 had a fair bit of work to do once 'async' stabilized. And OpenSSL has been a constant thorn in my side, despite being a native C dependency.
One handy tip: Don't force yourself to constantly update your code to use all the latest features. Not everything needs to be async. And it's OK to have some rarely-touched modules that are written like it's 2015.
> And OpenSSL has been a constant thorn in my side, despite being a native C dependency
If it's acceptable for your use case, it might be worth taking a look at rustls. I'm not sure how far along it was back in 2016, but it's in a pretty good state right now. I consider it much easier to deal with than OpenSSL, and the fact that a lot of legacy crypto that I have no need for isn't even supported in the library is appealing at least to me.
As someone newer to Rust who has been using error-chain because it was what I found at the time I'd be curious to hear what your preferred solution to errors in modern rust is.
I feel like error handling in Node hit a nadir in 10.0 due to async function stack traces being so truncated. I started in the industry when Java was young and while I appreciated stack traces plenty, I hardly ever had to deal again without them, and you really do come to depend quite a lot on this behavior.
Officially we are upgrading to 12 for perf, but I was the first (and will probably be the primary) contributor to that work because I want everyone to have decent stack traces again. Our code has too many layers of abstraction, and working without full traces is adding insult to injury.
I feel that the changes to date haven't been that significant. Adding `dyn` was almost completely automated, removing the need for `extern crate` was welcome and very easy to apply, likewise `try!()` to `?`. The changes to futures were a bit of a pain but futures were always known to be in flux. `impl Trait` is useful but failing to use it where you could is not ugly enough to irritate.
There are some upcoming improvements --- that I'd like to see! --- that are bigger and thus may be more challenging:
-- Better `const fn` will make many existing `lazy_static`s become unidiomatic. Worth it, but annoying.
-- Const generics will make a lot of existing code non-idiomatic. Again, well worth it, but annoying.
-- Generic Associated Types ... probably similar.
The question is, if people decided those important features don't belong in Rust because they would cause too much churn in code that wants to be idiomatic ... then what? That would almost guarantee a new language --- perhaps a fork of Rust, perhaps not --- would eventually fill that niche. Wouldn't everyone be better off if that language was Rust itself, and people who don't want to write that "modern code" ... don't?
This a key difference between the Go community and the Rust community. Go is like C 2.0: it tries to be minimal and stable. Go usually ships with no language changes between releases. Rust is like C++ 2.0: it is constantly being revised and expanded, supposedly to improve power, performance, and ergonomics. When a new version of Rust is released, the core Rust devs write a blog post gleefully explaining all the new "features" the current version has. What these devs perhaps fail to appreciate is that not having new features can itself be a feature.
I'm a Go fan and I've used it tons; I'm Rust-curious, but I've only made toy programs w/ it. While there is a germ of truth to this -- C++ and Rust are both complex -- I think it carries w/ it a lot of connotations which are untrue.
To wit, C++ is a brutal, terribly designed mess that's absolute torture to work with.
Rust is extremely well-designed and a pleasure to work with.
We hear this narrative really often even though it's not accurate: Go has its share of outrage about one change (in error handling too amusingly) last year and the proposal (the try keyword) even had to be repealed because it was considered too revolutionary.
Go modules are a huge change in how Go dependency management works and it's comparable, or even bigger in scope, to the Rust changes in 2018 edition regarding modules. And in a near future, Go's generics (contracts) are going to be a dramatic change, in a scale Rust arguably hasn't faced yet since 1.0, even though there is some similarities with the impl Trait features.
In fact, Go and Rust are both evolving fast compared to C (and maybe even to C++) and interestingly enough, most of the time the evolution comes in similar domains (error handling, modules, generics).
The big difference is the release schedule: Rust release small changes often while Go release big changes rarely. The 6-weeks schedule has advantages (each version is quite small so it's easier to test and bugs are found earlier) but it adds a feeling of churn which can be harmful.
Rust has only become more uniform and contains less special cases than just a couple of years ago.
The rate of adding features is quite slow, as demonstrated elsewhere in this thread. Important features spend a long time baking, and a long time in testing before they are piecewise stabilized.
> When a new version of Rust is released, the core Rust devs write a blog post gleefully explaining all the new "features" the current version has.
Of course when someone talks about a CHANGELOG, they'll talk (rather happily) about the things that have changed/improved.
IMO Go is more like C people took a stab at making a Java. I really like go, and it’s ethos, even if I haven’t used it much in production. Go is not however a replacement for C in the way C++ and Rust can be. Of course Rust and C++ aren't a replacement for C in some key ways, so maybe I don't have a point here?
Stability is THE most important feature. Rust needs to mature a little more and then mostly just stop. I seriously hope that it doesnt follow the C++ path.
Interesting. I witnessed a constructive collaboration by which the Rust community chose (mainly) the syntax for it's async features. I thought of it as amazing, thoughtful, rather democratic and on point. Nothing war-like to me.
To be honest, reading mainly blog posts, RFCs and summarisation comments, it did look like a thoughtful and organised process. However, there has been a constant problem of tiresome work and "intellectual and emotional labour" of reading thousands pieces of feedback, some of which are emotionally charged, and many of which are duplicates or re-statements of similar ideas, and many of which have misunderstanding or mis-valuations of other ideas. I've heard that collecting and editing this huge amount of unstructured feedback into comprehensive and balanced summaries has been a huge drain of mental energy for the participants.
I tried to contribute to the discussion and actually didn't find it to be super productive. We had thousands of comments just around syntax - from people who had never been involved in any async/await design or usage before. It was super hard for everyone involved to just keep up with the comments.
And while the syntax discussion saw a ton of comments, the more important underlying semantic aspects of async/await got a lot less attention - even though they also had and still have a few issues to resolve (e.g. around cancellation, thread safety, extensibility).
That's not really what happened : the core team decided they'd use ".await" instead of a regular prefix await (with good rational) and any people where pretty uneasy about that to say the least: most people considered that ultra ugly and confusing for new rust users (and I'm still in that camps even though I'm glad the discussion is finally over).
> I need to now change my code in order to keep it idiomatic
I'm not a Rust person so maybe I'm missing something, but why does the OP need to keep the code idiomatic? Can't the changing fashions in what's idiomatic be ignored?
> Can't the changing fashions in what's idiomatic be ignored?
They absolutely can, but you might be stuck on an older "edition" of Rust. I've stuck with `try!()` for error-handling, because I think error-handling deserves more prominence than a single character. But that means my code is stuck on Rust 2015. If something I need is added to Rust 2018 or a later edition, I'll be forced to update or backport.
If you don't update over time there's a danger that you won't be able to interoperate with other software, or you might not be able to take advantage of new features. It's easier to make small changes over time then trying to do a big bang upgrade with several years of changes.
I'm getting seriously concerned about feature-creep in Rust. I understand that there was an initial period of rapid growth as the community figured out what was needed, and that some of Rust's syntax sugar makes a very real difference in productivity.
But Rust is already not a simple language. It already has long compile times, and some of its syntax sugar already makes it harder to understand what's really going on when you invoke it. I think it's important that the Rust community start reeling in frivolous sugar, otherwise it may just become C++ all over again.
Not really going to address the rest of the post but I wanted to point out that `impl Trait` hasn't really changed what's idiomatic. People still use generics in argument position, and while I've seen a couple instances of people using impl Trait in argument position it's not enough to call it an idiom shift.
impl Trait in return position has changed how people code; but that's because it made certain things suddenly possible, which isn't an idiom change as much as obsoleting some old bad workarounds.
I'm curious to know why you felt like you had to change your code to be more idiomatic with impl Trait.
----
Nor does it seem like Ok wrapping is the kind of feature that would change what idiomatic Rust is.
,,The .await war was the final straw to make me stop watching the Rust community beyond what comes in the release notes.''
Regards the error checking syntax the article may be right, but as far as I saw, the await addition to Rust went perfect: it became stable when the decision was made (also a state of the art memory model was created for async calls), and nobody had to use it (or even follow it) before that.
Not sure I agree there. The language progresses with features that OP himself says he likes, and he also says that they DO maintain backwards compatibility, what more to ask for?
The author would be better or revisiting their code on a more relaxed cycle, for example every 18 weeks. Or whatever works for them, or just let go of the need to be using 100% of the latest best practices.
One of the main features I look for in a language is stability. I just don't want it to change that much other than adding functionality to the standard library.
I know that's not the fashion currently, but it's probably one of the most valuable things to me.
Have you used Rust? Rust has made a strong guarantee to always be backward compatible.
We don’t want dead languages, look at Java. It was stagnant for a long time, but has now shifted to a better delivery methodology of new language features. Rust is the same and continues to improve. Continues to make things easier and better to use without giving up its speed and low overhead goals.
I program to solve problems. Changes in a language or worse, "how it is done" mean that I must keep up with something else in addition to solving the problems before me. Waves of increasing syntactic sugar in a language begin to look like layers of frippery and frosting, and I can only remember that "fashion is a form of ugliness so intolerable that we have to alter it every six months." I do not want to look at some bits of upper-row "executable line noise" that is somehow called syntactic sugar and try to have to mentally project what surface lies under that frosting.
What I want is to be able to look at ten year old code and it immediately be working and understandable. I don't want it to be out to style or "uncool" or to even have to think about these things.
By all means, fix bugs. Add libraries as new formats, protocols, and technologies emerge. Huge mistakes can be corrected in rare major version updates, which may have to count as actual forks in the language. When I first looked at Python, somewhere around 2004 or 2005 if I had to guess, I remember seeing that whole floor division bit and thinking, "Yeah, they're going to have to change that eventually and digging in their heels on that one was foolish." That's a rare exception, and it counts in the "why did this make it to 2.x?" category.
I feel a bit lonely in this, but I just cannot seem to embrace the churn.
I've been meaning to write a blog post on this topic. Maybe I'll do it tomorrow. But, I've been thinking about this question too, or at least a related one: how many new features does Rust get, and how often does it get them? I'd like to bring some data to this discussion.
In 2019, we had eight releases: 1.32 to 1.40.
- 1.32: one language adjustment, finishing off previous module work
- 1.33: const fn can do a few more things
- 1.34: you can do a bit more with procedural macros
- 1.35: a few minor details around closures
- 1.36: NLL comes to Rust 2015. Not really a new feature so much as backporting it to an older edition.
- 1.37: you can #[repr(align(N))] on enums
- 1.38: no real language changes
- 1.39: async fn! some adjustments to match. Some more borrow checker adjustments.
- 1.40: #[non_exhaustive]. The 1.39 borrow checker adjustments are ported to an older edition. Macros can go in a few more places.
Really, 1.39 was a huge release, and other than that... all language changes were very minor, mostly sanding off some edge cases, making some things more orthogonal, stuff like that.
Most releases these days add some standard library APIs, maybe we have some toolchain improvements... but for all of 2019, we had one feature I'd call truly major.
I suspect that things were a lot more hectic previously, but the language has slowed way, way down recently. We have had two releases so far this year, and I would argue that the only real language feature was an expansion around match patterns. Which again, isn't so much a new feature as it is adding a little bit to an old one.
Churn is real. It's important to keep in mind. We've said for a very long time that Rust's churn rate would slow down. It's really pretty low at this point. Or at least, in the language.
One person on the lang team writing two blog posts fleshing out an idea does not mean the sky is falling.
Given that rust is changing, I think they are managing the change well.
The question is: should it be changing?
I think the answer is yes. Rust is a new kind of language that is showing people (like me) things I never would have thought were practical. It's inevitable that ergonomics are going to evolve to make everything flow together.
For those not familiar with the Rust drama, it should be emphasized that this blog post is very much a reaction to the linked blog post advocating for "Ok-wrapping": https://boats.gitlab.io/blog/post/why-ok-wrapping/
This is a subject that has provoked much drama in the past and looks like it will again.
In general, programming languages will change over time, so what matters to me is how that change is managed. Cautious, small, gradual changes over time seem safer than big releases every year or so, but particulary because of Rust's approach to stability. When Rust has a new feature implemented, it does not immediately become part of the stable language. Instead, Rust only commits to stability for a feature once it has been properly tested. It's something I think PHP (which I have been a significant contributor to) and other languages could learn from, because there's no substitute for real-world experience to decide if there are remaining rough edges on feature, or whether it is good idea at all.
Moreover, unlike some other languages, Rust has chosen not to force people to adapt their code to new syntax and features! They can stay on an old version (edition) of the language forever, yet still use an up-to-date toolchain and have others be able to make use of their code. I wish every language was like that. Imagine if Python 2/3 had never happened.
Yes, large projects like Firefox and Chrome are constantly updating their code. The rate at which that change happens varies though.
Sometimes you do that because the new stuff is a significant improvement in its own right, but you also need to do it because using an "obsolete" dialect of C++ makes it difficult to incorporate third-party code, makes it unattractive to new contributors, and is generally just a code smell.
I appreciate that the language I'm using is evolving, as well as the libraries and frameworks in the ecosystem. If I fail to keep up because I'm focusing on making the most out of the tooling I committed to, that leaves opportunity for growth. I care about creating solutions, not keeping up with the ambitions of a large, diverse group of high achievers.
Maybe it's just me, but every time I look at Rust I'm either turned off by the community or by this constantly shifting idea of what is best practice.
A lot of comments have talked about the idea of writing Rust like it is X year, which seems weird to me as I would imagine that a language with a strong ecosystem would not create a situation where five-year old code that was considered ok then is now looked back as bad code and a reason for derision. Besides the obvious learning better ways to do things as time goes on, shouldn't code written five years ago still be good if it works? Is code being a few years old the only excuse we need to rebuild it?
Maybe I'm wrong here, but what I want is to not have to think to myself a year after I build something "well, that was built in last years standard, time to rebuild in this years standard."
The "community" you're paying attention to is made up of enthusiasts, so it's to be expected that they tend to be in the camp of adopting new shiny things as soon as they're released. The same thing happens in C++; you'll often see reddit / stackoverflow telling you to stop using new/delete in favor of make_shared and make_unique, stop using loops in favor of functions from `<algorithm>`, and so on.
Regardless of whether the new additions make the language better or not (I believe they do, in both Rust's and C++'s case), adopting them immediately in the codebases you are responsible for is your decision. You have to decide by yourself whether the pros from adopting the changes are enough to offset the cons of making changes. If you conclude that the cons outweigh the pros, and if it bothers you that the "community" derides you for not tweaking your code, then a valid solution is to stop paying attention to the "community" and get on with your life.
Are you reacting to the talk about "editions," e.g., Rust 2015 and Rust 2018? Those are actual concepts in Rust, similar to how C has C89, C99, and C11. I personally don't feel compelled to rewrite working code in newer editions. I have, however, received at least one PR from someone else who felt compelled to do so without asking.
Meanwhile typescript people be like: oh I see you're still using the old style mapped quantum ensemble types introduced five weeks ago rather than the retro-causal discriminated union types which will be introduced five hours from now - how quaint.
[+] [-] pornel|6 years ago|reply
Instead of starting with a fat standard library, it started with minimal one and now each release adds 2-3 functions that could have been there in 2015. But none of it is idiom-changing revolution. These are mostly convenience functions, and you don't have to use them all just because they're there.
Every addition to the language is bikeshedded to death, goes through betas, revisions, refinements, before being stabilized years later. The first experimental release of async was 4 years ago and it has landed last November. So you may hear about new features a lot and they churn in nightlies, but actual big changes reach stable rarely.
Apart from async/await, since 2015 Rust made only 2 changes to how idiomatic code looks like (? for errors, and 2018 modules), and both of them can be applied to code automatically. I maintain over 60 Rust crates, some of them as old as Rust itself. All work fine as they are, and running `cargo fix` once was enough to keep them looking idiomatic.
[+] [-] twic|6 years ago|reply
This isn't slow.
Java went three years, from December 1998 to February 2002, without any language changes. And to be honest, even that wasn't that slow!
> Every addition to the language is bikeshedded to death
Not to death, because many of them don't die!
What i find annoying about Rust's changes is that some of them are so trivial - they change the language for such small improvements. async/await is not in that category, for sure. But Ok-wrapping actually is. The need to Ok-wrap results is a minor annoyance at most. Ditto a bunch of the problems solved by match ergonomics changes.
I think the root of the problem is that the changes are driven by a small core of Rust programmers - many working on Rust itself or some of its flagship projects - who are actively involved in the discussions around Rust. They tend to view change as natural, and the cost of change as low. I believe there is a larger group of Rust programmers who are not actively involved in these discussions, and are maybe not spending 100% of their time on Rust, for who the cost is higher. But we don't hear as much from them.
[+] [-] jkoudys|6 years ago|reply
There was a huge rush to use classes, which was sugar around the prototype system, but happened when we also got spread operators, Object.assign, and property name shorthand. We could already easily express the concept of a class far more easily than we were doing before, but because it all came out at the same time it didn't really click for the community at large and a lot of what became idiomatic didn't really feel important enough for a language update.
Ditto with generators and async functions, which while merely a very specific application of a generator is far better known. Again, not sure we needed all this extra syntax so you can say `async function foo() { await bar()`, when `co(function* foo() { yield bar()` was already available (if co were simply added to the Promise object). We're also now tying the language to a very specific implementation, when the co approach is explicit about saying what's responsible for taking control from the yielded function (a Promise).
[+] [-] ddevault|6 years ago|reply
[+] [-] k__|6 years ago|reply
Are they to slow and doing too much design by comitee or are they at an okay speed of innovation?
[+] [-] ekidd|6 years ago|reply
Some thoughts:
1. Most of the superficial changes, like 'dyn' and Rust 2018, are easily handled using automatic tools.
2. The original Rust 'Error' trait was clunky, and it lacked useful features like backtrace support. This led to a series of experiments and fads in error handling (e.g., error-chain, failure), which are only starting to calm down after recent enhancements to 'Error'. More conservative Rust users avoided this by sticking with 'Error' and living with the limitations.
3. Updating depencies has been surprisingly easy, with several notable exceptions. Very early adopters of 'tokio' 0.1 had a fair bit of work to do once 'async' stabilized. And OpenSSL has been a constant thorn in my side, despite being a native C dependency.
One handy tip: Don't force yourself to constantly update your code to use all the latest features. Not everything needs to be async. And it's OK to have some rarely-touched modules that are written like it's 2015.
[+] [-] saghm|6 years ago|reply
If it's acceptable for your use case, it might be worth taking a look at rustls. I'm not sure how far along it was back in 2016, but it's in a pretty good state right now. I consider it much easier to deal with than OpenSSL, and the fact that a lot of legacy crypto that I have no need for isn't even supported in the library is appealing at least to me.
[+] [-] oconnor663|6 years ago|reply
Indeed, the Rust compiler team has done a ton of work to build the "editions" system, so that you can do just that.
[+] [-] d1plo1d|6 years ago|reply
[+] [-] hinkley|6 years ago|reply
Officially we are upgrading to 12 for perf, but I was the first (and will probably be the primary) contributor to that work because I want everyone to have decent stack traces again. Our code has too many layers of abstraction, and working without full traces is adding insult to injury.
[+] [-] roca|6 years ago|reply
There are some upcoming improvements --- that I'd like to see! --- that are bigger and thus may be more challenging:
-- Better `const fn` will make many existing `lazy_static`s become unidiomatic. Worth it, but annoying.
-- Const generics will make a lot of existing code non-idiomatic. Again, well worth it, but annoying.
-- Generic Associated Types ... probably similar.
The question is, if people decided those important features don't belong in Rust because they would cause too much churn in code that wants to be idiomatic ... then what? That would almost guarantee a new language --- perhaps a fork of Rust, perhaps not --- would eventually fill that niche. Wouldn't everyone be better off if that language was Rust itself, and people who don't want to write that "modern code" ... don't?
[+] [-] gautamcgoel|6 years ago|reply
[+] [-] dilap|6 years ago|reply
To wit, C++ is a brutal, terribly designed mess that's absolute torture to work with.
Rust is extremely well-designed and a pleasure to work with.
Very important difference!
[+] [-] littlestymaar|6 years ago|reply
In fact, Go and Rust are both evolving fast compared to C (and maybe even to C++) and interestingly enough, most of the time the evolution comes in similar domains (error handling, modules, generics).
The big difference is the release schedule: Rust release small changes often while Go release big changes rarely. The 6-weeks schedule has advantages (each version is quite small so it's easier to test and bugs are found earlier) but it adds a feeling of churn which can be harmful.
[+] [-] Ar-Curunir|6 years ago|reply
The rate of adding features is quite slow, as demonstrated elsewhere in this thread. Important features spend a long time baking, and a long time in testing before they are piecewise stabilized.
> When a new version of Rust is released, the core Rust devs write a blog post gleefully explaining all the new "features" the current version has.
Of course when someone talks about a CHANGELOG, they'll talk (rather happily) about the things that have changed/improved.
[+] [-] Skunkleton|6 years ago|reply
[+] [-] phkahler|6 years ago|reply
[+] [-] yahyaheee|6 years ago|reply
[+] [-] cies|6 years ago|reply
Interesting. I witnessed a constructive collaboration by which the Rust community chose (mainly) the syntax for it's async features. I thought of it as amazing, thoughtful, rather democratic and on point. Nothing war-like to me.
[+] [-] GolDDranks|6 years ago|reply
[+] [-] Matthias247|6 years ago|reply
And while the syntax discussion saw a ton of comments, the more important underlying semantic aspects of async/await got a lot less attention - even though they also had and still have a few issues to resolve (e.g. around cancellation, thread safety, extensibility).
[+] [-] littlestymaar|6 years ago|reply
Here are the results of a survey ran on this syntax on about 400 Rust users from rust subreddit : https://i.redd.it/660zjw4rhsv21.png
You'd see the chosen syntax (field-like access) was one of the most disliked one…
[+] [-] rob74|6 years ago|reply
[+] [-] kens|6 years ago|reply
I'm not a Rust person so maybe I'm missing something, but why does the OP need to keep the code idiomatic? Can't the changing fashions in what's idiomatic be ignored?
[+] [-] davidcuddeback|6 years ago|reply
They absolutely can, but you might be stuck on an older "edition" of Rust. I've stuck with `try!()` for error-handling, because I think error-handling deserves more prominence than a single character. But that means my code is stuck on Rust 2015. If something I need is added to Rust 2018 or a later edition, I'll be forced to update or backport.
[+] [-] bosswipe|6 years ago|reply
[+] [-] typon|6 years ago|reply
[+] [-] _bxg1|6 years ago|reply
But Rust is already not a simple language. It already has long compile times, and some of its syntax sugar already makes it harder to understand what's really going on when you invoke it. I think it's important that the Rust community start reeling in frivolous sugar, otherwise it may just become C++ all over again.
[+] [-] Manishearth|6 years ago|reply
impl Trait in return position has changed how people code; but that's because it made certain things suddenly possible, which isn't an idiom change as much as obsoleting some old bad workarounds.
I'm curious to know why you felt like you had to change your code to be more idiomatic with impl Trait.
----
Nor does it seem like Ok wrapping is the kind of feature that would change what idiomatic Rust is.
[+] [-] xiphias2|6 years ago|reply
Regards the error checking syntax the article may be right, but as far as I saw, the await addition to Rust went perfect: it became stable when the decision was made (also a state of the art memory model was created for async calls), and nobody had to use it (or even follow it) before that.
[+] [-] AmrMostafa|6 years ago|reply
The author would be better or revisiting their code on a more relaxed cycle, for example every 18 weeks. Or whatever works for them, or just let go of the need to be using 100% of the latest best practices.
[+] [-] matt2000|6 years ago|reply
I know that's not the fashion currently, but it's probably one of the most valuable things to me.
[+] [-] bluejekyll|6 years ago|reply
We don’t want dead languages, look at Java. It was stagnant for a long time, but has now shifted to a better delivery methodology of new language features. Rust is the same and continues to improve. Continues to make things easier and better to use without giving up its speed and low overhead goals.
[+] [-] at_a_remove|6 years ago|reply
I program to solve problems. Changes in a language or worse, "how it is done" mean that I must keep up with something else in addition to solving the problems before me. Waves of increasing syntactic sugar in a language begin to look like layers of frippery and frosting, and I can only remember that "fashion is a form of ugliness so intolerable that we have to alter it every six months." I do not want to look at some bits of upper-row "executable line noise" that is somehow called syntactic sugar and try to have to mentally project what surface lies under that frosting.
What I want is to be able to look at ten year old code and it immediately be working and understandable. I don't want it to be out to style or "uncool" or to even have to think about these things.
By all means, fix bugs. Add libraries as new formats, protocols, and technologies emerge. Huge mistakes can be corrected in rare major version updates, which may have to count as actual forks in the language. When I first looked at Python, somewhere around 2004 or 2005 if I had to guess, I remember seeing that whole floor division bit and thinking, "Yeah, they're going to have to change that eventually and digging in their heels on that one was foolish." That's a rare exception, and it counts in the "why did this make it to 2.x?" category.
I feel a bit lonely in this, but I just cannot seem to embrace the churn.
[+] [-] steveklabnik|6 years ago|reply
In 2019, we had eight releases: 1.32 to 1.40.
- 1.32: one language adjustment, finishing off previous module work
- 1.33: const fn can do a few more things
- 1.34: you can do a bit more with procedural macros
- 1.35: a few minor details around closures
- 1.36: NLL comes to Rust 2015. Not really a new feature so much as backporting it to an older edition.
- 1.37: you can #[repr(align(N))] on enums
- 1.38: no real language changes
- 1.39: async fn! some adjustments to match. Some more borrow checker adjustments.
- 1.40: #[non_exhaustive]. The 1.39 borrow checker adjustments are ported to an older edition. Macros can go in a few more places.
Really, 1.39 was a huge release, and other than that... all language changes were very minor, mostly sanding off some edge cases, making some things more orthogonal, stuff like that.
Most releases these days add some standard library APIs, maybe we have some toolchain improvements... but for all of 2019, we had one feature I'd call truly major.
I suspect that things were a lot more hectic previously, but the language has slowed way, way down recently. We have had two releases so far this year, and I would argue that the only real language feature was an expansion around match patterns. Which again, isn't so much a new feature as it is adding a little bit to an old one.
Churn is real. It's important to keep in mind. We've said for a very long time that Rust's churn rate would slow down. It's really pretty low at this point. Or at least, in the language.
One person on the lang team writing two blog posts fleshing out an idea does not mean the sky is falling.
[+] [-] jeffdavis|6 years ago|reply
The question is: should it be changing?
I think the answer is yes. Rust is a new kind of language that is showing people (like me) things I never would have thought were practical. It's inevitable that ergonomics are going to evolve to make everything flow together.
[+] [-] ChrisSD|6 years ago|reply
This is a subject that has provoked much drama in the past and looks like it will again.
[+] [-] TazeTSchnitzel|6 years ago|reply
Moreover, unlike some other languages, Rust has chosen not to force people to adapt their code to new syntax and features! They can stay on an old version (edition) of the language forever, yet still use an up-to-date toolchain and have others be able to make use of their code. I wish every language was like that. Imagine if Python 2/3 had never happened.
[+] [-] MR4D|6 years ago|reply
Not sure I really get the concept here.
[+] [-] roca|6 years ago|reply
Sometimes you do that because the new stuff is a significant improvement in its own right, but you also need to do it because using an "obsolete" dialect of C++ makes it difficult to incorporate third-party code, makes it unattractive to new contributors, and is generally just a code smell.
[+] [-] saagarjha|6 years ago|reply
[+] [-] mcguire|6 years ago|reply
[+] [-] dheera|6 years ago|reply
* function as class -> class
* function() {} -> ()=>{}
* callback -> promise
* var -> let, const
Every year there's something else new that you are told you are doing wrong.
[+] [-] krakatau1|6 years ago|reply
[+] [-] Dowwie|6 years ago|reply
[+] [-] shruubi|6 years ago|reply
A lot of comments have talked about the idea of writing Rust like it is X year, which seems weird to me as I would imagine that a language with a strong ecosystem would not create a situation where five-year old code that was considered ok then is now looked back as bad code and a reason for derision. Besides the obvious learning better ways to do things as time goes on, shouldn't code written five years ago still be good if it works? Is code being a few years old the only excuse we need to rebuild it?
Maybe I'm wrong here, but what I want is to not have to think to myself a year after I build something "well, that was built in last years standard, time to rebuild in this years standard."
[+] [-] Arnavion|6 years ago|reply
Regardless of whether the new additions make the language better or not (I believe they do, in both Rust's and C++'s case), adopting them immediately in the codebases you are responsible for is your decision. You have to decide by yourself whether the pros from adopting the changes are enough to offset the cons of making changes. If you conclude that the cons outweigh the pros, and if it bothers you that the "community" derides you for not tweaking your code, then a valid solution is to stop paying attention to the "community" and get on with your life.
[+] [-] davidcuddeback|6 years ago|reply
Are you reacting to the talk about "editions," e.g., Rust 2015 and Rust 2018? Those are actual concepts in Rust, similar to how C has C89, C99, and C11. I personally don't feel compelled to rewrite working code in newer editions. I have, however, received at least one PR from someone else who felt compelled to do so without asking.
[+] [-] seemslegit|6 years ago|reply