25 ms·
I can't keep up with idiomatic Rust
- Animats 7y agoThey're still fussing with the preferred error handling syntax? Most of the hacks for not having exceptions seem to end up being worse than exceptions.
- dpc_pw 7y agoNot it didn't. Rust error handling is glorious comparing to exceptions. Rust community is just full of perfectionist and we love to argue endlessly about how to improve stuff even more, which is very refreshing. In many other PLs people just keep their heads down and crawl in the mud.
- smt88 7y ago> In many other PLs people just keep their heads down and crawl in the mud. Or, as I would put it, programming is a job for them and not also a hobby. They have other things to spend time on, so banging out an ugly codebase in JavaScript is "good enough" to let them clock out. Either is fine, but I don't think it's realistic to assume everyone can or should seek perfection in their tooling.
- lkschubert8 7y agoI think that's mostly because the end desire is to have them forced to be dealt with like java's checked exceptions, which most people have a problem with. It's hard to make forcing handling something easier for the developers, but I would argue its better than having unknown failure modes in functions you call.
- unlinked_dll 7y agoNo, it's just that a prolific rust contributor made a blog post and then a follow up and things have been heated in the community a bit (I lurk a bit). The fuss isn't over what the syntax should be, but whether it should be changed at all. The proposal isn't even an RFC, just a blog post and some discussion threads. I think the proposal made good points about the ergonomics of error handling. I think the community might just be a little stir crazy with the quarantine, and talking about a syntax change that upends the much loved Result idiom rustled some feathers. FWIW it is a purely syntactical change that adds sugar, the underlying mechanism does not change. The "hacks" for not having exceptions are strictly superior to having exceptions, at least in my opinion because the error monad is both opt-in on the caller side and opt-out on the callee, it does not include non local returns (errors don't cause the program to jump up the stack, like C++ exceptions, or any need to pass down the exception handler or pass up a continuation), they support all sorts of wonderful combinators that exceptions don't play nicely with, and unless explicitly disabled by a binary author the stack will always unwind and RAII patterns observed. The issues with exceptions are well documented.
- notacoward 7y agoPerhaps in terms of verbosity/tedium, but at least they don't have the problem of silently breaking functions between the exception thrower and catcher.
- awesomepeter 7y agoSeems like it would be beneficial if codemods would accompany such features if possible.. is it possible in rust?
- steveklabnik 7y agoThere are several ways of doing this, yes. Including one provided by the Rust project itself, “rustfix.”
- eindiran 7y agoIs "rustfix" what is running behind-the-scenes when you run "cargo fix" or is it something distinct?
- Ar-Curunir 7y agoyes, cargo fix uses rustfix
- steveklabnik 7y agoYes, it is.
- JoshTriplett 7y agoYes, cargo fix just runs rustfix on all the files in your project and passes the same flags cargo does to rustc. (Similarly, cargo fmt runs rustfmt on all the files in your project.)
- smabie 7y agoWhy not just add a fold function to Option (as all monads should have a fold)?
- geofft 7y agoFold isn't an operation on a specific monad, it's a generic operation over any monad. Adding it to Option defeat the whole point of thinking about Option as a monad, i.e., the ability to apply generic algorithms that work on any type constructor that follows the monad laws. (If the question is why no generic fold over any monad exists in Rust, the short answer is that Rust isn't Haskell. Which is great, it means Rust can specialize in things Haskell can't and vice versa. Personally my favorite example is that Haskell avoids shared mutable state by avoiding mutable state, and Rust avoids shared mutable state by avoiding shared mutability. Both have their downsides but each works better for different applications.)
- smabie 7y agoSure, but Scala supports monads via the 'for' construction and yet, no monad trait or class is defined in the base language at all. Even if they are defined ad-hoc on each type, there's value there.
- lmm 7y ago> Fold isn't an operation on a specific monad, it's a generic operation over any monad. Adding it to Option defeat the whole point of thinking about Option as a monad, i.e., the ability to apply generic algorithms that work on any type constructor that follows the monad laws. Having the same function exist with the same name helps communicate with other programmers, even if you can't express the fact that it's actually the same function at the language level. Just like in a language without generics you might still have add(int, int), add(decimal, decimal), add(string, string) and add<T>(list<T>, list<T>) functions. Rust already offers a function called "and_then" on most of its monadic types, and a programmer can see and understand that these are all in some sense "the same function" even though there's no way to abstract over that.
- 7y ago
- rddttxcdevsgood 7y agoRust isn't a homogeneous community and it would be a grave injustice to the devs' efforts to call their work bikeshedding. Rust community is two things- the extremely thoughtful about language and nice and helpful to community devs. The other is redditards who are toxic and want things their own way. It is arguable why Rust attracts that toxic crowd but what usually happens is on Anything popular that crowd goes and creates too much noise. Please don'tconflate the two communities. I would start by banning people on reddit to just shove them away.
- kens 7y ago> 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?
- davidcuddeback 7y ago> 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.
- Izkata 7y ago> But that means my code is stuck on Rust 2015. ...can't you upgrade and choose not to make that change? Did something happen to make that not compile? (not a Rust user)
- boardwaalk 7y agoIt looks like they might need to use "r#try!(...)" in Rust 2018 (a trivial search replace, 'cargo fix' might do it too, not sure), but the macro is still available: https://doc.rust-lang.org/stable/std/macro.try.html https://doc.rust-lang.org/stable/std/macro.try.html It's trivial to implement yourself, too (if you, for example, wanted to give it a non-reserved name).
- davidcuddeback 7y agoThanks. Didn't know about the raw identifier syntax. That's kinda ugly, so I'd probably still go with copying it to all of my projects and giving it a new name if I were to update to Rust 2018.
- 7y ago
- gautamcgoel 7y agoThis 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.
- dilap 7y agoI'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. Very important difference!
- inimino 7y agoC++ is two and a half decades older than Rust. Come back to this comment in 25 years and see how well the pleasure of Rust's design has held up.
- thawaway1837 7y agoThat’s ironic because arguably C++ became a much better language in the last decade or so than what it was before that.
- rob74 7y ago...and I'm sure the language features which feel like torture now looked like a good idea at the time they were implemented, decades ago.
- 7y ago
- xiphias2 7y ago,,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.
- throwaway17_17 7y agoCan you provide any links on references to a memory model for async calls, I would be interested in reading them.
- Matthias247 7y agoI actually have't heard of any - and I'm pretty deep into the async things. Rusts async model just follows the synchronous model. Everything is not thread-safe unless it's annotated with the `Send` or `Sync` annotation. Futures which can be awaited are either not thread-safe - which means they can only be executed by a single threaded executor. If they are `Send` they can be migrated between threads and also executed by a multithreaded executor - like tokio. But those are rather just thread-safety annotations and not a memory-model
- jreyes33 7y agoThey might be referring to `Pin`. See https://doc.rust-lang.org/stable/std/pin/index.html https://doc.rust-lang.org/stable/std/pin/index.html and also https://rust-lang.github.io/async-book/04_pinning/01_chapter.html https://rust-lang.github.io/async-book/04_pinning/01_chapter...
- tmandry 7y agoI’m not sure I would call this a memory model per se, but here’s how async tasks are laid out in memory. http://tmandry.gitlab.io/blog/posts/optimizing-await-1/ http://tmandry.gitlab.io/blog/posts/optimizing-await-1/
- xiphias2 7y ago
- adamnemecek 7y agoRust is not the only language that changes over time. The changes in Rust are must smaller than say C++.
- jfkebwjsbx 7y agoNot even close. C++ is a language that is over 30 years old. In comparison, Rust is way younger and has had many more changes and features added in a way shorter period of time. For good or bad.
- saagarjha 7y agoI think the rate of changes to C++ has accelerated recently as well. Until C++11 it wasn’t actually that unreasonable.
- jfkebwjsbx 7y agoEven if you add the recent additions, it is still less stuff than Rust already has. For instance, async. The problem with C++ is all the bending backwards they do to keep old code compiling and working, which is a major reason for its success.
- roel_v 7y ago"The problem with C++ is all the bending backwards they do to keep old code compiling and working" Uh, that's not a problem, it's (as you say) the main reason people use it and why they burn out on flavor of the day languages like Rust and Go (as the OP illustrates).
- Ar-Curunir 7y agoThis is funny, because with Rust you can almost certainly compile code from Rust 1.0, unless it was relying on a soundness bug. You can also seamlessly use dependencies that use newer editions of Rust; you don't have to adjust your code to do this.
- ekidd 7y agoI 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.
- oconnor663 7y ago> And it's OK to have some rarely-touched modules that are written like it's 2015. Indeed, the Rust compiler team has done a ton of work to build the "editions" system, so that you can do just that.
- d1plo1d 7y agoAs 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.
- steveklabnik 7y agohttps://blog.yoshuawuyts.com/error-handling-survey/ https://blog.yoshuawuyts.com/error-handling-survey/ is a good summary of what's out there. I think current rough consensus is anyhow/thiserr depending on if you're writing an application or library. I haven't actually used them myself, though. You don't have to keep up with the cool new libraries.
- 7y ago
- cies 7y ago> The .await war was the final straw [...] 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 7y agoTo 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.
- saghm 7y agoI wasn't involved at all in the discussion, but having dove deep into async over the past few months since async/await was stabilized, I definitely am happy with the result of that process. Writing code with postfix `.await` feels very natural to me and it fits it much better with the surrounding code I write than a prefix version would. I can sympathize that participating in that process might not have been fun, but I really hope that the results of future discussions make me as happy as this one has.
- lightgreen 7y ago> Writing code with postfix `.await` feels very natural to me and it fits it much better with the surrounding code I write than a prefix version would. That’s your subjective point of view, not everyone agrees with it. Part of the problem is that Rust team failed to find a solution good enough for the most people and failed to communicate this decision. In particular the switch to .await syntax happened just couple weeks before it was finally stabilized. And await is not the only controversial decision made by the Rust team. Even if 10% of people unhappy that’s too much, because the next controversial feature will cause 10% more of unhappy people and so on. I hope they will do better next time.
- diebeforei485 7y agoI feel this way about Swift.
- ViViDboarder 7y agoIt’s better than Swift actually. The Swift compiler isn’t even backwards compatible.
- saagarjha 7y agoIdiomatic Swift has been fairly stable for a couple of years.
- MR4D 7y agoDoes anybody change/update their C++ code to keep it “idiomatic”? Not sure I really get the concept here.
- mcguire 7y agoNo idea, but you do see a lot of "no, that's ancient deprecated crap; this is how you do it" every time a new C++ standard release comes out.
- saagarjha 7y agoFor my toy projects, all the time. In production code I often like to use modern C++ when replacing older code.
- roca 7y agoYes, 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.
- deleted 7y ago[deleted]
- benbenolson 7y agoJust use C99. No need to keep up with anything.
- rmdashrfstar 7y agoSeriously. This arrogance of “I need the one true language that was perfectly designed from the start and never needs to change! If a new feature is added at all ever after initial release, it must mean the language is useless. Why don’t we all use Go? That’s the perfect language. It’s just like C.” Yawn. The borrow checker is a major leap forward, even if it’s from the 80s. And, with the incredibly expressive power and concise syntax Rust offers, it’s an incredibly compelling option. Plus, Rust has a guarantee of backwards compatibility.
- cryptonector 7y agoMicrosoft please!
- alvarelle 7y agoPersonally, I stick with K&R C. I haven't gotten around to update all my with function signatures. whats is the thing with putting (void) all over or specifying the return type of my functions? Really, these explicit function declaration are just code duplication that serious programmers don't need as they know their code. (/s)
- nwxonwxo 7y agoYou’re being sarcastic, I know, but you just unironically exactly described an entire decade or more of early C programming.
- matt2000 7y agoOne 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.
- bluejekyll 7y agoHave 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.
- SaxonRobber 7y agoWhy does a language need changes to be alive? We don’t ship languages, we ship code written in them. It’s like claiming wood is dead because we have vinyl.
- geofft 7y agoThe comment you're replying to gave a good example - the history of Java. If you're shipping code and modified code, you care about the language in which you can make those modifications. A frozen language means that either those modifications are harder (because potential improvements to the language are ignored) or they require writing components in an entirely new language and figuring out interop. (If you're not shipping modified code, then you don't care if the language changes after you ship, anyway. You shipped, and then you're done.)
- pents90 7y ago> A frozen language means that either those modifications are harder I don't agree that it's harder. What is definitely harder is not being able to ship bug-fixes or modifications without ripping everything up because the language has moved on since your last release. And that is very common when developing for, as an example, iOS, since Swift is a fast-moving language that doesn't maintain backwards compatibility. The benefits of having some new language feature in Swift are far outweighed by the downside of existing codebases being invalidated. The various languages in the Javascript family suffer from this as well. The Python 2 -> Python 3 debacle was another example of this. I have dusted off 20 year old Java code which compiled and ran just fine just fine. That is extraordinarily valuable to me, and requires a lot of discipline by the language maintainers. In fact, the new faster pace of Java iteration could be its downfall, time will tell. A last note: how many language features from the past 20 years really matter? How many really speed up development, improve maintainability, etc. I would say that there are very few. In fact, perhaps the only one that passes that bar might be async/await type threading advancements.
- dheera 7y agoThe same can largely be said of JavaScript: * 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 7y agoWell of course but Javascript is in unique position to do those kind of things, other languages have to be careful not to alienate its communities.
- 7kmph 7y agoSad to see that rust is heading towards a wrong direction. I think everyone in the core team should be stopping what they are doing and write Haskell for a year. This way they can appreciate the benefit of Haskell, and know what to avoid when they implement those ideas in rust, and anyone who trying to make the language and the philosophy more like c++ or java should be banned from the rust community
- deleted 7y ago[deleted]
- steveklabnik 7y agoSeveral folks on the language team know Haskell well.
- smabie 7y agoI'm sure they do, but even you must admit that Rust has gotten less 'functional' in nature as time goes on. New syntax or ad-hoc abstractions are being created to handle problems that have well known FP solutions. Take this matching on an Option business. The easy solution is to just add a fold method on the option type. Problem solved, now you never will need to match an option ever again! The harder solution would be to implement HKT and add a real monad trait, but let's not get into that. Another example are the async/await syntax. Why does this syntax need to exist? What value does it provide? Why can't a future just be a regular old class? A long time ago I thought Rust was going to be a flexible and innovative general purpose language. While it still is undoubtedly innovative, it seems like the target audience has shrunk considerably. And as GCs improve and get more tunable, I think that target audience is going to get even smaller in the future.
- steveklabnik 7y ago> even you must admit that Rust has gotten less 'functional' in nature as time goes on. I don't think this is true, especially when you look at long timescales. > New syntax or ad-hoc abstractions are being created to handle problems that have well known FP solutions. They have known solutions when you have a GC and no control over memory layout. They do not have known solutions in a language like Rust. > Take this matching on an Option business. The easy solution is to just add a fold method on the option type. Problem solved, now you never will need to match an option ever again! Sorry, I do not understand what you're talking about. (I coded in Haskell most a decade ago, I'm not on the lang team.) What would fold do on an option, specifically? Fold is usually a list operation, but an option is a list of zero or one... so it would be a no-op? > The harder solution would be to implement HKT and add a real monad trait, but let's not get into that Again, this is "we don't know if this is possible in a language like Rust" territory. Which is why you don't want to get into that. > Another example are the async/await syntax. Why does this syntax need to exist? Specifically because of the previous statement. It is not clear that a more abstract option is possible. We could wait for more years until maybe it's proven possible, or we could implement a useful feature today that we know is. It's also more significant in Rust than other languages due to borrowing. http://aturon.github.io/tech/2018/04/24/async-borrowing/ http://aturon.github.io/tech/2018/04/24/async-borrowing/ is a bit out of date but the concept is the same. > Why can't a future just be a regular old class? Rust doesn't have classes. Futures are a regular old typeclass. > While it still is undoubtedly innovative, it seems like the target audience has shrunk considerably. We have seen a massive uptick in adoption over the past few years. async/await, for example, has been a feature that a lot of folks have said "I'll start using Rust once that hits stable."
- _bxg1 7y agoI'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.
- Ar-Curunir 7y agoCan you name some examples of "frivolous sugar"? Also compile times have been a big focus of the compiler team, and have been going down YoY.
- _bxg1 7y ago> Can you name some examples of "frivolous sugar"? The one mentioned in the article seemed fairly frivolous to me. I don't know if I can name one that's already been accepted into the language which I would call frivolous, per se, though they're all varying degrees of necessary. But most of the "sugar" syntaxes have made the language harder to understand for newcomers, even the ones that are arguably necessary. They all come with a cost. The ? syntax for Results, for example, rubs me the wrong way a little bit. In that case it really does eliminate a large amount of code and is probably worth the trade-off. But now instead of Results just being a monad that can be picked apart like any other data structure, they become a Language Feature that gets special, magical treatment not expressible by the type system. You just have to know what the question mark translates to underneath. Worthwhile or not, this makes me sad. Async/await is a similar case. > Also compile times have been a big focus of the compiler team, and have been going down YoY. Yes but adding complexity to the language immutably increases the difficulty of that task. Even if only by a little bit, it adds debt that will have to be reckoned with for the rest of the language's lifetime.
- hobofan 7y agoI don't completely buy the argument for `?`. Yes, you have to know what it compiles down to, but the same goes for any other part of `std::ops` (like Deref, Index, etc.). In that way the addition of `?` as `std::ops::Try` doesn't imply "special, magical treatment not expressible by the type system", but gives it the deserved representation in the type system that was possible anyway, and hooks it up with a syntax that is only achievable with compiler support.
- snambi 7y agoTotally agree. Rust is complicated for doing simple things.
- Dowwie 7y agoThis is true, as is the fact that work often demands one not do "simple things" and in this space Rust shines
- roca 7y agoI 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?
- swalladge 7y ago> 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? Agreed. The author's whole argument of not wanting "having to make these superficial changes again and again" doesn't make sense. There isn't any requirement for all code to follow the latest and greatest idioms. Rust guarantees backwards compatibility, and the author even acknowledges that in the article. It would be pretty sad if the reason for no new features or syntax in Rust was due to programmers not wanting to feel like their code was no longer idiomatic.
- sedatk 7y agoWow, he said he got stuck with Rust 2015 and I thought Rust wasn’t keeping backwards compatibility, like earlier Swift. Not cool.
- fluffything 7y agoI've been using Rust since 2015 and never had to update anything. The Rust "language version" is a per translation unit setting, and Rust supports having multiple library versions in a binary. So when I want to use a new language feature, or want to use a new library or library updated to use a new language feature, I just do so in the next translation unit I create. Creating a new translation unit always defaults it to the latest language version (unless you specify otherwise), so this is a quite laidback low-friction approach. I tend to create at least one translation unit per month. If I had to update all my code to use the latest language features I wouldn't be doing anything else full time. This has nothing to do with Rust. I also use C++, Javascript, ... I don't think I would manage.
- beetwenty 7y agoOn the one hand, this is a predictable outcome if you are trying to shepherd a large codebase through a fast-moving language. Idiomatic Python 1.6 looks dramatically different to idiomatic Python 3.x. On the other, Rust isn't the language I would want to write lots and lots of code in either. There are a few projects and organizations where it makes sense to do so(namely web browsers, databases, and other kinds of "deep backend, large surface area" types of projects), but most of the things it does well also act as a hindrance to feature development, compared with an idiomatic Java, C# or Go equivalent.
- marta_morena_23 7y agoSo what? Did you ever look at a production codebase? You will be hard pressed to find an idiomatic codebase and nobody in the world is going to update anything to be "idiomatic" every 6 weeks. I mean maybe your manager doesn't fire you right away if you try, but you better be doing this in your spare time lol. For academic and self-learning use? Sure go ahead, but then please don't complain that you can't keep up with it. Nobody should be using a feature for the sake of using a feature. If you don't need it, don't use it. If its old and not "idiomatic" there is literally ZERO reason to change it unless you ain't got anything better to do. Get your priorities straight.
- dx87 7y agoI can't keep up with it either, but that doesn't stop my code from doing what I want it to do. There are a lot of people who seem like they enjoy working on Rust as a hobby, the same way some people like playing video games. They still have a commitment to backward compatibility though, so who cares if a bunch of people geeking out on their favorite language are fine-tuning it and making superficial changes, the code I wrote before stil runs the same (or better) than it did when I wrote it. The compiler doesn't care if it's idiomatic, just that it's correct.
- ryuukk_ 7y agorust is just like scala, bloated and useless features, on top of an ugly syntax and a religious community (sect)
- steveklabnik 7y agoI'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.
- _bxg1 7y agoMy main concern is with new syntaxes. Expanding use-cases for existing ones, loosening restrictions that can be safely loosened, etc. are all well and good. But layering on new sugar-syntaxes that aren't truly necessary makes the language much harder to mentally grok over time. All of a sudden you can't just derive what's happening by studying the code, you have to add new pieces of arbitrary information to your mental toolbelt first. The Ok(..) one mentioned, from a quick glance, seems really unnecessary.
- 7y ago
- Manishearth 7y agoNot 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.
- Ar-Curunir 7y agoThis is an anecdote, but I'm someone who keeps up rather zealously with language updates, and even though I write a lot of generic-heavy code, I don't think my code contains a single instance of `impl Trait` in either argument or return position, across over 60,000 lines of rust code
- fluffything 7y agoI guess that depends on how you code. Do you ever write code that returns, e.g., an `Iterator` ? e.g. fn my_map<T: Mul, I: Iter<Item=T>>(it: I, x: T) -> impl Iterator<Item=T> { it.map(|i| i * x) } `impl Trait` in return position is the only way to write that kind of code, because you can't name closures. You can workaround this by re-implementing a custom `Map` iterator... Or if you are dealing with `Future`s, by writing a new custom `Future` type, but with `impl Trait`, you don't need to. I use it a lot. What before required a lot of boilerplate, now is a one liner.
- Manishearth 7y agoI address this in the second paragraph: > 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. this isn't a new idiom. this is code that wasn't possible before suddenly becoming possible, and people using it.
- jeffdavis 7y agoGiven 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.
- deleted 7y ago[deleted]
- ChrisSD 7y agoFor 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/ 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.
- crimsonalucard 7y agoI recommend that this guy switch to javascript to truly understand himself.
- shruubi 7y agoMaybe 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."
- Arnavion 7y agoThe "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.
- davidcuddeback 7y ago> writing Rust like it is X year 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.
- demarq 7y agojust a big FAT WARNING here. C++ suffered for a long time from staleness because people detested change. I think tools and technologies should prioritise the future and new users than focusing on the past and long time users. it is what is best for the survival of the language. if you don't want to deal with the changes then don't update your code base. but don't update the compiler then resent the fact that it is updated.
- malkia 7y agoC++ programmers, like what I do mostly, may have to do over and over with new standards, but don't have to for all code.
- AmrMostafa 7y agoNot 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.
- 978e4721a 7y agoI recently had a thought, that language team should provide automated migration tools for such things. It woukd made python 2 to python 3 switch much easier and faster, that applies to rust even more.
- dbrgn 7y agoThey do: https://doc.rust-lang.org/cargo/commands/cargo-fix.html https://doc.rust-lang.org/cargo/commands/cargo-fix.html It works much better than 2to3 actually.
- pjmlp 7y agoNow imagine when it gets to the 40 years of C++ existence, or 25 from Java, 20 from .NET, then one learns to value why enterprises care about backwards compatibility. More breaking changes are on the way, until error handling and async/await get properly integrated into std, instead of having a couple of incompatible crates each going its own way.
- dmit 7y agoPlease allow me to share my view of the conversation up to this point: Boats: Here is an approach I use in my personal projects that has proven to be ergonomic, consistent with other language features, and could possibly even unlock future optimization opportunities long down the road. OP: That's it, I'm DONE. The language moves too quickly and I can't keep up. You: More breaking changes are on the way. They never learn. ----- Would you agree that this escalated way, way too quickly? Boats didn't "move" the language with a blog post, it's not even a pre-RFC. As pointed out elsewhere in this thread, the language hasn't been moving at all since 1.0 - you could say the frontier has been inching forward, but that's what frontiers do; nobody's forced to fight on the front lines all the time. And then the cherry on top - "more breaking changes on the way", when 1) prior changes weren't breaking; 2) it's not clear there will be any new ones; 3) if there will, those won't be breaking either.
- pjmlp 7y agoPlease let us know how async/await is not going to be a breaking change, when even Fuchsia just decided to create their own async runtime, because surely we still don't have enough of them. So I wonder how std will incorporate a runtime implementation that happens to be compatible with all ongoing runtime flavours, so that those breaking changes don't happen.
- dmit 7y agoWell, either the language will leave async runtimes in the domain of third-party libraries, which is the current approach. Or, the potential blessed one in std will be an alternative that you may or may not want to use in your code. When I think of breaking changes, I think removing sun.misc.Unsafe. Which, yes yes, was never supposed to be used, but still was. Evolution of best practices and introduction of alternative implementations doesn't break anything.
- scoot_718 7y agoI don't want a language full of special cases.
- seemslegit 7y agoMeanwhile 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 7y agoRust 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.
- k__ 7y agoI can't comprehend what you're going at. Are they to slow and doing too much design by comitee or are they at an okay speed of innovation?
- twic 7y ago> 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.
- Dowwie 7y agoI 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.
- jtdev 7y agoAvoiding rust atm myself. Just seems too clever for its own good.
- 123_throwaway__ 7y agoThis is what happens when a bunch of web developers are in the core team of a supposedly "systems programming" language. Web developers are used to moving to a new framework every week.
- TazeTSchnitzel 7y agoIn 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.
- ilaksh 7y agoI thought that not knowing what idiomatic Rust looks like was the most idiomatic thing about Rust.