Live data from Hacker News

Flattening Rust’s learning curve

corrode.dev

91–100 of 405 posts

Re: Flattening Rust’s learning curve

#91
post #6
post #2

> Treat the borrow checker as a co-author, not an adversary Why would I pair-program with someone who doesn’t understand doubly-linked lists?

For people who don't get the reference, this might be referring to the notoriously gnarly task of implementing a doubly-linked lists in Rust [1] It is doable, just not as easy as in other languages because a production-grade linked-list is unsafe because Rust's ownership model fundamentally conflicts with the doubly-linked structure. Each node in a doubly-linked list needs to point to both its next and previous nodes…

Apologies since I have not taken the time to learn rust yet, but I've written a lot of modern C++. Is the ownership model kind of like std::unique_ptr and std::move, and `Rc>` the same idea as `std::shared_ptr`? But less idiomatic? Or do I have the wrong idea?

Re: Flattening Rust’s learning curve

#92
It took me a few tries to get comfortable with Rust—its ownership model, lifetimes, and pervasive use of enums and pattern matching were daunting at first. In my initial attempt, I felt overwhelmed very early on. The second time, I was too dogmatic, reading the book line by line from the very first chapter, and eventually lost patience. By then, however, I had come to understand that Rust would help me learn programming and software design on a deeper level. On my third try, I finally found success; I began rewriting my small programs and scripts using the rudimentary understanding I had gained from my previous encounters. I filled in the gaps as needed—learning idiomatic error handling, using types to express data, and harnessing pattern matching, among other techniques.

After all this ordeal, I can confidently say that learning Rust was one of the best decisions I’ve made in my programming career. Declaring types, structs, and enums beforehand, then writing functions to work with immutable data and pattern matching, has become the approach I apply even when coding in other languages.

Re: Flattening Rust’s learning curve

#93

[flagged]

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?

Re: Flattening Rust’s learning curve

#94

[flagged]

I have taken the time to learn rust and you're absolutely right. It's a very complex, design-by-committee language. It has brilliant tooling, and is still much less complex than it's design-by-committee competitor C++, but it will never be easy to learn.

> It's a very complex

I find it relatively simple. Much simpler than C++ (obviously). For someone who can write C++ and has some experience wth OCaml/Haskell/F#, it's not a hard language.

Re: Flattening Rust’s learning curve

#95

Earlier quoted context omitted.

Rust has better defaults for types than C++, largely because the C++ defaults came from C. Rust is more ergonomic in this regard. If you designed C++ today, it would likely adopt many of these defaults. However, for high-performance systems software specifically, objects often have intrinsically ambiguous ownership and lifetimes that are only resolvable at runtime. Rust has a pretty rigid view of such things. In thes…

> However, for high-performance systems software specifically, objects often have intrinsically ambiguous ownership What is the evidence for this? Plenty of high-performance systems software (browsers, kernels, web servers, you name it) has been written in Rust. Also Rust does support runtime borrow-checking with Rc >. It's just less ergonomic than references, but it works just fine.

Anyone that works on e.g. database kernels that do direct DMA (i.e. all the high-performance ones) experiences this. The silicon doesn’t care about your programming language’s ownership model and will violate it at will. You can’t fix it in the language, you have to accept the behavior of the silicon. Lifetimes are intrinsically ambiguous because objects have neither a consistent nor persistent memory address, a pretty standard property in databases, and a mandatory property of large databases. Yes, you can kind of work around it in idiomatic Rust but performance will not be anything like comparable if you do. You have to embrace the nature of the thing.

The near impossibility of building a competitive high-performance I/O scheduler in safe Rust is almost a trope at this point in serious performance-engineering circles.

To be clear, C++ is not exactly comfortable with this either but it acknowledges that these cases exist and provides tools to manage it. Rust, not so much.

Re: Flattening Rust’s learning curve

#96
post #89

[flagged]

