Live data from Hacker News

Inside Rust's Async Transform

blag.nemo157.com

71–80 of 84 posts

Re: Inside Rust's Async Transform

#72

Earlier quoted context omitted.

To me, at least, this means that the overhead is substantially greater than zero.

That’s not what that phrase means.

Look, I am really tired of all this. It is very emotionally taxing for nothing. It is not easy to argue in a foreign language about subtle topics.

All I have tried to say is that there are language features based on extensive research. Erlang is one example, Go is another. There are obvious counter examples everyone know and love.

My first comment was about that by making an IO selector a language construct the need call Jetty which calls Netty, which call Shitty is eliminated, and the code could be reduced into a single function with a few helpers. This has been demonstrated by Rob Pike in every single fucking video on Youtube.

Creating another general purpose event-driven framework, Tokio or whatever, is, of course, very rewarding, especially for those imposers who call themselves "engineers", but it seems that engineering as a discipline is about reducing to an optimum, instead of piling up fancy bullshit. Every single video of Joe Armstrong on Youtube is about this very difference. We already have way too many Java frameworks.

We could actually compare into which assembly Go's code with select statement compiles versus Rust's code, including dependencies, but it is so obvious that it is almost frustrating to spell this explicitly. That is why I mentioned LOCs.

It is really frustrating to argue when some unknown idiots are flagging your posts without offering any single reason. BTW, if you want to know how shotings are originated - this is this exactly the way. But don't worry, I am very far away in some third world shithole, and I don't care that much.

In good old times, on LKML and everywhere else smart people would focus on meaning and ignore the style, which is one's own choice, while nowadays they attack our style, ignoring the meaning. So be it.

Just fuck this modern HN with all that SJW idiocy.

Re: Inside Rust's Async Transform

#73
post #50

Earlier quoted context omitted.

The problem with fibers is interop. The moment you need to do some FFI, especially FFI that involves callbacks, things get a lot more complicated, since code you're calling into/through doesn't have any of that fiber magic (and, depending on how you implemented yours, it might actually break it).

