Making rust easy to learn and use

Honestly, after quite a bit of time playing with Rust and being currently in the process of launching my own Rust-build server into production, I begin to feel that the "steep learning curve" is only a problem for those, who don't need Rust in the first place. The following would be elaborations of that same thought.

  • Ownership and Borrowing aren't hard, and the Borrow Checker isn't there to make your life worse.

    Your program - running on a physical, virtual, or Docker-based machine - on the most basic level, does only two things. It plays with data (which requires a processor) and it stores this data (which needs some memory). To be useful, your program will also need to handle transfers of this data, but that's a separate topic. You can think of data transfers as reading from, and writing to, a memory which isn't "yours". Whenever you program, in essence, you play and you store. That's it.

    Whenever you play with any data, you have to: 1) initialize it ("allocate" some space from memory for your playing to take place), 2) play with it (process it however it needs to be processed, transfer it somewhere or fill the memory you've pre-allocated with the transferred data from some other place) and 3) clean it (by "dropping" it, "freeing" or "deallocating" the memory, or marking the sectors of the memory that were previously used by your data as usable once again for your OS - depending on how low you're willing to go from the highest possible abstractions). Nothing else.

    As you initialize, play and clean - you need to keep track of which data is being played with by which "player" (which on the basic level is represented by a function, but can be abstracted away by introducting classes, objects, etc). Why do you need that? Because if several "players" start initializing, playing with, and throwing away the same data, you get nasty problems.

    Your OS doesn't want your players to play with data that doesn't belong to them, your players - most likely - don't want to read or write to wrong parts of memory, thinking that your data is still there, and whenever you try to introduce parallel computations in your code, you don't want for those computations to come up with strange, unpredictable results, which can creep up quite suddenly if all you have at your disposal in a toolkit of the language like C.

    Sure, you can do the same things with it, and perhaps it will even be faster - as fewer safety checks, for which Rust is known for, won't be slowing you down, but the chances of you getting more and more things wrong (by accident and not) get closer and closer to 100% the bigger your program becomes. Segmentation faults, sudden crashes, security exploits, all the beautiful things that you and your users definitely expect will keep you company for a very long time.

    You can also abstract away as much as you possibly can. You can say that any data that ever gets played with by anyone should be sealed behind 10 locks and called an "object" - which is what languages like Python and JS do. Though much easier to pick up, this approach turns out to be quite a waste of resources and "dynamic" typing for which it's famous for also tends to incorporate some hidden unpleasant surprises into the behavior of your application without your explicit intent.

    Your third approach - is to pick up Rust. It'll tell you exactly which of three steps of your coding game are written in a way that can introduce some problems, and it'll force you to think about how you can rewrite / refactor / rethink your design to make sure nothing nasty happens.

    The concept of ownership and borrowing is the way this enforcement is done. Only one player "owns" the data that is playing played with at any moment in time (meaning: only one player is responsible for keeping this data in memory and throwing it away afterwards). Only one player can "mutably/exclusively borrow" it from the owner, gaining the right to modify this data however it wishes. And if no one has an exclusive access to this data, as described above, then as many other players as you want can "take a look" at this data ("immutably borrow" it) and do something with it, provided they don't change anything in the data (and the memory that holds it). That's it.

    "Do I really need this, though?" - if you'd like to drag yourself and whomever happens to be on the receiving end of your program's end through the thrill of unexpected glitches, crashes and exploits, or by providing them with a less performant, and perhaps harder to reason about, solution, perhaps not. Stick to C in the former case, and to JS / Python - in the latter.

    Otherwise, just dig a bit deeper, understand how your machine works, understand Rust's toolkit - and perhaps become a bit more capable and knowledgeable in the process, all the while making your code more stable, secure and performant.

  • There are tons of resources.

    From the official book, to Rust for Rustaceans, to Zero to Production, to Jon Gjengset's channel - if you want to learn Rust, you can. Can it be improved? Sure. Can someone do the hard work of organizing the material for you in order to simplify things further? That's unlikely. Rust's power lies in being able to go from the bare-metal to highest level of abstractions in web servers and clients. It's neither practical, nor reasonable, to compile one giant encyclopedia for "all things Rust" - because the people that use it differ radically in terms of their fields, interests and incentives.

  • There aren't enough mature libraries.

    This is the Rust's biggest trouble at the moment. We've gotten (you've gotten, guys - I'm just an observer, really) pretty far in terms of the ecosystem, but it's still fairly limited right now. Most libraries are yet to reach the stage of 1.0 - even the most used and important ones. Beginners often get extremely confused with similar alternatives to the same problem - tokio vs async-std, rocket vs actix-web, you name it. This is where the real problem lies, but only time will solve it.

    Wider adoption can help, but at this point anyone that could discover Rust already discovered it. People who aren't using it, even though they'd like to - mostly cite the lack of eco-maturity as the main reason why. Perhaps it would make sense to compile a list of the most requested libraries / guidelines / lacking crates from possible external adopters, and work towards the minimization of the amount of items on that list? - that would require someone posting weekly here and on reddit, asking for global community assistance, and not just "hey, we'd appreciate if you could help us here". Less "it would be nice" and more "we need this next" could really improve the situation.

    That would entail a bit more proactive, even slighly pushy approach - but if the increased speed of adoption is the goal, this is the best way to go, IMHO. That would actually make Rust easy to use - import the library X for Y, and you're done. As for the learning part, it's not that big of an issue. It might help for people to get a bit more clear as to why Rust's approach makes sense, instead of focusing so much on how to learn it. As the saying goes, those who have the will, find a way - otherwise, the whole learning tends to boil down to the question of "how do I trick the compiler into not screaming at me?" - which is as bad of an approach as it can possibly be.

11 Likes