Live data from Hacker News

The Rust I wanted had no future

graydon2.dreamwidth.org

421–430 of 523 posts

Re: The Rust I wanted had no future

#421

Earlier quoted context omitted.

> (i.e. function coloring) I really wish people stopped using this concept, especially in the context of Rust because the `async fn`/“regular function” split is strictly equivalent to the `try_something()`/`something()` split (the first one being failible and returning a `Result` in case of failure). `Result`s and `Option`s are coloring the stack in exactly the same way a `Future` does (and `async` is pure syntactic…

There's consistent use of Result and Option in std, community agreement to do things that way, and it's pretty easy to use them. Tons of stuff in std and many other crates don't use async. A lot of stuff is harder and more code to do async. A lot of it is much harder to read. That's the difference.

> There's consistent use of Result and Option in std,

Well, there are dozens[0] of incompatible error types in std, two of them being just called `Error`[1][2].

Everytime you create a function that use more one of the different error types from std (for instance, an I/O error and a TryFrom-related error) you have to create a custom Error enum to accommodate the different kinds of errors from std…

> community agreement to do things that way

And the community agreement is e̶r̶r̶o̶r̶-̶c̶h̶a̶i̶n̶, ̶f̶a̶i̶l̶u̶r̶e̶, ̶ s̶n̶a̶f̶u̶, this_error, unless it's for a binary crate and then it's ̶a̶n̶y̶h̶o̶w̶, ̶e̶y̶r̶e̶, color-eyre.

The error ecosystem is much more fragmented than the async one (even though I think this_error is here to last, so I don't have to migrate once again…). In the async world, there's pretty much tokio (but I think it would actually be better if it interoperated better with other runtimes so alternatives could emerge)

> A lot of it is much harder to read.

Ah yes, fut.await is fundamentally harder to read than res?, right?

Overall, you vastly underestimate the friction that the `Result`-based error handling adds. I still think it's worth it, and it's been slowly getting better (did I say I loved this_error?), but it remained one of the biggest point of friction in Rust over the 8 years (time flies) I've been using it. Async is comparatively less disrupting (mostly because it only appears in the call stacks where you're doing I/O, whereas errors are ubiquitous).

[0]: https://doc.rust-lang.org/std/error/trait.Error.html?search=...

[1]: https://doc.rust-lang.org/std/io/struct.Error.html

[2]: https://doc.rust-lang.org/std/fmt/struct.Error.html

Re: The Rust I wanted had no future

#422
post #403

Earlier quoted context omitted.

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.

Are you saying that Rust will refuse to compile code that does not explicitly check option return result for empty?

Re: The Rust I wanted had no future

#423
post #409

Earlier quoted context omitted.

> 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.

> this is not required for a lot of use cases, like smart pointers.

Nobody claimed otherwise. The question was what things Rust can't do, not what it can do.

Re: The Rust I wanted had no future

#424
When I first read Graydon talking about his plans for Rust, I pictured it as StandardML (or OCaml) without a garbage collector, and I was sold. This list doesn't look fully like that, but is closer than current Rust is.

My interest back then was in a higher level language with type inference and a modern ML-like type system but that could be used for systems programming, especially in database, virtual machine, and even operating system dev.

These days I work pretty much full-time in Rust, and I think Rust as it is today delivers on some of that promise, but not all. I feel like the language's borrowing and ownership checking are pretty brilliant but really begin to become a pain when dealing with nested and interrelated trees of objects and iterators (like if building a compiler or query evaluator, etc.), and resorting to Arc/Rc/RefCell, etc. feels awkward.

I'm not sure if the language Graydon talks about here would have been better for that or not.

But I'm also happy we have Rust, because it's an improvement over what else is out there, and I hope the community gets through its growing pains.

Re: The Rust I wanted had no future

#425
> The other option, which I wanted, was for these to be compiler builtins open-coded at the sites of use, rather than library-provided. No "user code" at all (not even stdlib). This is how they were originally in Rust: vec and str operations were all emitted by special-case code in the compiler.

One of the things I like about Delphi is that it has some powerful types as compiler intrinsics. Sets, strings (the compiler-generated code does call into RTL methods for things like finding substrings, but the string type itself), and so forth are all compiler-generated.

I would like to see more, in fact: I think a map type would be a great inbuilt addition. (What I'd really like is compiler stubs so you could link in your own implementation. Whatever is linked in, it's then heavily optimised by the linker to be inlined etc as appropriate.)

Re: The Rust I wanted had no future

#426

Earlier quoted context omitted.

The language doesn't push you towards interfaces implemented once, but many developers indeed persist doing it for no reason at all. With proper code review we're able to make that practice go away on the projects I'm working on.

Lots (all?) major frameworks push for dependency injection though, where interfaces are a must, as far as I know (not for DI-the-principle, but DI-as-implemented). ASP.Net Core is a good example. It's not C# at the language level forcing interface-driven development, but frameworks like ASP.Net are so tightly integrated that boundaries blur.

Yup, that's what I meant by "practically." Nobody forces you to use the Microsoft.x nuget packages, but good luck at finding packages that don't rely on Microsoft.DI, or Microsoft.Hosting, or what-have-you.

Re: The Rust I wanted had no future

#427
post #419
post #49

Earlier quoted context omitted.

Virtual threads (like java’s loom, erlang’s and goroutines) are arguably that. In case of java there really is no compiler magic even, “just” runtime magic.

how big is the overhead for this? and how much easier is working with virtual threads than Rust's async?

1. Low enough that you don't need to worry for most web backend code and 2. Anything is easier than that. *XYZ is not Send* amiright?

With Rust's async you have to worry about a different worker thread picking up the work after a context switch, which makes things complicated. Not so with Java.

Re: The Rust I wanted had no future

#428
post #227

Earlier quoted context omitted.

The safe thing Rust did here is affordable in Rust (Option is the same size as T for many T including all references) so they could afford to do it, whereas it's expensive in C++. Could it have been made cheaper in C++? Sure, but safety wasn't their priority so who cares? That prioritisation applies to the whole ISO language, not only to the standard library.

Talking about C? https://godbolt.org/z/vYcMhE9h7

You turned on a feature which helps diagnose this type of mistake at runtime, and it helped you by diagnosing the mistake at runtime. What does that prove?

What I'm talking about is that Rust's Option is very cheap in all the cases where it can be very cheap, which makes this whole design feature more affordable. C++ eventually grew std::optional which is not powerful enough for this work and yet is also bigger and slower. They could have done better, but safety wasn't a priority.

Re: The Rust I wanted had no future

#429
post #76

Earlier quoted context omitted.

Its certainly possible with compiler magic. Zig does exactly that - where functions can be colorless and they work slightly differently in async and syncronous contexts, doing the obvious thing in both cases. I'm not sure how well it works in practice (I haven't spent enough time with zig to know). I'd worry that bugs would creep in to whichever variant of the function you aren't exercising. Its a lovely design thoug…

_Unyielding_ describes the issues that arise when the author of the code doesn't have control of the transactionality / atomicity of their operations at the level they need to: https://glyph.twistedmatrix.com/2014/02/unyielding.html To my mind it's very much a balancing act between "low power to the developer, high power to the language" and "high power to the developer, low power to the language" all up and down the…

See also: https://www.tedinski.com/2018/11/06/concurrency-models.html which is the first article I've ever seen that says that `m:n`-style-green-threads are bad and good at the same time.

TL;DR - he says that "doParallel" and "doConcurrently" are separate operations with distinct semantics that designers of programs must care about and that conflating the two (especially the common "doConcurrently-and-often-but-not-always-in-parallel") is one of the most common causes of bugs in programs that need to make progress in multiple threads of execution.

Re: The Rust I wanted had no future

#430
post #6

Very interesting insight from Graydon, in hindsight I too would have loved something more towards ML than C++. I never liked the kitchen sink approach that I see first C++, now Rust moving towards, but I respect what Rust has managed to solidify into. It's a good language. That said, I still hate async with a passion, it makes the language more complex and not very elegant (i.e. function coloring). And now that I kno…

> That said, I still hate async with a passion, it makes the language more complex and not very elegant (i.e. function coloring).

async in Rust is a popularity issue even more than a technical issue.

A whopping amount of people who are coming to Rust are doing so because they want a good ecosystem for implementing network service servers. Rust/cargo/crates hits the sweet spot for them.

I am with you that I loathe async/await in Rust. However, I also have to acknowledge that without async/await, Rust is a vastly less popular language.

All the other uses of systems programming are simply dwarfed by number of people building network services. That's just the sad reality.

Post reply on HN