Another win for embedded languages/inside-out FFI in my book, since controlling the outside world (C in Snigl's case) makes it trivial to register a trampoline with whatever state needed to deliver the call.

Sure, but now you need C code that needs to be aware of your trampoline, specifically. Good luck if it's an existing library. Also, what happens if there are multiple interleaved C parts of the stack, and the innermost one invokes the trampoline? What happens to the ones in the middle? It all sounds awfully like setjmp/longjmp (which is the one thing that you never do in C if you want to interoperate with anything in a sane fashion).

And I don't think FFI direction matters much. The moment you have callbacks, your stack has interleaving of languages anyway (i.e. X called into Y which called back into X). Does it really matter which language the innermost and the outermost stack frames belong to? You still need to handle the mix in the middle.

Re: Inside Rust's Async Transform

#74
post #49

Earlier quoted context omitted.

Look into continuation-passing style. Semantically , async/await is much like syntactic sugar for CPS (or rather futures, but at the most basic level they can be thought of as single-shot continuations). But ultimately, to make use of async, you need async primitives - something that lets you say "do this in the background somehow, and let me know once you're done". Any async/await call should ultimately end at one o…

It's only semantically CPS in as much as all code is semantically CPS. Thinking about the parallels with CPS does nothing to help, here. Async/await is just like threaded code with the blocking/concurrent calls specially marked.

Except it's not like threaded code, because there aren't necessarily multiple threads. And with a single thread event loop, you don't need locking and other synchronization mechanisms at all, further reinforcing the point.

Async/await is literally all about explicit continuations. It's not about concurrency or parallelism per se, although it can be used in that context.

Re: Inside Rust's Async Transform

#75
post #73

Earlier quoted context omitted.

Another win for embedded languages/inside-out FFI in my book, since controlling the outside world (C in Snigl's case) makes it trivial to register a trampoline with whatever state needed to deliver the call.

Sure, but now you need C code that needs to be aware of your trampoline, specifically. Good luck if it's an existing library. Also, what happens if there are multiple interleaved C parts of the stack, and the innermost one invokes the trampoline? What happens to the ones in the middle? It all sounds awfully like setjmp/longjmp (which is the one thing that you never do in C if you want to interoperate with anything in…

Why? You really only need the C library to be able to pass a data pointer to the callback, and most do.

This sounds like a native compiler perspective to me; with pure VM fibers like Snigl's these are not issues.

It's not about direction, it's about controlling the world from the outside.

You sound more like you're on a mission to prove to the world it's impossible, since Rust didn't manage to get it right.

Re: Inside Rust's Async Transform

#76
post #73

Earlier quoted context omitted.

Sure, but now you need C code that needs to be aware of your trampoline, specifically. Good luck if it's an existing library. Also, what happens if there are multiple interleaved C parts of the stack, and the innermost one invokes the trampoline? What happens to the ones in the middle? It all sounds awfully like setjmp/longjmp (which is the one thing that you never do in C if you want to interoperate with anything in…

Why? You really only need the C library to be able to pass a data pointer to the callback, and most do. This sounds like a native compiler perspective to me; with pure VM fibers like Snigl's these are not issues. It's not about direction, it's about controlling the world from the outside. You sound more like you're on a mission to prove to the world it's impossible, since Rust didn't manage to get it right.

What happens with all the interleaving stack frames when that callback gets invoked?

Re: Inside Rust's Async Transform

#77

I'll take fibers that yield automatically on blocking operations over async/await most days for most tasks. It's slightly less flexible, since you can only wait for one async action at a time per fiber; but a pleasure to use in comparison. But for that you need fibers built in. Go sort of does the same thing, but insists on running fibers in separate threads at its convenience; which means giving up the lovely simpli…

Wren and I'm guessing Lua have fibers that work similarly.

Re: Inside Rust's Async Transform

#78
post #74

Earlier quoted context omitted.

It's only semantically CPS in as much as all code is semantically CPS. Thinking about the parallels with CPS does nothing to help, here. Async/await is just like threaded code with the blocking/concurrent calls specially marked.

Except it's not like threaded code, because there aren't necessarily multiple threads. And with a single thread event loop, you don't need locking and other synchronization mechanisms at all, further reinforcing the point. Async/await is literally all about explicit continuations. It's not about concurrency or parallelism per se, although it can be used in that context.

[deleted]

Re: Inside Rust's Async Transform

#79
post #63

I'll take fibers that yield automatically on blocking operations over async/await most days for most tasks. It's slightly less flexible, since you can only wait for one async action at a time per fiber; but a pleasure to use in comparison. But for that you need fibers built in. Go sort of does the same thing, but insists on running fibers in separate threads at its convenience; which means giving up the lovely simpli…

Have you given Erlang a look? What it calls processes sound like what you call fibers; although it does have quasi-premptive yielding as well as yielding when waiting for a message. Since Erlang is built on async message passing, you can easily send a request and block on the response, but you can also send multiple requests and process the responses as they arrive.

Sure, I played with Erlang back in the days. Preemptive kills the whole idea, which is why you can't share values. And it's probably the least integrated language I've come across.

Re: Inside Rust's Async Transform

#80

I'll take fibers that yield automatically on blocking operations over async/await most days for most tasks. It's slightly less flexible, since you can only wait for one async action at a time per fiber; but a pleasure to use in comparison. But for that you need fibers built in. Go sort of does the same thing, but insists on running fibers in separate threads at its convenience; which means giving up the lovely simpli…

Wren and I'm guessing Lua have fibers that work similarly.

Lua has fibers? I thought they settled on throwing coroutines over the fence, which is very much not the same thing even though you can sort of build fibers using them. I'm pretty sure Wren's fibers aren't integrated with the IO-layer, but I'd be happy to be wrong there.
Post reply on HN