The original design I wanted with piccolo and gc-arena was for Lua to snarf coroutines from Rust.
Let me unpack this to see if I can understand it: if piccolo was not a stackless design, then you couldn’t snarf Rust’s coroutines into Lua, because Lua has full coroutines and Rust doesn’t; that is, Lua coroutines can yield anywhere in the call stack, while Rust’s can only yield from the outermost call. In a naive design, this would make it impossible to use Rust’s more limited coroutines for Lua’s more capable ones, but by making the whole VM stackless, that bypasses the problem because you can just always stay on the outer call where it’s possible to yield?
To me, systems programming languages are languages where if you need to make system A work with system B, no matter what those systems are, you can use them. […] They’re supposed to be the languages with the fewest possible assumptions about how the rest of the world works, because they’re meant to be a host or glue language to inner systems with better assumptions, which are more fit to purpose.
It is so refreshing to hear this articulated from someone who’s obviously a very skilled Rust user. Having no assumptions is great when you’re doing something that pushes at the edges, but it’s exhausting for doing normal, straightforward application programming. Assumptions (in the best case) are guarantees that you just don’t have to think about possibilities X, Y, and Z which simply cannot happen, (for instance, immutable data structures changing out from under you) so you can save your brain power for what you actually care about.
I love this article. A few years ago I was thinking that Erlang would be a nice embedded scripting language since it also runs functions with a certain amount of “fuel” (reductions in Erlang speak). The ability to pause your embedded scripting language seems like a wonderful super power. I also love the way that you can statically compile Lua code into a binary since it is just a C library.
I think this combination of features will be very powerful.
My understanding is that “stackless” is more “the stack of the language being implemented isn’t 1:1 with the language being used to implement it” which is broader than just CPS but does include CPS?
I believe this is necessary when you’re implementing a language with full coroutines in a language that doesn’t have them.
I’m not the author, but as far as I understand it, it is not. CPS means, you make a call, and give it the Info where the code should continue after the call, e.g. by a function pointer. Here, the calls always return to where they were called from.
It stack less because you can pass around the context and continue its execution from anywhere in the stack.
Let me unpack this to see if I can understand it: if piccolo was not a stackless design, then you couldn’t snarf Rust’s coroutines into Lua, because Lua has full coroutines and Rust doesn’t; that is, Lua coroutines can yield anywhere in the call stack, while Rust’s can only yield from the outermost call. In a naive design, this would make it impossible to use Rust’s more limited coroutines for Lua’s more capable ones, but by making the whole VM stackless, that bypasses the problem because you can just always stay on the outer call where it’s possible to yield?
It is so refreshing to hear this articulated from someone who’s obviously a very skilled Rust user. Having no assumptions is great when you’re doing something that pushes at the edges, but it’s exhausting for doing normal, straightforward application programming. Assumptions (in the best case) are guarantees that you just don’t have to think about possibilities X, Y, and Z which simply cannot happen, (for instance, immutable data structures changing out from under you) so you can save your brain power for what you actually care about.
I love this article. A few years ago I was thinking that Erlang would be a nice embedded scripting language since it also runs functions with a certain amount of “fuel” (reductions in Erlang speak). The ability to pause your embedded scripting language seems like a wonderful super power. I also love the way that you can statically compile Lua code into a binary since it is just a C library.
I think this combination of features will be very powerful.
Here “stackless” seems equivalent to “Continuation Passing Style” (CPS), if I understand correctly?
My understanding is that “stackless” is more “the stack of the language being implemented isn’t 1:1 with the language being used to implement it” which is broader than just CPS but does include CPS?
I believe this is necessary when you’re implementing a language with full coroutines in a language that doesn’t have them.
I’m not the author, but as far as I understand it, it is not. CPS means, you make a call, and give it the Info where the code should continue after the call, e.g. by a function pointer. Here, the calls always return to where they were called from.
It stack less because you can pass around the context and continue its execution from anywhere in the stack.