Live data from Hacker News

Rust Is Hard, Or: The Misery of Mainstream Programming

hirrolot.github.io

361–370 of 811 posts

Re: Rust Is Hard, Or: The Misery of Mainstream Programming

#361
post #309

Earlier quoted context omitted.

The important difference is in purpose, not implementation. Most async runtimes use a thread or more per core, and the OS is doing that thread scheduling, so it's not the either-or situation that you describe. The interesting thing about async (especially async-await) is that it is a fluent way to write a program that waits for events (e.g. I/O), without resorting to inefficient designs like thread-per-client in orde…

> The important difference is in purpose, not implementation. I couldn't disagree stronger on that one. Abstraction is generally good, but this becomes a purely philosophical discussion as soon as you ignore the actual implementation when talking about the differences of how something actuals behaves and should be used . And philosophical discussions like that have their place but are imo pointless in the context of…

I'm not saying that implementation doesn't matter. I'm saying that that there isn't a fundamental implementation difference "async" vs "threads". Threads are used in both cases. It's a different choice of abstractions over the same underlying concepts.

FYI, Rust (the language) has no concept of prioritising workloads; there is no async runtime in the language.

Even with any of the async runtimes, workloads (i.e. tasks doing work) are prioritised by the OS. It's just threads executing code. Async runtimes are primarily concerned with the gaps between work, like waiting for I/O or other events.

Re: Rust Is Hard, Or: The Misery of Mainstream Programming

#362

I've been doing async Rust since the tokio 0.x combinator days, and I remember being like OP. For some reason `Arc` did not exist in my mind and it was a struggle appeasing the borrow checker. The Go version is similar to the final Rust version; except the Go version is forcing you to use Arc everyone[1]. Seriously, just use Arc (or Arc >), in 70% of cases you are wrestling with the borrow checker trying to do someth…

I do completely agree with your advice of using `Arc`s. But unfortunately, sometimes it gets very tedious to deal with all these `Arc`s: https://github.com/teloxide/teloxide/blob/ec1d41220c51872cf9... . It also blurs the advantage of Rust as a lifetime validation tool if you use reference counting anyways. But it seems that it's the only viable approach for async at the moment.

The overall effect of Arcs being more usable is something that was true before Rust. It is an emergent property of Rust too, because it's still true. The alternative to using Arc or similar used to be validating your own lifetimes manually and inevitably making show-stopping mistakes in C/C++. Now the alternative is machine-checking it and being able to never make mistakes. But Arc is still more ergonomic than either.

