Settings

Theme

Rust – What made it “click” for me (Ownership and memory internals)

deavid.wordpress.com

79 points by shortj 3 years ago · 75 comments

Reader

DarkNova6 3 years ago

> As said earlier, C++ developers have an advantage on understanding Rust because they have a mental model of what the memory looks like, pointers and so on

The immeasurable success of Rust certainly lies in its clear communication and forcing developers to learn about the basics of hardware.

I can't help but to feel validated in thinking that every developer worth its salt should know about these basics anyway. But I have to admit that not everybody comes with a CS background.

  • vsnf 3 years ago

    > not everybody comes with a CS background.

    Something doesn't sit quite right with me to describe the "basics of hardware" as being something that comes with a "CS background".

    I come from a formal CS background, and we spent more time dealing with finite state automatons, programming language theory, and other aspects of abstract computation. Getting down and dirty with data sizes, system components, and bit fiddling was an available, but optional path. We all spent one or two courses dealing with the practical nature of computers, but it was largely drowned out by theory, at least in my program.

    • josephg 3 years ago

      I have a funny relationship with this. I also come from a formal CS background too. The old joke is that there are two lies in Computer Science: firstly its not science, and secondly it isn't really about computers.

      But the reality is, I still can't tell you what Computer Science actually is. Is it:

      - About understanding how to control computers (which are fast electronic machines)

      - About inventing programming, from the ground up. (A weird sub-discipline of mathematics and category theory)

      or

      - Learning to make software in order to improves the lives of humans

      We sort of need to learn all three aspects. Haskell programs run slower than C++ programs because haskell isn't written in harmony with the physical CPU cores we've made. Making fast programs is pointless if our software doesn't solve user needs. And solving user needs are impossible if we can't express ourselves clearly to the computer - which programming language theorists are obsessed with.

      I think the basics of hardware is part of CS, but maybe a CS undergraduate degree doesn't give anyone enough time to really go broad in the field. I dunno!

      • zonotope 3 years ago

        > About understanding how to control computers (which are fast electronic machines)

        Computer Systems Engineering

        > About inventing programming, from the ground up. (A weird sub-discipline of mathematics and category theory)

        Computer Science

        > Learning to make software in order to improves the lives of humans

        Software Engineering

        • josephg 3 years ago

          I mean, I hear what you're saying - but all of those things also seem to be a single discipline.

          Otherwise, where do operating systems fall? Are they systems engineering? They don't seem to be entirely about the hardware to me, and they were a core part of my CS program. What about SeL4 - which is a formally verified operating system project?

          How about programming languages like C or Rust? Is that computer science, or systems engineering? How about Excel - the world's most popular programming language - that happens to be functional? Are financial planners doing computer science when they program a spreadsheet?

          The lines are blurry everywhere. My CS program offered 3 different degrees, like you said - Computer engineering, Computer Science and Software Engineering. The only difference was the CS degree had a lot of electives, and the other two filled those electives in with (different) required subjects.

          Maybe CS is just "lets play with some cool things on computers!". And there's a big playpen of things to explore. Thats more or less how it feels to me.

          • saurik 3 years ago

            The lines between these majors definitely blur and some of the required courses do overlap; yet, they are still separate majors, the same way that the many specific sub-disciplines of biology are separate majors despite also having blurry overlap.

      • linhvn 3 years ago

        Computer Science is not about learning to make software, although it is usually a byproduct, as strong understanding of fundamental allows you to design software correctly from the first principle. Programming; however, is usually done through training at work.

        Computer Science is about understanding what computation can and cannot achieve, and more importantly, how to achieve it (that is where it differs from Mathematics, where mathematicians are usually not interested in the how part). Under this definition, we can put typical college subjects into consideration:

        * Data Structures and Algorithms: about studying how to manipulate data to solve a task efficiently.

        * Complexity Theory: about formal classification of hardness of problems. What makes a computational problem "hard" or "easy"?

        * Computer System: about how to construct a software system to achieve certain purposes. What are the constraints in a system (performance, security, privacy, correctness, fault tolerance, etc), and how to design a system to address such constraints? What tradeoffs to be made when you cannot meet all the desired requirements?

        * Distributed System: how to design system with a few to massive number of computers that are connected in a network? How do you reason about fault tolerance, consistency, sharding, and so on?

        * Operating System: about how to create abstraction to the hardware, that allows for other softwares to interact with it without having to explicitly deal with the hardware?

        The list could go on, but I just give a couple of examples.

      • ihatepython 3 years ago

        - Learning to make software in order to improves the lives of humans

        This is not a discipline that I am aware of

        - Learning to make software in order to make the lives of humans miserable

        This is a discipline, but not quite Computer Science

        - Learning to make software so that great engineers become average engineers, and incompetent engineers become managers

        This is software engineering

      • jltsiren 3 years ago

        There is also the part of CS that could be described as the science of computation.

        The lines between academic fields are primarily administrative. Their main purpose is to facilitate undergraduate education. They are also fuzzy and vary between institutions. A person working in a CS department could find their home in the mathematics department at another university. Or physics. Or economics. Or biology. Or somewhere else. No matter what CS was at your university, it can be something very different at another.

  • sshine 3 years ago

    I know the basics.

    But manually managing memory lifetimes you only learn from a lot of exposure to C/asm.

    In my first 3 months of Rust, I spent an equal amount of time with the type-checker and the borrow-checker. A year in and I don’t really have a separate phase of resolving borrow-check errors before I can compile.

    People with more C exposure tend to think that way already.

    • kaba0 3 years ago

      > But manually managing memory lifetimes you only learn from a lot of exposure to C/asm

      Why C? It is not any lower than Rust, one might even argue that Rust is lower-level than C due to it having control over SIMD and the like without non-portable compiler extensions.

  • jeremychone 3 years ago

    Agree. The problem is that languages like Java, C#, ... are making it so easy not to worry about memory that we (at least I) tend to forget the basics after a decade or so. And the basics have mostly stayed the same.

    • imron 3 years ago

      You still end up worrying about memory eventually, and the solution will often be to purchase more memory - which can be a fine tradeoff to make at times.

  • FpUser 3 years ago

    I'd learned "basics of hardware" by programming old CPUs and MCUs in assembly and machine codes. No I did not have CS background. Masters in Physics instead.

    Memory management in C was too high level at that time ;)

  • Thaxll 3 years ago

    I don't see how understanding pointers and memory layout help at all with borrowing concepts.

    • aparsons 3 years ago

      They don't. They're fairly orthogonal concepts. You can have a concept of lifetimes without memory management (for example, the object changes state while you have a reference to it).

    • voidhorse 3 years ago

      It provides historical context. Someone coming from a gc langage that has never even had to learn what memory even is wrt to a program will not understand why a borrow checker is even a thing.

      You can get very far writing software without even being aware that your language is even doing something called garbage collection for you, or without even having a basic concept of memory being tied to values, sizes, etc. If you lack this context a borrow checker just seems like a pointless nuisance.

    • matthews2 3 years ago

      If you are writing C or C++ and aren't thinking about ownership and lifetimes, you have either statically allocated everything or you are doing it wrong.

  • ReflectedImage 3 years ago

    I'm not so sure that C++ gives an advantage. It's a different paradigm.

    • imron 3 years ago

      If you’re a safe c++ programmer who never writes code that has memory errors, you need to be tracking ownership and lifetimes.

      Once you get your head around the borrow checker, Rust takes a lot of that cognitive load off you, by tracking things for you at compile time and dinging you on it if you get something wrong.

      • ReflectedImage 3 years ago

        Rust imposes a lot more constraints than just what is needed to make it safe. It imposes constraints to make it provably safe according to Rust's internal theorem prover.

        I'm not convinced Rust & C++ have as much in common as you think. Rust is really familar to OCaml or Haskell users.

        • kaba0 3 years ago

          Rust is literally C++’s RAII made into a compiler-checked concept.

  • 2h 3 years ago

    > its salt

    their salt

