Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I spent about the past month learning rust - and decided it just wasn't a usable language for me.

I think what it comes down to is that I'm just not that into bondage and discipline from a compiler. Yes, I know, it's trying to make my code 'safe', and I'm horribly cavalier and I should feel bad, but:

1. the borrow checker rejects valid programs, has a lot of corner cases it can't catch, and is in active development

2. people routinely write more inefficient code to satisfy it

3. people routinely freak out about 'unsafe', which is a bit much given the first point

Anyway, YMMV. Maybe you're smarter than me, or rust fits your mindset better, or you enjoy asking for help on discord all day, but I am so glad not be using it anymore.



Just curious, what was your programming background. Have you used C++ a lot especially “modern C++”?

I find that as a C++ programmer, Rust encodes in the compiler a lot of best practices about ownership and memory management. Using Rust is a breath of fresh air in not having to worry about dangling references.

From experience programming C++, I can see what the error messages are trying to prevent and why it is important.

However, if your experience was primarily with managed/garbage collected languages, a lot of the Rust compiler pedantry is stuff that you never had to worry about to being with and you have never experienced the pain it is trying to prevent.


I had a stint as a C++14 programmer, and I switched over to C++20 for this project.

You covered the downsides pretty well, big upsides for C++:

- ability to use C libraries directly - and thus original C API docs. I've got battlescars from NPMs deep dependency trees, and cargo is a similar story.

- I don't need the (very patient and knowledgeable!) people on rust discord to hold my hand every day. There's a stackoverflow for almost every C++ issue.

- that 5% edge case where the codes safe but the borrow checker isn't happy I can just write. No RefCell or nightly compiler.


Of course you will also write the 5% edge case where you've wrongly convinced yourself that it's fine. In general the sort of self-discipline that would likely ensure this doesn't happen also satisfies the borrow checker which might be why some people find this not a problem and others really struggle. Worth somebody studying perhaps.


I think that's a big philosophical difference I have with the rust culture - static analysis is a tool, not a religion. Useful, but nowhere near enough by itself to make reliable software.


> ability to use C libraries directly - and thus original C API docs. I've got battlescars from NPMs deep dependency trees, and cargo is a similar story.

This is something Rust is relatively good at, you just may need some unsafe blocks, but assuming you can compile using clang for the C code everything tends to work well. I am saying this as a Rust skeptic.


Agree with this wholeheartedly.. I was a hardcore c++ dev by day for 7 years straight and picking up rust was like the best thing I ever did. If anything it made me a much better c++ programmer by the end.


> 3. people routinely freak out about 'unsafe', which is a bit much given the first point [borrow checker]

It sounds like you're making a common misconception here. unsafe code and the borrow checker are not closely related, and unsafe blocks are not a way to play fast and loose with ownership issues. See https://steveklabnik.com/writing/you-can-t-turn-off-the-borr...

If you don't want to deal with the borrow checker, the solution isn't unsafe, it's Arc, Clone, RefCell, etc.


You can unsafe to get around the borrow checker, just not directly; you have to go through raw pointers.


> I spent about the past month learning rust

This is a red flag for your complains: Is VERY likely you believe Rust is wrong, when the fact the problem is that your code is not good.

I know this, my first 3 months starting Rust were thinking between "I'm a failure as developer" and "Rust is wrong" or "What? Why can't do this?". For first time after learning more than 12 languages I was truly in shock. And even, for second time in 20 years, picking a book and PAYING attention to it.

THE major problem with Rust is not, not even close, the borrow checker or that is picky. Is that Rust idioms are not OO idioms, not C/C++ idioms, not PHP idioms, no Java idioms.

Is fairly a simple language, actually, and the productivity is very high (today I code in Rust faster than python, that is still my benchmark on productivity).

What is NOT simple, is that it require several things to "click" and align properly to make the journey smooth.

And that it reveals how much other langs hide for your.

P.D: The problem you say, sometimes are true, but only at first, when the people are not fluent on the lang, or later, when doing seriously advanced stuff.

Not think I bashing you. This experience is common for many in the community, and even very strong developer get the weird experience with Rust. But also is true that when Rust "click" is very, very good!

P.D.2: I bet Rust is much harder the more experience a developer is and the more ingrained some ways are. I teach Rust to some newbies, and the experience for them is far smother.


> This is a red flag for your complains: Is VERY likely you believe Rust is wrong, when the fact the problem is that your code is not good.

I'm gonna be blunt: This is the worst thing to come out of the Rust community, bar none. Rust is a fine language and I love to write in it, but I loathe the way Rust developers have convinced themselves that Rust is an axiomatically 'better' language and that the things you can't do in Rust, or the things that are painful to do in Rust, are a perfect circle venn-diagram overlap with the things that are just bad to do in general. It's a mindset that shuts down discussion and constantly shifts goalposts. It doesn't help anyone.


Maybe you can rewrite his statement as "your code is not idiomatic to Rust"?


