Live data from Hacker News

Flattening Rust’s learning curve

corrode.dev

221–230 of 405 posts

Re: Flattening Rust’s learning curve

#221
post #208
post #93

Earlier quoted context omitted.

I don't know how to read your comment other than "nothing hard is worth doing". Some things have benefits and drawbacks, is the existence of drawbacks always a non-starter for you? I'm trying to phrase this as delicately as I can but I am really puzzled. If someone wrote an article about how playing the harp is difficult, just stick with it... would you also say that playing the harp is a terrible hobby?

Let me help you If it takes the average person 1 million hours to learn rust then the average person won't learn rust If it takes the average person 1 hour to learn rust then the average person will learn rust. If you were designing a language which would you pick all else being equal? To your question, no but I wouldn't be puzzled when most people pick up a guitar. (Both are so much more intuitive than any programmi…

> If you were designing a language which would you pick all else being equal?

But why would you think all else is equal? You might not agree with the tradeoffs Rust makes, and it's not as if there's a perfect language for all uses, but it absolutely makes hard software easier to write.

I've had the opportunity to debug weird crazy memory corruption, as well as "wow it's hard to figure out how to design this in Rust", and having come to terms with things much like this blog post I now get more work done, with less corruption _and_ design problems.

Re: Flattening Rust’s learning curve

#222
post #103

Write a CHIP8 emulator! Bonus: do it with no heap allocation. This actually makes it easier because you basically don’t deal with lifetimes. You just have a state object that you pass to your input system, then your guest cpu system, then your renderer, and repeat. And I mean… look just how incredibly well a match expression works for opcode handling: https://github.com/ablakey/chip8/blob/15ce094a1d9de314862abb... My…

I’ve found emulators to be a pretty poor first project for rust specifically for the reasons you alluded to: That you need to know to write it without heap allocation (or other hoop jumping so long as you avoid juggling lifetimes) when so much literature and example emulator code doesn’t do this is a recipe for a bad experience. Ask me how I know. If you’re going to write an emulator in this style, why even use an im…

These emulators already exist in basically every language, so why do anything? The point is the journey, which doesn’t need to be the shortest, most optimal path possible.

Re: Flattening Rust’s learning curve

#223
post #175

Earlier quoted context omitted.

C may be simple, but its too simple to be called elegant. The lack of namespacing comes to mind. Or that it is a staticly typed language, whose type system is barely enforced (you have to declare all types, but sometimes it feels like everything decays to int and *void without the right compiler incantations). Or the build system, where you have to learn a separate language to generate a separate language to compile…

C is elegant because as an extremely powerful programming language used to create an uncountable number of high-profile projects it's simple enough that I feel optimistic I could write a C compiler myself if it was really necessary. It may be impractical for some tasks but the power:complexity rate is very impressive. Lua feels similar in that regard.

The mechanism for sharing definitions, 'include' aka "copy file here", is absolutely not elegant. The absolute minimum you could do maybe, but not elegant.

Re: Flattening Rust’s learning curve

#224
post #69
post #18

It's like reading "A Discipline of Programming", by Dijkstra. That morality play approach was needed back then, because nobody knew how to think about this stuff. Most explanations of ownership in Rust are far too wordy. See [1]. The core concepts are mostly there, but hidden under all the examples. - Each data object in Rust has exactly one owner. - Ownership can be transferred in ways that preserve the one-owner ru…

The second bullet in the second section is overpromising badly. In fact there are many, many, many ways to write verifiably correct code that leaves no dangling pointers yet won't compile with rustc. Frankly most of the complexity you're complaining about stems from attempts to specify exactly what magic the borrow checker can prove correct and which incantations it can't.

A great teaching technique I learned from a very good match teacher is that when explaining core concepts, the simplified definitions don't need to be completely right. They are much simpler to grasp and adding exceptions to these is also quite easy compared to trying to understand correct, but complex, definitions at the beginning.

Re: Flattening Rust’s learning curve

#225
post #18

It's like reading "A Discipline of Programming", by Dijkstra. That morality play approach was needed back then, because nobody knew how to think about this stuff. Most explanations of ownership in Rust are far too wordy. See [1]. The core concepts are mostly there, but hidden under all the examples. - Each data object in Rust has exactly one owner. - Ownership can be transferred in ways that preserve the one-owner ru…

That's not explaining ownership, that motivating it. Which is fine. The thing that's hard to explain and learn is how to read function signatures involving (...) -> &'a [&'b str] or whatever. And how to understand and fix the compiler errors in code calling such a function.