Maybe Rust is so complex, it is even more complex for an LLM to generate correct code (one-shot) without hallucinating non-existent functions. Would rather have that than all the issues that JavaScript or any other weakly typed and dynamically typed language.

There _are_ more than two programming languages, though. I feel like most of the debates about Rust devolve into the same false choice between safety and ease.

Before Rust I was hearing the same argument from Haskell or Scala developers trying to justify their language of choice.

I know Rust is here to stay, but I think it’s mostly because it has a viable ecosystem and quality developer tools. Its popularity is _in spite of_ many of its language features that trade that extra 1% of safety for 90% extra learning curve.

Re: Flattening Rust’s learning curve

#97
post #67

> Use String and clone() and unwrap generously; you can always refactor later At that point you might as well be writing Java or Go or whatever though. GC runtimes tend actually to be significantly faster for this kind of code, since they can avoid all those copies by sharing the underlying resource. By the same logic, you can always refactor the performance-critical stuff via your FFI of choice.

I went through this the first year that I did Advent of Code in rust, like okay I read in all the strings from the input file and now they're in a vector, so I'm going to iterate the vector and add references to those strings into this other structure, but of course they're still owned by the original vector, that's awkward. Oh wait I can iter_into and then I get owned objects and that ownership can be transferred to the other structure instead, but now I need them to also be keys in a map, do I use references for that too?

Cloning small objects is lightning fast, turns out in a lot of these cases it makes sense to just do the clone, especially when it's a first pass. The nice thing is that at least rust makes you explicitly clone() so you're aware when it's happening, vs other languages where it's easy to lose track of what is and isn't costing you memory. So you can see that it's happening, you can reason about it, and once the bones of the algorithm are in place, you can say "okay, yes, this is what should ultimately own this data, and here's the path it's going to take to get there, and these other usages will be references or clones.

Re: Flattening Rust’s learning curve

#98

Earlier quoted context omitted.

This is incorrect. A learning curve measures expertise on the x axis and effort on the y axis. Hence the saying "steep learning curve".

https://en.wikipedia.org/wiki/Learning_curve

It is unclear how this comment was meant; in any case, it is appreciated. As stated in the link:

“The common English usage aligns with a metaphorical interpretation of the learning curve as a hill to climb.”

Followed by a graph plotting x “experience” against y “learning.”

Re: Flattening Rust’s learning curve

#99

A learning curve measures time on the x axis and progress on the y axis. A flat learning curve means you never learn anything :-\

This is incorrect. A learning curve measures expertise on the x axis and effort on the y axis. Hence the saying "steep learning curve".

Calling it inaccurate was too harsh; my definition only became common usage in 1970, and the original “time vs learning” is still used in academic circles.

Re: Flattening Rust’s learning curve

#100
post #67

> Use String and clone() and unwrap generously; you can always refactor later At that point you might as well be writing Java or Go or whatever though. GC runtimes tend actually to be significantly faster for this kind of code, since they can avoid all those copies by sharing the underlying resource. By the same logic, you can always refactor the performance-critical stuff via your FFI of choice.

I went through this the first year that I did Advent of Code in rust, like okay I read in all the strings from the input file and now they're in a vector, so I'm going to iterate the vector and add references to those strings into this other structure, but of course they're still owned by the original vector, that's awkward. Oh wait I can iter_into and then I get owned objects and that ownership can be transferred to…

> Cloning small objects is lightning fast

It's really not, it's the way python works. Heap allocations are "fast" on modern CPUs that are too fast to measure for most stuff, but they're much (much) slower than the function call and code you're going to use to operate on whatever the thing it was you cloned.

Code that needs memory safety and can handle performance requirements like this has many options for source language, almost none of which require blog posts to "flatten the learning curve".

(And to repeat: it's much slower than a GC which doesn't have to make the clone at all. Writing Rust that is "Slower Than Java" is IMHO completely missing the point. Java is boring as dirt, but super easy!)

Post reply on HN