voidhorse 3 years ago

Personally, I'd recommend learning C to learn about the basics of memory management in higher level languages in general. It is simpler than Rust and is very transparent, making it easier to grok the concepts before moving on to something like the borrow checker, further more, it will actually make the motivations for the borrow checker and what it does to help clear. Same goes for other memory management solutions, gc, reference counting, etc. So much of what we do is still bound to a deeply entrenched model that C established.

Ultimately we are all still just writing nicer versions of C. The fundamental model of pretty much all high level languages remains the same. You can still explain and think about the vast majority of memory related goings-on in a program as using the basic abstraction of the pointer and contiguous arrays of bytes. Even languages that have different paradigms, be they functional, logical, or object oriented can be described in terms of pointers--one easy way to understand pretty much every other programming language paradigm is basically just to ask "how would I implement this using pointers?". It's a shared history and approach to computing we have yet to move on from.

  • warabe 3 years ago

    I started learning some Rust, just begging of this yeae, and I am starting to think learning C might be the shortest path to fully understand the motivation of ownership model.

    But at the same time, I don't want to invest so much time into learning a language which I probably am not going to use.

    I am probably being disrespectful. I understand a lot of people use C, including Linux kernel devs, but I cannot imagine developing new apps with an old language such as C.

    • voidhorse 3 years ago

      Not wanting to invest time makes sense, but I think you'll definitely get return on investment by learning C. It's doesn't end with rust. Learning C's approach to memory will give you a much better understanding of pretty much all object oriented and imperative languages and give you a better understanding about how memory might be used under the hood in higher level languages in general.

      It won't take you too long either! Compared to modern languages, C is very small and very simple and likely won't take as long as learning any other popular language in use today. You can learn all of C in the amount of time it takes most people to learn just the basics of a borrow checker. If you only focus on the aspects related to memory (stack, heap, sizing, arrays, pointers) it would likely only take half a day, if that.

      • warabe 3 years ago

        Yeah, haste makes waste. I will give it a shot! Thanks for the tips!

    • lozenge 3 years ago

      Are you not interested in contributing to existing projects like Postgres, CPython... or being able to use the many libraries with C APIs?

      • warabe 3 years ago

        Well, that sounds exciting, but I am a novice programmer from data science field. So, I am more like a user, rather than a developer.

        Contributing to world class projects such as Postgres sounds cool, but doesn't it take years of experience?

        Of course there are other benefit of learning C as you noted.

  • DarkNova6 3 years ago

    I second this 100%. In the first semester of my CS degree we were only programming in C and it helped so much to understand the basics of memory. Heap, Stack, Pointers are crucial mental models which help you in nearly all programming languages.

    If you are responsible for your own memory, it makes you more aware of issues such as indirection and cyclic dependencies.

  • Georgelemental 3 years ago

    This is the path I took, and recommend. The borrow checker and Rust's restrictions are easier to understand once you have experienced doing it manually. And the basics of C89 don't take that long to learn!

