Rust is too hard to learn

Why is it easier to write initial code in Rust that doesn't compile than one that compiles? Don't you think the language needs simplification? It is okay that the purpose is to make everything very explicit for the programmer, but this is a very heavy burden when starting with language.

Initially, Rust is easy, but as soon as you are introduced to "LIFETIME HELL" everything becomes unpleasant. There are hours and hours spent trying to understand what the cryptographic message of the compiler means and in the end the code insists on not compiling with new mysterious errors. I already gave up and tried again several times. The language is very good for agile development but lifetime hell is an obstacle that is difficult to overcome.

3 Likes

The Rust compiler checks for more bugs than the compilers/interpreters of other languages do. This lets you be more confident that compiled code is correct. It also means that buggy code you’d expect to compile in other languages (to be fixed later) will be rejected by the Rust compiler.

If you were to measure the effort to get a fully working and debugged program instead of just a compiled one, I suspect Rust would be comparable to or better than other languages.

13 Likes

Sorry, I didn't explain my problem, I edited the post

It is hard to learn, indeed. Rust is trying to lower the learning curve though teaching materials and good compiler errors (if you think these errors are bad — they have been much worse!). Some of the core concepts around ownership are just tricky to learn, but required for the language to work.

Some of the strictness is intentional. Rust doesn't want to let you compile invalid programs. It tries to catch mistakes at compile time, rather than at run time. In other languages you can easily run any code, but then you get crashes/exceptions/"undefined is not a function" when it's incorrect. The strictness may be hard when you start with a small program, but it usually pays off in larger/more complex projects.

18 Likes

In my eyes, the strictness of the compiler is one of Rust's most important features, because the compiler is extremely good at catching my mistakes, meaning that the resulting application is much more robust than anything I would be able to write in any other language.

I encourage you to ask questions here regarding the lifetime challenges you are running into, and we would be happy to point you in the right direction.

28 Likes

This may not be exactly what you are asking, but one Rust feature that I find very useful when writing initial code is the todo!() macro. That allows you to define and compile a function without having to worry about how the return type is constructed. Of course function will panic at runtime, but it's a useful way to get everything compiling when you are starting out.

6 Likes

If you're in lifetime hell, then you probably have references in structs. As @kornel says, that's an advanced feature that you should use only after you are comfortable with other aspects of the language.

7 Likes

That is a good question. For example it is much easier to write code in C or C++ that compiles. Back in the day I swear a C compiler would happily compile any random input I gave it. On the other hand it is hard to get an Ada prom to compile. The down side of the "easy to get anything ti compile" approach is that it is then easy to create programs that silently produce wrong results at random and/or crash in mysterious ways. Which is often amazingly hard to debug and very expensive if discovered after the product is shipped.

That thought has often crossed my mind. However I have yet to see better ways to do what it does and provide the safety/correctness guarantees it does. Do you have suggestions?

I agree that Rust does demand one puts some effort into learning it's in's and outs when getting started. A steep learning curve as they say. On the other hand I would claim that it is not so bad. Im not the brightest star in the programming world but I managed to start getting code into production after a few weeks.

I would also argue that putting that effort in is a very good investment in ones understanding of programming, which will help one write better code in other languages.

This is true. The simple way around that is don't get into "lifetime hell". At least not when starting out. In my first year of Rust I don't recall there is even one lifetime notation in all the code I have running in production today. In fact as soon as I feel the need for a tick mark I back off and reconsider what I'm doing. Lifetime hell can be avoided easily enough with Rusts "smart pointers", recel/arc etc. The use of clone helps. And basically one just has to arrange ones code and data such that lifetimes is not an issue. Avoid putting reference in structs for example.

I'm not sure what to make of that. I find Rust's compiler error messages some of the most helpful of any language I have ever used.

I suggest, stick with it. It's worth the effort in the end.

What I would like to see is some drop dead simple guide for Rust beginners, that eases them around these pain points. I'm sure that is possible.

11 Likes

Rust wasn't hard to learn for me. This is subjective, and as such, I deeply despise blanket "hard to learn" statements.

Maybe it's not a great first language? You have to know what you are doing in order to write Rust. You have to understand memory models, know typical implementations of common data structures, you have to be familiar with terminology around concurrency and parallelism, and it doesn't hurt to have intermediate-level experience with C++ in order to understand RAII, and the same with an ML-family language like Haskell in order to grasp the type system and pattern matching. If you have just wrapped your head around the concept of types or indirection, maybe you don't want to jump into Rust just yet.

There's also the fact that Rust calls you out on all sorts of sloppiness, something that most mainstream languages let you get away with. Except that said languages don't actually make your life easier by accepting sloppy code. You'll pay the price later, when you spend sleepless Friday nights trying to debug mysterious memory management problems and null pointer exceptions.

In other words, Rust in and unto itself is not hard. If anything, it's producing correct programs that is hard.

18 Likes

Well yes, rust is challenging to learn, I've been fiddling with it for the better part of 3 years now and i'm finally getting comfortable with it.

The biggest challenge (and yet superpower!) is indeed the compiler (and/or borrowchecker) telling you you're doing it wrong.. And it takes time to actually accept that well.. you're doing it wrong! :slight_smile:

Writing applications in rust requires a pretty different approach than what i was used to in java But after some time i came to realise that it's actually a good thing! I absolutely prefer coding in rust over java now, and yes it took some time and yes I gave up at least 10 times but in the end it was all worth it!

So yeah, I would absolutely recommend you to try again, fail again, learn from your mistakes and keep going!

6 Likes

Yes, the learning curve is steep. I think it is important to realize that is it not enough (at least for most of us; I belong to most of us) just to program. IMHO, it is vitally important to deal explicitly with

  • ownership and borrowing
  • error handling
  • lifetime