shrugs

Who knows, maybe rust clicking for me was just around the corner. I kept thinking "finally I'm understand this" and then something else would happen.

I'll leave it to the incredibly patient programmers who can spend 3 months just learning it. I'll use all the time I save to write more tests, and probably end up with something much more correct.


Probably not, I am afraid.

After all, you are human, and we humans aren't good at exhaustive covering of all bases. Sometimes when I am reading a rust compiler error message about erroneous borrowing I really wonder that I never could have thought about that corner case.

It's true. Sometimes Rust compiler's pedantry is just not neccessary. Then write Python, TypeScript, Ruby or in Rust box, arc and clone everything.


> I'll leave it to the incredibly patient programmers who can spend 3 months just learning it.

I understand, I was close to drop it.

In retrospect, I create a lot of self-inflicting problems in my journey (like I learn Rust making a programming language and hit by coincidence some of the hard stuff with Rust!) and knowing what I know now, Is clear the time running in circles was in big part that.

But, of course, is hard to see you are running in circles when you are running in circles :(


> has a lot of corner cases it can't catch

The instances of safe code that the borrow checker can't verify as such are not "corner cases" by and large, they're genuinely non-trivial patterns, often with non-obvious drawbacks such as lack of composability/modularity. Rust devs and researchers are working on better abstractions to support those cases, but these are very much the exception, not the rule.

> people routinely write more inefficient code to satisfy it

People should stop freaking out about this. The "more inefficient code" you might get by adding a few .clone() or Rc<RefCell<…>> when the borrow checker complains about something is still way more efficient than anything written in alternative "safe" languages.

The "slow" solutions are a bit noisy but that's a good thing, since it tells you where it might be worthwhile to either refactor for efficiency or document why a refactor isn't feasible.


> The instances of safe code that the borrow checker can't verify as such are not "corner cases" by and large, they're genuinely non-trivial patterns, often with non-obvious drawbacks such as lack of composability/modularity.

Unfortunately, the borrow checker can't handle a basic observer without falling back to patterns that violate encapsulation. The observer pattern is one of the best patterns for composability/modularity, and I find that the borrow-checker-compliant solutions are more complex and don't solve anything but rather move problems somewhere else.

It's cases like these that make me appreciate Rust's wisdom of adding Rc<RefCell<T>>.


>People should stop freaking out about this. The "more inefficient code" you might get by adding a few .clone() or Rc<RefCell<…>> when the borrow checker complains about something is still way more efficient than anything written in alternative "safe" languages.

But you don't have to use a "safe language". C++ can avoid a lot of copies and be just as safe from an absolute point of view. The borrow checker isn't god and Rust isn't perfect. In an absolute sense the C++ code you can write could be more correct and efficient(it just doesn't tend to be).


You can always just go down the UnsafeCell/pointers way and will still be safer than C++ as the borrow checker still works for inside unsafe, and that the few places where a memory error can lurk will be highlighted by unsafe blocks.


> the borrow checker rejects valid programs

That's Godel's incompleteness theorem for you. Every static type checker also rejects valid programs, but that doesn't make them any less useful. Just one of those inconvenient facts about our universe.


I think it's more of a Rice's theorem/ halting problem issue than an incompleteness theorem issue.


> the borrow checker rejects valid programs

Yup, this is the tradeoff you have to make to catch the wide variety of bugs. For personal use, probably not worthwhile, but it definitely pays off for the safety it provides in production contexts.

The way I view Rust's philosophy is "it's better to catch bugs at the compile stage than at the execution stage".


One charitable way to view Rust's philosophy is that it's better to catch bugs at the compile stage than at the execution stage.

In theory yes. In practice, getting to the execution stage was such a slog that it rarely happened.

Would have liked it a lot better if the borrow checker had the option to be -Wall instead of -Werror.


Out of curiosity, what are your preferred language(s) to write in, and what sort of software were you trying to write?

> Would have liked it a lot better if the borrow checker had the option to be -Wall instead of -Werror.

Wouldn’t this defeat the purpose of the borrow checker and remove the guarantees the language gives you?


Most enjoyable languages for me are definitely GC'd (JS, TS, Ocaml, Ruby). But I have professional C++ experience.

The software is a layer over an in-process key value store written in C (LMDB).


That's been every language's philosophy for generations. (Obviously, some languages do a better job of it than others).


Not really? Python's dynamic typing and lack of variable declarations clearly shows it was designed for developer velocity, not catching bugs.

Seems like your argument is Python catches some bugs when converting to bytecode, so it cares about catching bugs early. That's not true -- for the most part, Python catches only the most trivial of typos before execution.


I agree with this. My experience was that the learning curve for Rust has a huge kink in it right where the borrow checker is.

Type checkers provide tools that make it comparatively easier to ignore when they could be wrong or are getting in the way. To do something in a type-safe manner often doesn’t require re-abstracting behavior.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: