15 ms·
I disagree with all the points in the article with the exception of lifetimes which i do find cumbersome at times due to the way they have to be propagated whic
by tmpfs 4y ago
I disagree with all the points in the article with the exception of lifetimes which i do find cumbersome at times due to the way they have to be propagated which makes refactoring to references awkward.
I think the larger standard library of a language like Go is appealing but Rust is a community effort and doesn't have Google scale resources to maintain a large standard library.
I particularly abhor Go style uppercase for public visibility and much prefer Rust's explicit syntax. In addition, i find Rust's module system very enjoyable and prefer it to any other language i have used once i got familiar with it.
- ncmncm 4y agoJust making borrow checker violations into warnings for debug builds would go a long way to making the language more tolerable to the overwhelming majority of programmers not already committed to it. Wanting to ship without violations does not mean you are not interested in getting your algorithm working, first. Often enough, you will abandon your laboriously borrow-safed code without shipping it, because you figured out a better way. But! you had to borrow-safe the new way, too, before you could even try it out. Rust has already penetrated a good fraction of places that will tolerate it as it is now. To find wider usage, the user experience will have to get much better. Without finding enormously wider usage, it will fizzle. It will have fizzled: you only know after it is too late. Fizzling is absolutely the normal fate of any new language. It takes absolutely phenomenal adoption to generate a lasting ecosystem. Even phenomenal adoption is not always enough. We once thought Ruby had legs, and Ada.
- eminence32 4y ago> Just making borrow checker violations into warnings for debug builds This is an interesting idea. I wonder what class of borrowck problems could be ignored like. Some of them can't be ignored, I think, because they would allow catastrophic things like use-after-free. But are there other violations that aren't as serious?
- ncmncm 4y agoIf they are catastrophic, you may have to fix them to make progress. But most are not, and you can make other progress. Leaks are not. Cargo should not be dictating your work schedule.
- sfvisser 4y agoI think this is valid reasoning. Allowing to turn errors into warnings for dev builds would probably allow for fixing issues faster. Given the UX is good. I use todo!() a ton when building as well. Sketching out data types and signatures before diving into implementation details.
- josephg 4y ago> Just making borrow checker violations into warnings for debug builds would go a long way to making the language more tolerable to the overwhelming majority of programmers not already committed to it. The problem is that the borrow checker isn't just a verifier of correctness. It actually impacts the semantics of a program. For example, in javascript if you open a TCP connection and let your connection handle go out of scope, the connection will stay open. And as a result, your program will sort of just hang. In Rust, when you open a connection and your handle goes out of scope, the socket is closed automatically. How does the compiler know when your program should close the socket? It knows based on the borrow checker's analysis of your program. If your program confuses the borrow checker, that means that the compiler can't figure out when it should close that TCP connection on your behalf. This isn't the sort of thing you can just turn off in debug mode, because programs should act the same in debug and release modes. A program which doesn't close the TCP connection is a different program from one which does. There are ways around this - you can use types like Box, String, Rc, Cell, etc. And then just .clone() all over the place. But your code will run slowly. And thats still way more annoying to use compared to other languages. I don't know any other language which makes you write "Box" to put an object on the heap. I hear the criticism. It is legitimately really hard to learn how to write rust code in a way that makes the borrow checker happy, especially at first. I'm still avoiding async rust after getting my feet burned by it a couple of years ago. As another commentator has mentioned, rust makes you experience all the pain up front. Its a lot of pain for new programmers to the language - probably too much. I genuinely believe rust will never achieve the popularity of languages like Python, Go or Javascript. Its just so much harder to learn. I don't think there's anything wrong with that. Most programmers don't need to write systems software. I'd rather rust keeps focuses hard on what its good at: situations where performance and correctness are more important than development speed. We have plenty of good programming languages for quickly prototyping things out. There's nothing wrong with using them when they're the right tools.
- ncmncm 4y agoA buggy program is a buggy program. But sometimes you have other bugs you know about that you want to fix first. Or you want to try out something else, first. As long as your builds report violations, you will know you aren't done. You might suspect one or other warning is why something mysteriously doesn't work, and try tackling that. Or you know already, and have bigger fish to fry. Before you are done, and ship, you will certainly have fixed everything, because your release build had to complete without violations. You are strictly better off making your own work schedule choices. I would like for Rust to be used more in places where C is today. But that can't happen if it does not get wider acceptance.
- fulafel 4y agoA common suggestion for this seems to be to use the stdlib GC mechanism (refcounting) for those cases, is that too limiting?
- pjmlp 4y agoToo boilerplaty. While other languages with RC based GC mechanisms take care of managing the references automatically, even the C++ std ones do it, in Rust you have to manually increment the references with calls to clone().
- ncmncm 4y agoYes. Rust probably should have a built-in pimpl-y construct, in lieu of user-codable moves. (Maybe it does, by now? Dunno.)
- pjmlp 4y agoIt doesn't and I guess it will never get one, as it is apparently considered good practice that clone() calls are explicit, as in the developer is painfully made aware of the performance cost of reference counting. So then we land in Rust code golf, where one tries to make the code as much as possible with bare bones borrow checker.
- ncmncm 4y agoNot real clear on this... In C++, pimpl types almost always have a std::unique_ptr<Impl> in them, and they get moved, not copied. The compiler generates the move constructor implicitly, and move cannot fail. Maybe in Rust this just a struct with a ref in it? And what would be member functions borrow from it?
- pjmlp 4y agoAh, sorry. I misunderstood your point, so went into another path. I don't see how this would work, Rust is already move by default, the problem is how to get std::shared_ptr() like convenience where copy member functions are called by the compiler, with the side effect of taking care of the counters implicitly. In Rust, copying is explicit, thus manually typing the copy()/clone() calls.
- ModernMech 4y ago> Just making borrow checker violations into warnings for debug builds would go a long way to making the language more tolerable to the overwhelming majority of programmers not already committed to it. I hope Rust never does this, as I think it would kill the best thing about the language. There's almost no point in using Rust if you're not interested in leveraging the borrow checker to write safer code. Just write C++ instead. The last thing the Rust community needs is to be flooded by new users who don't bring with them a culture of writing safe code. If you give users the ability to just turn off the borrow checker, they'll leave it off and ship code in debug mode. Many users find the borrow checker perplexing only because they can't understand why the code they write day in and day out in other languages gets rejected by Rust. Well the answer is likely because it's unsafe in some subtle way, and the borrow checker caught it before you even had an inkling there was an issue. Best to get used to writing safer, well-architected systems first, and then you'll have an easier time satisfying the borrow checker.
- pjmlp 4y agoVisual C++ development experience with background live static analysis is slowly approaching Rust like, and that is the team's goal. It just needs to be good enough for people not bothering to change.
- ncmncm 4y agoEither Rust gets this, or almost everybody who might otherwise have coded Rust, someday, will be obliged to "write C++ instead". Or something. Letting your favorite language fizzle because you want to force everybody else's implementation schedule to match your biases is a peculiar choice. I don't mind, personally, if Rust fizzles, but it seems like you ought to care.
- indiv0 4y agoThere is an answer to this. Just `.clone()`, `.to_owned()`, `Arc::new`, and `Mutex::new` like a madman. Sure it’s visual garbage. Yes it impacts the semantics of your program. Yes it wastes memory. Who gives a crap? Those four things break you free of the borrow checker while also letting you get a grip on the language. The docs don’t advocate this approach. Presumably because they favour correctness and understanding over blind hacks. I get why the docs are the way they are but I don’t think it’s worth the blood sacrifice necessary to stay on Mr. Borrow Checker’s Wild Ride. Note that the above advice is no longer a 100% hammer-fits-all solution because futures and async and pin have unleashed brand new eldritch horrors upon us.
- ModernMech 4y ago> Those four things break you free of the borrow checker while also letting you get a grip on the language. Technically those methods don't break free of the borrow checker; they satisfy the borrow checker by not borrowing.
- deleted 4y ago[deleted]
- ncmncm 4y agoIn other words, do enormously more work, that will then have to be undone, just for lack of a build flag. Nice. Rust absolutely can still fizzle, and certainly will be found to have done, in time, without major improvements in adoption rate. If you have better ideas for that, propose those. The more the better. Spurious objections to ways to improve adoption favor other languages.
- indiv0 4y agoEh I wouldn’t say enormously. The latter two are hyper powerful but hyper rare because how often is a newbie using threads? The former two are just a method call you add to the offending line when the borrow checker complains, and not a moment sooner. It tells you what’s wrong, you fix it, you move on. It’s no different than forgetting a semicolon in Java. Nothing needs to be undone after. Either those 4 tools get you a valid program or you made a logic mistake you would’ve made in any other language. Or in Rust sans borrow checker. I don’t see how that’s an issue. I don’t see how my methods are spurious objections or how I’ve spuriously objected to anything. My methods are tested, tried, and proven to work on a sample of n=1. All that’s left is government funding and we can start mass human trials next month.
- Starlevel001 4y agoThe borrow checker is not hard. The difficulty is vastly overstated by web developers being told "no" to their shitty code for the first time in their life.
- ncmncm 4y agoThis is the "my leet lang is just for me, not for thee" argument. It is a sure route to there being no shops offering work coding in it. If that is your goal, you know how to get there. But you already are there.
- indiv0 4y agoYou’re completely correct, but I think GP’s point is that we need said web developers to chase fancy new framework Flask-Native-Redux-Rust Edition™ to keep momentum going for the language as whole. Which personally I think has some merit. Personally I think the understated way in which Rust now maintains a death grip on the WASM tool chain and tooling is the answer. Let the web devs have their JS. We can have everything `<canvas>` and below.
- ellen364 4y agoIn a strange way, the borrow checker is old fashioned. It seems like an experience described by older programmers, of punching programs into cards and waiting for time on the computer, when they’d finally know if their program worked. My few experiences with Rust made me realise that I’d become used to dropping into a Python shell to sort of explore and actually experience what was happening. Even in toy programs in Rust, I had to change my approach and also ensure I wrote one small, working chunk of code at a time. (Rather than roughly sketching out bigger sections, for example.) I quite liked it, but changing habits isn’t easy and now I’m wondering if maybe it will limit the wider adoption of Rust.
- kaba0 4y agoI could actually see it work by adding a new keyword/macro to a variable that effectively gives the needed lifetime to the variable everywhere it is used. It couldn’t be compiled to a release build but indeed there are cases where one wants a working prototype first.
- ByteJockey 4y ago> I particularly abhor Go style uppercase for public visibility and much prefer Rust's explicit syntax. I don't want to comment on Go's visibility here, but is it that much different than how in Rust the lack of a semi-colon means you're returning (or the presence of a semi-colon means it's an expression instead of a statement, which has tripped me up many more times than the inverse)?
- guitarbill 4y agoI suppose in a way it is. With the semi-colon, it's present or not. Whereas uppercase for export is kind of mixing information. The casing of identifiers is syntax, not just stylistic - but only the first character. Otherwise, it's just for readability (e.g. valueOf vs valueof). Which has interesting consequences, e.g. for non-ASCII identifiers where there is no concept of lower- or uppercase: https://go.dev/doc/faq#unicode_identifiers https://go.dev/doc/faq#unicode_identifiers Whether or not this bothers you is a different question.
- brundolf 4y agoI've wondered whether the lifetime elision that happens sometimes on functions could be translated to structs too. So eg. by default all references in a struct are assumed to have the same lifetime, without any annotations. If you need multiple lifetimes or more control, then you add explicit parameters. That would simplify a whole lot of basic uses Edit: Found some prior discussion here https://users.rust-lang.org/t/why-no-lifetime-elision-for-structs/8216 https://users.rust-lang.org/t/why-no-lifetime-elision-for-st...