3 ms·
I would highly recommend that the author look into continuation-passing-style - the general construction they discover in their blog just seems to be a reinvent
by gopiandcode 5y ago
I would highly recommend that the author look into continuation-passing-style - the general construction they discover in their blog just seems to be a reinvention of the pretty old observation that we can make any program tail-call recursive if we write it in a CPS form. In fact, in languages like OCaml, it's fairly common to do this transformation to avoid stack overflow (typically paired with a Monad), especially when compiling to JS. The requirement of generators isn't actually needed - you just need first class functions - although, generators and coroutines do allow expressing the code in a slightly more concise way.
- Guvante 5y agoGenerators and such are designed to avoid manually writing contuation passing style which is generally difficult when you need compound state. Especially since Rust makes manual contuation passing style very complex. Generally function pass around references with lifetimes bound to the execution of the function. While continuation passing style does satisfy the constraints needed the compiler can't deduce that thus requiring unsafe code. Generators being built into the compiler can perform that transformation on your behalf and provide the nicer syntax of not having to write out your state explicitly.
- wahern 5y agoNot having to explicitly pass around your state everywhere when you need to resume one routine after calling another is why stacks were invented in the first place! And then when systems began adding concurrent execution of tasks they added these things called processes and threads. And then later the underlying concepts were identified as continuations, generators and coroutines (in order of language-level usefulness). 20 years ago the new, cool advice was that processes and threads were bad. Today, the new, cool advice is that even stacks are bad and it's better to use promises or explicit CPS even in languages that predominately rely on implicit function call stacks. Yet function call stack semantics work so exceedingly well that the people who dislike them rely on them in ways they can't even appreciate. Ditto for processes/threads. Fortunately there are a few languages where the designers and maintainers have the good sense to understand the original function of those abstractions, their relationship to concurrency, and to carry them forth; such as Java (Project Loom) and OCaml (new async runtime--see "One-shot Algebraic Effects as [Stackful, Asymmetric] Coroutines"). Of course, underneath they use simpler mechanisms (e.g. CPS) to present those abstractions, but the majority of the time that's exactly what you want--the OS and compiler to deal with that crap (mostly low-level, irreducible instrumentation for invoking functions) so you don't have to.
- Guvante 5y agoI feel you aren't being fair here. Stacks are an implementation of being able to resume execution after a unit of work is done. That is what is wanted. Rust has generators and async await which covers the most popular form of them. General generators aren't in only due to Rust having a hardcore backwards compatibility guarantee that other than not having an ABI is one of the strongest out there.