Live data from Hacker News

Flattening Rust’s learning curve

corrode.dev

301–310 of 405 posts

Re: Flattening Rust’s learning curve

#301
post #269

Earlier quoted context omitted.

Indeed. Programmers are holding Rust wrong.

Programmers new to Rust, you mean. It's kind of like career Java programmers using JavaScript or Python for the first time and bringing their way of doing things.

It's more than that. Rust's value & reference passing semantics are completely different from the way most programmer's have trained their entire lives to think about it.

When you pass an argument to a function in Rust, or assign a value into a struct or variable, etc. you are moving it (unless it's Copy). That's extremely different from any other programming language people are used to, where things are broadly pass by value pass by reference and you can just do that as much as you want and the compiler doesn't care. It's as if in C++ you were doing std::move for every single argument or assignment.

And so as a programmer you have to shift to a mindset where you're thinking about that happening. This is profoundly unintuitive at first but becomes habit over time.

Then having that habit, it's actually a nice reasoning skill when you go back to working in other languages.

Re: Flattening Rust’s learning curve

#302
post #161

Earlier quoted context omitted.

I’m not sure why it’s counterintuitive that &str and String are different things. Do you also find it counterintuitive in C++ that std::string is different from const char* ? What about &[u8] and Vec ?

Better analogy is std::string_view vs std::string

Technically that's a bit closer, yes, but way more people have heard of char* than string_view, and char* is similar _enough_ to &str that the analogy still works.

Re: Flattening Rust’s learning curve

#303

Earlier quoted context omitted.

Is safe rust not Turing complete? I can see the argument that a purist "safe rust only" program might be slow, but it still will be expressible

Turning completeness doesn’t take efficiency into account, nor the reality of things like “call into the operating system so that you can display output” that are necessary when building real systems.

With respect, I think that's moving the goalposts. If we have defined out of existence all forms of I/O, then what are we actually discussing?

Re: Flattening Rust’s learning curve

#304

Earlier quoted context omitted.

How often do you care about the order in which objects are dropped?

anything where you need to have stuff run in constant time.

If you're in hard realtime land then you can't have any allocations at all; that's a pretty different ballgame.

Destructors should be as simple and side-effect free as possible, with the exception of things like locks or file handles where the expectation is very clear that the object going out of scope will trigger a release action.

Re: Flattening Rust’s learning curve

#305
post #267

I'm not sure there are many cases where I would choose rust. I'm open to it. I just think in any given situation there would most likely be a better option. Perhaps it will become prevalent enough that it will make sense in the future.

Rust will prevail only if it fixes C++ interop

Re: Flattening Rust’s learning curve

#306
post #101

Earlier quoted context omitted.

Sure, C++ has a more complex spec, nobody can argue against that. Complex is the wrong word. Baffling is a better word. Or counterintuitive, or cumbersome. If “easy enough for someone with experience in C++, OCaml, Haskell, and F#” were the same thing as “not hard” then I don’t think this debate would come up so frequently.

Of course, this is very subjective. For someone who only knows python or javascript at a superficial level, Rust may seem out of reach. But if you're ok with the most common programming paradigms, I don't find Rust baffling. I mean, you can't expect to learn a new language in a few days, it'll always take a bit of work. My feeling is that people complaining of the language being hard aren't putting the effort. My exp…

My feeling is that Java / C++ / Python / Javascript are all really the same language when you get down to it. Rust borrows from OCaml more than an other popular imperative languages (the first implementatoin by Graydon Hoare was in OCaml, so the inspirations abound), and therefore it really is quite different to a lot of devs who have never seen the functional paradigm. Good rust is written as a mix of imperative with a strong functional flavoring. Bad Rust is when you try to do everything by mutating arrays over iteration as you would do in imperative languages.

For me, I almost never write "for loops" and "if statements" in Rust; instead I use "functional iterators" and "match expressions", which interface with the borrow checker more nicely.

For example, iterating over an array while modifying it is a common pattern in imperative languages that compiles fine but often causes hard to reason about logic errors during runtime. In Rust, such a thing would cause compile time errors. So instead you rewrite to be more functional, it compiles, and then the magic is it just works, which is a common property of functional languages like Haskell.

IMO a lot of the consternation about the cost of the learning curve is because developers haven't realized once you get past it, the benefit is your code more often is just correct and therefore you run into fewer runtime bugs. In other languages you get the code compiling faster, but then you spend a great deal of time debugging things at runtime which you didn't anticipate at compile time.

Re: Flattening Rust’s learning curve

#307

Earlier quoted context omitted.

Turning completeness doesn’t take efficiency into account, nor the reality of things like “call into the operating system so that you can display output” that are necessary when building real systems.

With respect, I think that's moving the goalposts. If we have defined out of existence all forms of I/O, then what are we actually discussing?

We haven't, that's why Turing completeness is not relevant for the question at hand.

I can implement the non-IO parts of Brainfuck with safe Rust, so it is Turing Complete. That doesn't change the fact that there are useful programs not expressible in it.

Re: Flattening Rust’s learning curve

#308

Earlier quoted context omitted.

Macros are introduced early in Rust for a couple reasons. 1. println!() is a macro, so if you want to print anything out you need to grapple with what that ! means, and why println needs to be a macro in Rust. 2. Macros are important in Rust, they're not a small or ancillary feature. They put a lot of work into the macro system, and all Rust devs should aspire to use and understand metaprogramming. It's not a languag…

Hard disagree, macros almost always lead the "too clever for you own good" even when the macro system is safe. Macros should always be used sparingly, and I think that Rust teeters on the edge of encouraging too much complexity for the sake of convenience. As a systems programmer I am allergic to unnecessary levels of indirection that make it more difficult for me to reason about what the system is actually doing and…

I agree that if you're using macros to create unnecessary levels of indirection that make things more difficult to reason about, that's not advisable. One shouldn't do that with macros or any other abstraction.

With functions for instance, sometimes people get carried away very straightforward linear code, and atomize it into a hundred little functions that all call one another, all in the name of reducing code duplication. Doing so is an abuse of functions, but one wouldn't say that functions should be used sparingly.

I think that macros are an area where many programmers don't have a lot of experience, and so they also throw out some best practices in order to wrap their heads around what they're doing.

But macros can be very helpful if properly applied, and Rust makes that more ergonomic, and safe, to do.

For example, if I have to write 100 functions that all are similar in structure, but have a slightly different function signature. I would reach for a macro. I don't think it reduces clarity at all, and it increases maintainability because I don't have to change code in 100 functions if an adjustment needs to be made.

Another area where macros is very useful is in creating DSLs within Rust. This is usually the domain of LISPs, but it's an ergonomic way to write tests little scripts.

Re: Flattening Rust’s learning curve

#309

Earlier quoted context omitted.

> 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 pret…

You can always fall back to unsafe. Again, there are very few workloads that C/C++ can support which Rust cannot.

Re: Flattening Rust’s learning curve

#310
I seem to have eased into a rust programming style that dodges these, perhaps at the cost of some optimizations. Using the first example, for example (The article suggests this): Don't return an `&str`; use those for transient things only like function parameters; not for struct fields or returned types.

I'm starting to wonder what I'm missing out by doing this. Not addressed in the article: Any tips for using the more abstract features, like Cow etc? I hit a problem with this today, where a lib used Cow instead of String, and the lifetime errors bubbled up into my code.

edit: I found this amusing about the article: They demo `String` as a param, and `&str` as a return type for triggering errors; you can dodge these errors simply by doing the opposite!

Post reply on HN