If Rust forces you to use Arc where in C/C++ you would normally just be freewheeling your lifetimes, by complaining about your lifetimes, a lot of people are going to see that as "Rust is really annoying and gets in my way, it's making me choose between a tangle of lifetime bounds and explicit Arcs". The truth is that it is teaching you that your normal style would have led to mistakes and you should never have been coding that way. So people go on complaining about being re-taught until their normal style works in Rust, or until they give up. (I don't think that's what you're doing, this is mainly just to say Arcs are not a waste of the language's power, rather an effect of the language's power to know when your freewheeling would be mere lifetime guesstimation and quite possible buggy in C++.)

The author's point is strong though.

> the process of designing APIs is affected by numerous arbitrary language limitations like those we have seen so far.

There's a long way to go in being able to perfectly express all the ways you might want to use lifetimes. Sometimes you come across a situation when a few of these limitations converge on one spot, and you get the author's problem. But equally, the author is trying to write something that has probably never had its lifetime rules described before. Yes, languages with GCs can do it easily. That was also true of lock-free queues & running destructors. GCs have it easy in a ton of different areas around lifetimes. The core complaint here is that Rust does not have a GC and we have had it really easy being able to rely on one & not having to write down exactly the lifetime bounds that could make it work statically. The author is complaining that there are hundreds of compiler issues preventing some of this being expressed... well, yeah, nobody has ever, EVER, tried to write this stuff down before in a machine-readable way, we are slowly covering the untrodden ground, and you might be in an especially untrodden area. I think that's a pretty good excuse for the compiler having issues and some things being not quite expressible, but it's also an important caveat to "fearless concurrency" and I think the post illustrated that well.

Re: Rust Is Hard, Or: The Misery of Mainstream Programming

#363
post #355

Earlier quoted context omitted.

> complex language which limits you Rust really does not limit you. Anything possible in C or C++ can be done in Rust if you're willing to use unsafe code.

This is not the case if you are designing a library. Much of what is routinely used to capture semantics into mainstream C++ libraries is wholly impossible to express in Rust. (C is not even a participant, here.) This is not about template metaprogramming, just ordinary stuff. Most of that difference is in things that happen at compile time, so this is not a question of Turing completeness.

> Much of what is routinely used to capture semantics into mainstream C++ libraries is wholly impossible to express in Rust. (C is not even a participant, here.) This is not about template metaprogramming, just ordinary stuff.

Do you have any examples?

Re: Rust Is Hard, Or: The Misery of Mainstream Programming

#364

Is rusts most loved status simply Stockholm syndrome? I've really tried with rust, and we simply don't get on. I hear all the arguments about CVEs and wonder if rust will reduce the number of these problems simply by disabling the programmers that create them. I understand the draw, I want to love it, but i think I might not be smart enough.

It's a language designed by people who's favourite language is not even pronounceable. Did you think that such a group of people, who place their love for the language above practical things like readability, would come up with a new language that cared about the user-experience[1]? As we see all the time WRT to programming languages, readability is more important than the more abstract stuff. > I hear all the argume…

This opinion seems to be very sure of things.

Re: Rust Is Hard, Or: The Misery of Mainstream Programming

#365
post #311

Is rusts most loved status simply Stockholm syndrome? I've really tried with rust, and we simply don't get on. I hear all the arguments about CVEs and wonder if rust will reduce the number of these problems simply by disabling the programmers that create them. I understand the draw, I want to love it, but i think I might not be smart enough.

No, it's a selection effect. The stackoverflow most loved metric is people_who_want_to_keep_using_the_language / people_who_have_used_it_in_the_past_year Since Rust is so early in its adoption and there are few jobs, many of the responders are hobbyists who are into Rust, like it and want to keep using; not necessarily people who use it for work. And since you only take into account the people who have used it in the…

This selection effect cannot explain Rust's standing relative to other new languages and neither can it explain why Rust's popularity (as measured by "most loved") increases over time as more and more companies are using it. Here's the history of Rust's "most loved" percentage going back to 2015

  Year - Most Loved Pct. - Rank
  2015 - 73.8%           - 3
  2016 - 79.1%           - 1
  2017 - 73.1%           - 1  
  2018 - 78.9%           - 1
  2019 - 83.5%           - 1
  2020 - 86.1%           - 1
  2021 - 86.98%          - 1

Re: Rust Is Hard, Or: The Misery of Mainstream Programming

#366
post #3

Rust isn't hard. Programming is hard. Rust just points out failure states before you encounter them in production.

This right here. Rust is a low-level language hat makes a whole dimension of implicit knowledge explicit.

This is a very good thing, but if you are a programmer that is used to "copy paste, and then it works". You will have a very, very, very bad time with it. Rust forces you to think about memory. In an age where dynamic typing is so prevalent this seems like a fading art.

Re: Rust Is Hard, Or: The Misery of Mainstream Programming

#367
post #344

Just got started with Rust and yeah, my biggest pain point so far were lifetimes and async code. I finally replaced tokio with multithreaded blocking code, which seems to be much simpler and more familiar. The problem with async was that some of the libraries I needed (e.g. for QUIC) didn't support it, so you had an unholy mixture of blocking and non-blocking code. Coming from a C++ background I appreciate Rust's nov…

Just use `Arc`, it's fine, it will be plenty fast.

That's what I ended up doing, Arc> for sharing stuff between threads, works really well.

Re: Rust Is Hard, Or: The Misery of Mainstream Programming

#368

Just got started with Rust and yeah, my biggest pain point so far were lifetimes and async code. I finally replaced tokio with multithreaded blocking code, which seems to be much simpler and more familiar. The problem with async was that some of the libraries I needed (e.g. for QUIC) didn't support it, so you had an unholy mixture of blocking and non-blocking code. Coming from a C++ background I appreciate Rust's nov…

I've successfully replaced tokio with the lower-level mio in one such case. After all threads and async serve different purposes: Threads when you're computing a lot, async when you're waiting a lot, no?

> After all threads and async serve different purposes: Threads when you're computing a lot, async when you're waiting a lot, no?

It doesn't have to be one or the other. Go uses coroutines and multiplexes them onto multiple OS-level threads (usually as many as there are cores).

Re: Rust Is Hard, Or: The Misery of Mainstream Programming

#369
I believe that the borrow checker is amazing, some other things are nice - but as though it's all kind of an experiment.

I'm extremely wary of issues of productivity in Rust - most code does not need to be that perfect and the tradeoff is not rational in so many cases.

Rust is the 'C++' of it's era of languages - bizarre, unwieldy. It's an experiment.

We are waiting for the 'James Gosling of Rust' to come along, and blow a ton of unnecessary complexity away with the 'Java' iteration of Rust.

Then it will be mainstream and uncool :)

Re: Rust Is Hard, Or: The Misery of Mainstream Programming

#370
post #329

Earlier quoted context omitted.

I think that's ocaml. Higher level, with GC, nice type system, no traits but signatures and higher order modules might be enough for you, and a compiler that produces fast native binaries.

Ocaml is just a mess. Has like two standard libs. You'll just fighting everything but your application logic instead.

There is only one OCaml build system (dune) which is used by people that don't write their own build system. But yes, you have the freedom of using alternative to the OCaml standard library if you wish so.
Post reply on HN