4 ms·
I am the author of the original post. Unfortunately, before publishing anything, it's very hard to predict all possible misinterpretations of my text. > I real
by Hirrolot 4y ago
I am the author of the original post. Unfortunately, before publishing anything, it's very hard to predict all possible misinterpretations of my text.
> I really wish the author clearly pointed out that they write the article from a point of view of a library author trying to come up with generic and flexible APIs.
Most commentators viewed the text from the perspective of application programming. You are more close to true: I am a library author and the dispatcher example was concerned with the problems of library maintainers. However, I wrote this post mainly to talk about _language design_.
Rust is ill-suited for generic `async` programming, because when you enter `async`, you observe that many other language features suddenly break down: references, closures, type system, to name a few. From the perspective of language design, this manifests a failure to design an orthogonal language. I wanted to convey this observation in my post.
Additionally, how we write libraries in a given language reveals its true potential, since libraries have to deal with the most generic code, and therefore require more expressive features from language designers. This also affects mundane application programmers though: the more elegant libraries you have, the more easily you can write your application code. Example: language's inexpressiveness doesn't allow you to have a generic runtime interface and change Tokio to something else in one line of code, as we do for loggers.
One gentleman also outlined a more comprehensive list of the `async` failures in Rust [1]. This pretty much sums up all the bad things you have to deal with in generic `async` code.
UPD: I added an explanation section [2] to my original post. Thank you for your feedback, this is very appreciated.
[1] https://www.reddit.com/r/rust/comments/v3cktw/comment/ib0mp49/?utm_source=share&utm_medium=web2x&context=3 https://www.reddit.com/r/rust/comments/v3cktw/comment/ib0mp4...
[2] https://hirrolot.github.io/posts/rust-is-hard-or-the-misery-of-mainstream-programming.html#update-addressing-misinterpretations https://hirrolot.github.io/posts/rust-is-hard-or-the-misery-...
- dgb23 4y agoMy intuition is that async is fundamentally the wrong abstraction. First, you want to get rid of function coloring and make coordination itself explicit. Then you build an abstraction over that, where you can declare or infer whether an operation is commutative or associative and generate/select scheduler logic from that. Right?
- steveklabnik 4y agoThat is a valid way to design things, as long as it doesn’t clash with other goals. It’s not clear that this is possible given all of the other constraints involved that Rust is attempting to fit together. Doesn’t mean it’s impossible, but the possibility is an open question. This is partially because some of it is subjective! For example, the whole idea that “function coloring” is inherently bad is not a given in a language like Rust. Languages that want to reach down into the lower levels often make costs fairly explicit. Async and sync functions are significantly different, and so some may argue that in a Rust context, this is a good thing, not a bad one. It’s the same idea with values vs references: in many languages, the difference is papered over, not shown to the end user. But in Rust, it is, and this does lead to some ceremony if you want to call a function that takes one with an argument that’s the other. But nobody is arguing that Rust should totally remove this distinction (other than the fact that references are themselves values but that’s not really relevant here…) due to some sort of two colored functions. However, some do want this for mutable vs immutable references. Tl;dr it’s not that simple, in many contexts.
- throwawaymaths 4y agoThis is basically what zig does "async", though it's not coordination so much as "context switching control flow points" that are made explicit. It's very low to the metal and if you think about what the machine is "actually doing" it makes a ton of sense, and it's kind of a "shift" in the way of thinking about things in the same way that pointers are. I rather dislike how it's called "async" though. I feel like "reentrant" or "detached" makes more sense, because that's what it feels like to me but if you write your own scheduler you basically have what everyone else calls async. Iirc rust takes an async function and turns it into a abstract state machine, and I feel like this is a surprisingly high level concept for a systems programming language
- 2fast4you 4y agoI'll say. That's how C# handles async too
- 4y ago
- drogus 4y ago> From the perspective of language design, this manifests a failure to design an orthogonal language. I wanted to convey this observation in my post. I wouldn't say it's a "failure". It's an incremental design. This stuff is known to language maintainers and it's being worked on as far as I know. I understand your point of view, but I felt like it would be good to point out that it should be viewed only in a very specific context. > Additionally, how we write libraries in a given language reveals its true potential Yes and no. Rust has many flaws in this context and yet I think it's still one of the best languages out there. Can it be better? Sure, and I hope it will be. Is it good enough for most of its users? Yeah, I think so. > One gentleman also outlined a more comprehensive list of the `async` failures in Rust [1]. This pretty much sums up all the bad things you have to deal with in generic `async` code. I really hate this kind of comments. Saying that async was "rushed" is an insult to all of the people that put so much time and effort into releasing the future. It wasn't rushed, it took years to release it. All of these issues are well known and many people are working on improving the situation and comments like this are not only not constructive - they're actively harmful to the development of the language. To be clear: I don't mind listing things you find frustrating, it's fine. I just don't like doing it in this kind of unconstructive way that basically just burns out language maintainers. I really hope the issues listed there can be resolved in time, but if I had a choice between having async in its current form vs waiting for an ideal release in 10 years, I would vote for releasing it even sooner. Again, it's not ideal, it has lots of problems, but I wrote very successful async web services and there are countless companies that did so too, so I'd say it's good enough.
- dmitriid 4y ago> I wouldn't say it's a "failure". It's an incremental design. I'd say all this is why you don't usually try and bolt on async (and anything doing multithreading, async, parallel, or distribution) after the fact. It has to be in the language from the very beginning.
- ssokolow 4y agoThe bits of Rust that feel "bolted on" were known to Rust's developers prior to the v1.0 freeze. You can go back through the mailing lists and find talk about things like higher-kinded types and guaranteed tail call optimization and all sorts of other things. ...the problem is that doing this sort of stuff in an eagerly evaluated native-compiled imperative language with no GC and an emphasis on C interop is an area of active research. Rust is literally pushing the envelope with things like its take on async/await.