One source for free which is dealing with this areas is: The Rust Programming Language - The Rust Programming Language .

Actually, when I started I was amazed that despite the problems I had with specifically ownership, borrowing and lifetime I was able to get a command line app running. But as said it pays if you work thru the Rust Programming Language.

Don't forget: when the compiler is happy you are also mostly happy because your programm works most probably ok with the exception of possible logic error and the like.

It's a funny thing about that "lifetime hell".

Lifetime hell exists in every compiled, "systems programming", language I have ever used: PL/M, Coral, Pascal, C, C++ even Ada.

The important difference with Rust is that one finds out about lifetime problems at compile time rather than at run time. As many have noted it is much easier and cheaper to fix such problems when one is writing the code, at compile time, than when random failures start being reported by users, at which point they can be very hard to diagnose and fix.

In this way we see that Rust is actually doing a very good job of saving one from lifetime hell.

I would argue that Rust could well be a suitable first or perhaps second language for those new to programming. Rust's lifetime hell is much easier to deal with in the long run than those languages I listed above.

I also think this because when I was first introduced to programming it was with BASIC, which at least made us aware of what a program even was. Variables, expressions, conditionals loops etc. But in that same course we were soon expected to handle assembly language. In the modern world that would be like taking a beginner from Python to Rust in a couple of months.

Cannot be so hard can it?

11 Likes

Yes I think it's hard
No I don't think it NEEDS to be simplified, because they are already trying to simplify it as much they already can while not sacrificing rust's features.

How much is your current experience with rust? Maybe you're going too fast. I personally do not consider myself any expert on lifetimes, yet I can get plenty done without worrying about them. I would suggest not trying to deal with lifetimes in early stages.

P.S. Ask OZ for help :sweat_smile:

1 Like

Regarding "maybe not a great first language?", I have a strong suspicion that Rust might actually be more approachable as a first language than as a second one. People (myself included) get into mental ruts. Especially after you've learned a couple languages that all do things more or less the same way, switching gears can be a challenge of its own, whereas if you come to Rust with few preconceptions and are introduced to it one concept at a time, the way you might be in a typical introductory programming class, it's not much more complicated than Java, and less complicated than C++ or Python, in some ways.

That said, different people find different things challenging, as anyone who's been on this board for long will know. Some people pick up lifetimes fairly quickly but struggle to design programs without using class inheritance. Some people are just the opposite. Some people have to wrestle with each concept that other people just intuitively understand.

@rafaelcout, if what you're dealing with is "lifetime hell", it's probably because you're using references where they're not necessary or appropriate. People who are new to Rust often overuse references because they haven't understood the semantic differences between owning and borrowing a value, or haven't designed their program with ownership in mind (both things you should do in any language, by the way; Rust didn't invent the concept of ownership, and in some ways it's even more important in languages like C++ that have no compiler guardrails).

If you're comfortable sharing the code, many of us would be willing to take a look at it. There's a good chance the design can be simplified to reduce and avoid lifetime problems.

5 Likes

Fair enough – I was only wondering that because I usually see people struggle with Rust due to not understanding explanations that build on background knowledge common to Rust and other languages.

That said, the "mental rut" is absolutely a realistic problem, so I guess it boils down to the trade-off between the two.

2 Likes

Yeah, I mean, I'm mostly just speculating. I don't know of any courses/books that teach Rust to complete beginners (along the lines of Head First Whatever, Learn You a Haskell, etc.) and I don't know any programmers who have learned that way, so I don't even have anecdotal evidence to support the theory.

1 Like

I was just wondering about that. As in "what is that background knowledge?"

Much of understanding Rust is basically all about memory. What is the stack? What is the heap? Where is everything? Simple things like a String being both a structure on the stack and the actual string content on the heap.

The background knowledge then is how our processors actually work, how they work with memory, how functions become actual code and how that code refers to memory.

Harking back to my early days that background knowledge came by way of the fact that I was following a "computer science" course, all be it at a kind of high school level. We were made aware of how processors worked, instructions, memory, ALUs etc. All be it in a very simplified way.

Seems to me many programers today, having only been exposed to Java, JS, Python etc, have never been aware of such computer mechanics.

8 Likes

Stick with it. Lifetimes are a new paradigm if you're coming from languages like C, C++, Java, Python, etc. It will eventually "click" for you after more practice. It was difficult for me to grasp too. I simply avoided putting references in my structs for the first 6 months of learning the language because I just didn't get it.

One thing that helped me start using lifetime specifiers correctly was to give them meaningful names instead of the standard 'a, 'b, etc. For example, instead of doing this:

struct MyStruct<'a, 'b> {
    credentials: &'a Credentials,
    cookie: &'b Cookie,
}

I started doing it like this:

struct MyStruct<'credentials, 'cookie> {
    credentials: &'credentials Credentials,
    cookie: &'cookie Cookie,
}

Doing it this way helped me understand that the lifetime specifier is tied to the thing it is referencing. 'credentials is the lifetime of the struct that the reference credentials points to.

9 Likes

I'll add my vote for the compiler and borrow checker being a feature of Rust that I've finally come to appreciate. Also, learning Rust as a second full language was great, but only once I realized I needed to break all my assumptions about programming down to basics to figure out how to write things correctly. I'm starting to think of the compiler and borrow checker as training wheels for writing correct code, which I'm trying to end up relying on less and less. While they can definitely feel like a wall, you just have to find the doors.

8 Likes

Interesting. I learned Rust without ever thinking about the stack and heap. What slowed me down was thinking the borrow checker was all about data races. Things fell into place once I realized it was all about memory management.

5 Likes