Waterluvian 3 years ago

Today I had a moment with TypeScript where I got an error because a class property wasn’t definitely initialized in the constructor.

I thought, “I wish there was a way to prove to the compiler that it will be there when I access it, rather than having to tell it to trust me.”

And that’s when lifetimes in Rust really clicked for me. I know it’s not exactly the same thing but the value of describing the valid lifetime of a thing at compile time began making a lot more sense.

l0b0 3 years ago

> As a rule of thumb, if you don’t want the function to consume the data (to free it), don’t ask for ownership.

As a Rust beginner, that's a handy thing to remember! Thinking of variable passing in terms of least privilege seems much better than just trying to use the simplest syntax (changing ownership by passing the variable rather than a pointer to it) all the time.

the_arcadian 3 years ago

> Ideally, you don’t want to make a self-referential struct in Rust. Instead you should leverage other types to accomplish the same thing; for example Rc<T> can be used for things like linked-lists or trees. Also, have a look for libraries that might do this work for you, as these are very easy to do wrong.

LOL, sure borrow-checked reference counted pointers that can't equal null to mark the beginning or end of a chain are exactly what I am looking for when I want to build a linked list or tree. Why are you like this, Rust?

j16sdiz 3 years ago

The author explained the ownership and move semantics, but NOT why it "click" for him/her.

I understand what the claims advantages of Rust are, but I can't understand those cult-like passions.

