Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I don't have a degree in CS so I always feel out of my element in these discussions...

Is the runtime something the compiler adds to the binary to make sure it is able to correctly interact with the system it is built for?

It seems like people argue that green threads require a runtime as if async doesn't? I don't understand the arguments on either side. In terms of what code looks like I far prefer being able to just declare green threads like golang does.

Honestly I wish I understood on a deep level, but I've been programming for 17+ years and the fact that I still don't implies to me that I never will.



A Runtime generally refers to "things added to the program to make it work". That can mean libc, it can mean a GC, etc.

> I don't understand the arguments on either side. In terms of what code looks like I far prefer being able to just declare green threads like golang does.

Under the hood `async` is sugar over a function such that the function returns a `Future<T>` instead of a `T`. What is done with that future is up to the caller.

In most cases this is handed off to a runtime (your choice of runtime, generally speaking) that will figure out how to execute it. You could also manually poll the future until it's complete, which does happen sometimes if you're manually implementing the Future trait.

If you have no async code you can simply avoid having an async runtime altogether, reducing the required runtime for an arbitrary program.

> I far prefer being able to just declare green threads like golang does

This relies on an implicit runtime. That's fine - lots of Rust libraries that work the way you're suggesting will just assume a runtime exists.

That lets you write:

    spawn(async {println!("hello from async");});
And, just like a goroutine, it will be scheduled for execution by the implicit runtime (or it will panic if that runtime is not there).

Note that this implicit runtime has to be there or you'll panic. This means that the reasonable behavior would be to always provide such a runtime, which would mean that even "sync" programs would need it. Or otherwise you'd need to somehow determine that no "async" code is ever actually called and statically remove it. That is a major reason why you wouldn't want this model in a language that tries to minimize its runtime.

> but I've been programming for 17+ years and the fact that I still don't implies to me that I never will.

I think it's just a matter of exposure. Try writing in more languages like C, C++, Rust, etc, and dig into these features.


> That's fine - lots of Rust libraries that work the way you're suggesting will just assume a runtime exists.

Is this a new development? Last time I checked, every library seemed to be tied to a specific runtime (usually tokio).


That's what I'm saying. When a library uses "spawn" it is generally assuming a runtime, typically tokio (although in my experience a lot of libraries are generic).


I don’t think that has changed.


I don't really understand when you say that spawning async would be just like a green thread (goroutine). I thought they were fundamentally different.


They aren't different. They are the same. The only difference is that in Go the `yield` points are implicit (the compiler inserts them) whereas in Rust they are explicit (.await).

Otherwise they both schedule a task to be executed with the implicit runtime - in Rust that may be tokio or something else, in Go that would be the Go runtime.


I would say they function similarly. There are quite a few internal differences. The main benefit of Rust is that futures are just regular types and don’t need a stack when idle. And the main benefit of Go is that there is only one type of function, so no coloring.

> they both schedule a task to be executed with the implicit runtime

To be pedantic, in rust the runtime is referenced with a global or thread-local variable, but it’s still explicit. This means crate authors can’t spawn tasks without depending on a runtime… unless there’s been recent developments.


Sure, their implementation differs in all sorts of ways. But for the purposes of this conversation, with regards to scheduling a future without having to manually pin it up into a your call graph, they are the same.

> but it’s still explicit.

I guess it just comes down to your definition of explicit. There's a dependency, but from a caller's perspective it's implicit. It doesn't matter though, I think the point is clear enough.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: