28 ms·
My intuition is that async is fundamentally the wrong abstraction. First, you want to get rid of function coloring and make coordination itself explicit. Then y
by dgb23 4y ago
My 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
- throwawaymaths 4y agoC# is in a highly managed VM, so I can't see how it would be the same as zig. The alternative (high level) way to have "nice" async, which, if c# is similar to zig I think they made "the wrong choice" is to layer async over green threads/cooperative multithreading + message passing/channels. Elixir's Task.async function is I think very well done, leveraging the isolation of erlang's VM and doing a whole ton of things "just right" (a future is process id + unique reference, monitoring the task when you await, e.g)
- 2fast4you 4y agoI was talking just about a sync functions being compiled to a state machine. It’s been awhile but I’m pretty sure C# does the same thing
- throwawaymaths 4y agoGot it. Thanks for clarifying. That seems like a not- unreasonable choice for a HLL like c#, though I'm still baffled they didn't go with something like Task.async