marcodiego 3 years ago

The example:

  This does not work in Rust. But the counterpart in C kind of does:
    int &p_a = 0x100;
    int a = \*p_a;
Is not valid C.
2h 3 years ago

> let mem: Vec<u8> = vec![0; 18_000_000_000_000_000_000];

probably dont want to actually use that code...

andrewstuart 3 years ago

Grrrrr.....

let a: String = "Hello world".to_string();

  • lytedev 3 years ago

    But this allocates a new string instead of being a slice to the data in the binary in memory loaded by the os, doesn't it?

ilrwbwrkhv 3 years ago

I wished rust looked less ugly. It sounds like a fascinating language. But swift seems so much more beautiful. Rust imo seems the ugliest of the recent languages.

kazinator 3 years ago

Ownership is a time-wasting idea; an object should be freely able to go anywhere in the program you need it to go without any concerns.

  • c3534l 3 years ago

    Problem is, it can't go where you need it to go without any concerns. There are problems doing that whether you ignore them or not. I should be able to plug whatever I want into an electrical socket and not have to worry about whether it'll start a fire, but I can't.

    • kazinator 3 years ago

      This is a solved problem. There are situations when the solutions don't work, but they are subject to the 90/10 rule. Or 99/1 or whatever is applicable.

      There are almost no application domains in which you need to conform to some insane borrowing protocol for the entire software.

      Your analogy is stupid beyond belief; and terms of the safety of the circuit itself that is behind the outlet, yes I can plug in anything without worrying there will be a fire in the wall. I live in the first world, where we have electrical codes and circuit breakers.

      • felurx 3 years ago

        I think there might be a misunderstanding here: The analogy works precisely in that you can't plug in anything dangerous because the electrical codes make it so that dangerous things don't exist, and because circuit breakers protect you from malfunctioning stuff.

        You can't plug a device that pulls 10kW into a plug and have it work, because the circuit breaker stops you from overloading your circuits. You can't plug in a device that attaches the live to your left hand and the neutral to your right, immediately stopping your heart, because such a device is forbidden by electrical codes, and everyone who makes electrical devices has to follow these.

        • kazinator 3 years ago

          Are you saying that memory management under which I can confidently any object anywhere in the program without any puerile borrowing protocols isn't safe?

          Or, else, what is your point?

          • 112233 3 years ago

            Yes it is not safe. Just because you do not access undefined memory in an untyped GC language like javascript or python does not mean you can enforce that program invariants are maintained. You still get resource leaks, races, corruption etc. just without a crash (which makes it arguably worse because the defect is not immedeately apparent) Encoding program invariants cannot have "correct" solution, because you must balance expressivenes with compile time decidability.

            • kaba0 3 years ago

              Both JS and python are safe from races and corruption, unless you very explicitly go out of your way. JS has no parallelism, and python has the GIL.

              Leaks are not a security concern (besides DOS attacks).

          • felurx 3 years ago

            I'm not saying that borrowing protocols are the _only_ way to get memory-safe programs. But aside from that, yes exactly. How memory management in C/C++/... works is not inherently safe, otherwise we wouldn't have all the memory-related bugs we have. Of course, you can write memory-safe code, but adherence to borrowing protocols can guarantee that your code is memory-safe, or at least reduce the risk by a lot.

        • SAI_Peregrinus 3 years ago

          The latter device is very easy to make with a power cord and some wire cutters & strippers though.

          • felurx 3 years ago

            And you can use `unsafe` in Rust, code up all sorts of memory-unsafe stuff and have it blow up in your face.

            In both cases, it should be clear to you that you are behaving in a possibly dangerous manner, that you should know what you're doing and that you are responsible for not endangering others with whatever you're doing.

            • kazinator 3 years ago

              In a sane language, you can hook up objects in a graph structure with cycles and pass the whole thing (or any portion thereof) wherever you want without having to abandon safety.

              Making safe things unsafe: rusterfuck.

    • eyelidlessness 3 years ago

      You put this better than I did.

  • eyelidlessness 3 years ago

    A new conception of software freedom: free from the constraints or considerations of reality. Where it’s not the code that’s unsafe, it’s the thinking about and addressing its safety that’s harmful. Kill your gods but don’t let the compiler ever figure it out!

    • kazinator 3 years ago

      Criticize Rust and here comes god talk in 3... 2... 1....

      • eyelidlessness 3 years ago

        Lol I’m not a Rustacean, I’m amazed I’ve gotten any Rust to even compile some of the times I’ve tried. I was riffing on probably poorly fit sayings, but definitely not as a Rust partisan.

  • josephg 3 years ago

    Ownership sure saves a lot of time for the computer when it runs the final binary.

    For some software (eg browsers, operating systems), time spent making our programs correct and fast is worth the effort.

    • kazinator 3 years ago

      Ownership is completely inadequate for operating systems.

      Good luck with a browser without javascript.

      • kstrauser 3 years ago

        Ironic that it came from a project in Mozilla, who used it to experiment with a new browser engine.

        • josephg 3 years ago

          Yeah; I'm pretty sure parts of firefox have already been rewritten in rust. And there's a project at google to start adding rust to chromium too[1].

          > Ownership is completely inadequate for operating systems.

          The linux kernel is adding rust support as a first class language. In time I wouldn't be surprised if large parts of the linux kernel were written in rust. Obviously linux will always have a lot of unsafe code, but unsafe is part of rust too. Its surprising how infrequently you need it.

          [1] https://security.googleblog.com/2023/01/supporting-use-of-ru...

  • nobody0 3 years ago

    > Freedom is slavery, and ignorance is strength

  • shrimp_emoji 3 years ago

    Aaand that's how you end up with data races.

  • adamnemecek 3 years ago

    Why do you think Rust has been such a success?

    • kazinator 3 years ago

      Rust has an obvious audience: programmers who have somehow been lulled into accepting an insane language and language features: namely C++ people.

      You basically just have to readjust their blinders.

    • Snelius 3 years ago

      It has not a success. Just aggressive ads.

      • adamnemecek 3 years ago

        All the big tech companies are using Rust in one way or another. What other recent language can claim that?

        • FpUser 3 years ago

          Big tech companies do use many languages. Sometimes smaller one as well. I deal directly with at least 5 at the moment. C++ is in this set but no Rust so far as I do not have business case for it. But do some reading to be aware.

          • adamnemecek 3 years ago

            What other recent language is used by all large tech companies.

            • FpUser 3 years ago

              >"What other recent language is used by all large tech companies."

              What on earth constitutes "recent" language and where did you se me mentioning "resent"? Anyways, does C++17 qualify? What about PHP8, ECMAScript of latter editions, newer versions of C#, Java etc. etc. ?

              If I understand your thinking correct let me help you with your question: what native high performance language with no GC, memory / lifetime management and with the stable release after 2015 is used by all large tech companies. Nice try.

              Also what FAANGs do with their choice of tech is their own worries. They have needs that will never be encountered by majority of the rest of the world's programming.

              • adamnemecek 3 years ago

                > What on earth constitutes "recent" language and where did you se me mentioning "resent"? Anyways, does C++17 qualify? What about PHP8, ECMAScript of latter editions, newer versions of C#, Java etc. etc. ?

                No, language versions are not languages.

                > If I understand your thinking correct let me help you with your question: what native high performance language with no GC, memory / lifetime management and with the stable release after 2015 is used by all large tech companies. Nice try.

                I meant in general, which languages that were created in the last 20 years are used by all big tech companies.

                > Also what FAANGs do with their choice of tech is their own worries. They have needs that will never be encountered by majority of the rest of the world's programming.

                I was arguing that Rust is popular since it has quite a bit of adoption, as demonstrated for example by it's usage by big tech. Also, no, there is a dire need for good systems languages.

      • daniel-grigg 3 years ago

        Yes and no. The aggressive marketing is successfully entrenching it to future generations so whether it’s successful with the current gen of c++ programmers or even GC languages like Java doesn’t really matter imo.

      • notjake123 3 years ago

        What aggressive ads?

      • adamnemecek 3 years ago

        Rust is a resounding success and it's only getting started.

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection