Live data from Hacker News

The Rust I wanted had no future

graydon2.dreamwidth.org

401–410 of 523 posts

Re: The Rust I wanted had no future

#401
post #321

Earlier quoted context omitted.

async has fragmented the crates ecosystem. If you want to want to write async-free code with threads, you'll probably still have to opt-in to an async executor for some dependency because these days many libraries will implement only an async interface

I think you're manifesting what I'm talking about. The reason you cannot replace async with threads has nothing to do with the ecosystem, but the simple fact that threading is a model of parallelism and async/await is a model of concurrency. These are two subtly different concepts in software architecture, but they are not the same thing. More concretely, threaded code has nothing to say about whether or not its sync…

> I think you're manifesting what I'm talking about. The reason you cannot replace async with threads has nothing to do with the ecosystem, but the simple fact that threading is a model of parallelism and async/await is a model of concurrency.

That is an artificial distinction you made up. I have written many apps and desktop applications, all of which where using 3-10 threads, some of them doing "parallel" work meaning the parallel computation of divide and conquer algorithms, some were doing concurrent work.

I tried async often. I threw it away every single time, because it "infects" the entire codebase. I suspect the only reason async exists is because the Javascript event-loop is single-threaded and there are no blocking primitives in JS. If you don't have access to blocking data-handoff between threads, you can choose between callback hell or async/await.

Please take a look at the video I posted earlier.

Re: The Rust I wanted had no future

#402
"Exterior iteration. Iteration used to be by stack / non-escaping coroutines, which we also called "interior" iteration, as opposed to "exterior" iteration by pointer-like things that live in variables you advance. Such coroutines are now finally supported by LLVM (they weren't at the time) and are actually a fairly old and reliable mechanism for a linking-friendly, not-having-to-inline-tons-of-library-code abstraction for iteration. They're in, like, BLISS and Modula-2 and such. Really normal thing to have, early Rust had them, and they got ripped out for a bunch of reasons that, again, mostly just form "an argument I lost" rather than anything I disagree with today. I wish Rust still had them. Maybe someday it will!"

I remember that one. The change was shortly after I started fooling with Rust and was major. Major as in it broke all the code that I'd written to that point.

"Async/await. I wanted a standard green-thread runtime with growable stacks -- essentially just "coroutines that escape, when you need them too"."

I remember that one, too; it was one of the things that drew me to the language---I was imagining something more like Pony (https://www.ponylang.io/).

"The Rust I Wanted probably had no future, or at least not one anywhere near as good as The Rust We Got."

Almost certainly true. But The Rust We Got is A Better C++, which was never appealing to me because I never liked C++ anyway.

Re: The Rust I wanted had no future

#403
post #398
post #353

Earlier quoted context omitted.

Then I have to check the result anyways. Same thing

No. In Rust check is there by default, with optional unchecked access. In C++ the safety is off by default and you have to remember to check. It's like Yaml parsers, they had "load_yaml" which is unsafe and "safe_load_yaml" which is the secure option. Imagine no surprise when Rubyists went for shorter safe looking method and got their servers pwned.

I think you are wrong. I looked and in Rust doc it says that: "Removes the last element from a vector and returns it, or None if it is empty". You better be doing check for "None".

Re: The Rust I wanted had no future

#404
post #167

The key challenge of rust for me: "Complex grammar. I've become somewhat infamous about wanting to keep the language LL(1) but the fact is that today one can't parse Rust very easily, much less pretty-print (thus auto-format) it, and this is an actual (and fairly frequent) source of problems. It's easier to work with than C++, but that's fairly faint praise. I lost almost every argument about this, from the angle bra…

Is there a practical issue with this, or is this more philosophical?

Re: The Rust I wanted had no future

#405
post #261

Earlier quoted context omitted.

It's crazy that the programming community even accepted the concept of async/await as a sane one. Being sync or async is essentially a property of the attention of the caller, not of the action itself. Is "eating a donut" a sync or async action? If I'm focusing all my attention on it, essentially putting all tasks aside (after) - then it's a synchronous action. If I'm reading a book/watching a video/walking/etc, whil…

> How does "func EatADonut() async {}" aka "eating a donut is an inherently async action" even make sense to people? Of course it does, read it as "beware, something blocking down the road". If you can EatADonout without blocking, please do, but want it or not that's a different implementation, one that doesn't block and the signature it's telling you so. We're so used to sync and having hidden blocking operations. I…

> want it or not that's a different implementation,

Implementation is the same. In both cases it's the same set of CPU instructions, but async/await languages create artifical division, forcing developer to think othervise.

So, let me explian my reasoning. Code starts with a developer's mental model of a problem and behavior of the system and then translating it into the code. The more straightforward this translation, the more readable the code. Code is a second degree map of problem domain so to speak ("real" world -> mental model -> code).

Like if you want to add two values, the simplest form of code would be "add(2,2)" which is pretty straightforward. If the code forces you to do some mental gymnastics (i.e. "2 2 addOnlyEvenNumbers") - that's less straightforward, less clear and less readable.

In the same vein, if you want to execute some function ("EatADonut" or "MakeHTTPCall") – you may care or not care about blocking and waiting for results. But it's your call. So it makes sense to give you two options to run this function. Go has simplest possible solution – "eatADonut()" vs "go eatADonut()". It doesn't matter what is a "default" here – it could be "eatADonut()" (go to background) vs "sync eatADount()". What matters that "eating a donut" is just a set of instructions to the CPU, and it's up to caller to decide how you want to execute it in terms of concurrency.

Now, "async/await" approach turned this ownership of "synchronicity" around. Now function is deciding how it should be called. Mental model of "actions" now needs to be translated into "actions being async or sync for the purpose of fitting into this language concept". Which is cognitively expensive for no added benefit.

Sure you can rationalize it, and get used to it as to any other absurd design, but it still adds unneeded complexity to the code, makes it less readable and less clear.

Re: The Rust I wanted had no future

#406
Funny how every time I click a link to a dreamwidth.org hosted blog the,

>"Hello, you've been (semi-randomly) selected to take a CAPTCHA to validate your requests. Please complete it below and hit the button!"

...pops up and the button doesn't actually work. Truly one of the worst blog hosts out there if you actually want everyone to be able to read what you write.

Re: The Rust I wanted had no future

#407
post #167

The key challenge of rust for me: "Complex grammar. I've become somewhat infamous about wanting to keep the language LL(1) but the fact is that today one can't parse Rust very easily, much less pretty-print (thus auto-format) it, and this is an actual (and fairly frequent) source of problems. It's easier to work with than C++, but that's fairly faint praise. I lost almost every argument about this, from the angle bra…

Is there a practical issue with this, or is this more philosophical?

Is there anything easier to parse than Lisp? Plus you get homoiconicity and `quote` is free. But... it's ugly.

Re: The Rust I wanted had no future

#408

I love Rust and built some production code with it in the past. But nowadays I want something more simple so that not-so-senior developers can pick it up quickly, and I want flawless tooling, and willing to sacrifice a bit of performance. So basically I often end up with Go. Go is exceptionally great in tooling, ecosystem, any objective metrics like build times or crosscompilation... but I still don't like the langua…

Nim gets real close. It doesn't have great UI tooling, but its command line tools are quite good.

Nim is quite imperative, too. And its BDFL(Araq) takes a dim view of functional programming: https://forum.nim-lang.org/t/8927

Re: The Rust I wanted had no future

#409
post #388

Earlier quoted context omitted.

You can track all of this (things like Rc or Arc do) except move. Relative pointers are possible, depending on what you mean. Making this safe (e.g. preventing users of that type from breaking the relative addressing) is done via the Pin type.

> You can track all of this (things like Rc or Arc do) except move. Which means you can't track this. Tracking moves is fundamental here. > Relative pointers are possible, depending on what you mean. Pretty sure they're not possible in the sense I mean, for the same reason as above - you need custom moves for this. I'm referring to a pointer (not an offset; a pointer) that automatically adjusts itself when copied or…

> Tracking moves is fundamental here.

I mean, arguably. If it is fundamental for your hypothetical use case, then sure, but this is not required for a lot of use cases, like smart pointers.

Re: The Rust I wanted had no future

#410
post #403
post #398

Earlier quoted context omitted.

No. In Rust check is there by default, with optional unchecked access. In C++ the safety is off by default and you have to remember to check. It's like Yaml parsers, they had "load_yaml" which is unsafe and "safe_load_yaml" which is the secure option. Imagine no surprise when Rubyists went for shorter safe looking method and got their servers pwned.

I think you are wrong. I looked and in Rust doc it says that: "Removes the last element from a vector and returns it, or None if it is empty". You better be doing check for "None".

The check is still there, that's not under dispute. GP is saying that it's still not the "same thing" as C++, since Rust will refuse to compile the code unless you either perform the check, or actively opt into unchecked access. In contrast, C++ will happily compile the code if you unintentionally neglect to perform the check.
Post reply on HN