The good news is that idiomatically written good clean Rust code doesn't need to rely on such borrow signatures very often. That's more when you're leaving the norm and doing something "clever."

I know it throws people off, and the compiler error can be confusing, but actual explicit lifetimes as part of a signature are less common than you'd expect.

To me it's a code smell to see a lot of them.

Re: Flattening Rust’s learning curve

#226
post #31

Earlier quoted context omitted.

Got recommended learning paths? I tend to prefer follow along adventures via video.

Check out Jon Gjengset. https://www.youtube.com/@jonhoo

I wouldn't agree with that. Jon's content is great, but it's really not aimed at beginners, and some of his stuff really gets into the weeds.

Re: Flattening Rust’s learning curve

#227
post #113

Earlier quoted context omitted.

Hard in safe rust. you can just use unsafe in that one area and still benefit in most of your application from safe rust.

I don’t use C++ for most of my applications. I only use C++ to build DLLs which implement CPU-bound performance sensitive numeric stuff, and sometimes to consume C++ APIs and third-party libraries. Most of my applications are written in C#. C# provides memory safety guarantees very comparable to Rust, other safety guarantees are better (an example is compiler option to convert integer overflows into runtime exception…

It does sound like quite a similar model; unsafe Rust in self contained regions, safe in the majority of areas.

FWIW in the case where you're not separating code via a dynamic library boundary, you give the compiler an opportunity to optimise across those unsafe usages, e.g. inlining opportunities for the unsafe code into callers.

Re: Flattening Rust’s learning curve

#228

Earlier quoted context omitted.

You’re passing in two references and returning a reference. The compiler knows the returned reference must be tied to one of the incoming references (since you cannot return a reference to something created within the function, and all inputs are references, the output must therefore be referencing the input). But the compiler can’t know which reference the result comes from unless you tell it. Theoretically it could…

> Theoretically it could tell by introspecting the function body, but the compiler only works on signatures Note that this is an intentional choice rather than a limitation, because if the compiler analyzed the function body to determine lifetimes of parameters and return values, then changing the body of a function could be a non-obvious breaking API change. If lifetimes are only dependent on the signature, then its…

Oh yes, I didn’t mean to make it sound like a problem. I personally strongly prefer signature-based typing vs like in Typescript where you can easily be returning an entirely unintentional type and not realize it until you try to use it in an explicitly typed context down the line.

I also imagine it’s much faster for the type-checking pass of the compiler to just look at the signatures.

Re: Flattening Rust’s learning curve

#229
post #18

It's like reading "A Discipline of Programming", by Dijkstra. That morality play approach was needed back then, because nobody knew how to think about this stuff. Most explanations of ownership in Rust are far too wordy. See [1]. The core concepts are mostly there, but hidden under all the examples. - Each data object in Rust has exactly one owner. - Ownership can be transferred in ways that preserve the one-owner ru…

Maybe it's my learning limitations, but I find it hard to follow explanations like these. I had similar feelings about encapsulation explanations: it would say I can hide information without going into much detail. Why, from whom? How is it hiding if I can _see it on my screen_. Similarly here, I can't understand for example _who_ is the owner. Is it a stack frame? Why would a stack frame want to move ownership to it…

> Why would a stack frame want to move ownership to its callee

Rust's system of ownership and borrowing effectively lets you hand out "permissions" for data access. The owner gets the maximum permissions, including the ability to hand out references, which grant lesser permissions.

In some cases these permissions are useful for performance, yes. The owner has the permission to eagerly destroy something to instantly free up memory. It also has the permission to "move out" data, which allows you to avoid making unnecessary copies.

But it's useful for other reasons too. For example, threads don't follow a stack discipline; a callee is not guaranteed to terminate before the caller returns, so passing ownership of data sent to another thread is important for correctness.

And naturally, the ability to pass ownership to higher stack frames (from callee to caller) is also necessary for correctness.

In practice, people write functions that need the least permissions necessary. It's overwhelmingly common for callees to take references rather than taking ownership, because what they're doing just doesn't require ownership.

Re: Flattening Rust’s learning curve

#230

Earlier quoted context omitted.

> Rust still needs a way out of that mess. In practice, it really doesn't. The difficulty of implementing doubly linked lists has not stopped people from productively writing millions of lines of Rust in the real world. Most programmers spend less than 0.1% of their time reimplementing linked data structures; rust is pretty useful for the other 99.9%.

Doubly linked lists are rare, but backlinks to the owner are often needed. It's the same problem, mostly.

Backlinks work fine with weak Arc references, don’t they?
Post reply on HN