Generators in lone lisp
Delimited continuations were not enough. Gotta have more. Gotta have generators.
Lone now features its own dedicated generator type. It will eventually form the foundation of iteration in lone lisp.
( import ( lone print set lambda generator yield ) ( math + ) ) ( set f ( lambda ( x ) ( yield ( + x 1 ) ) ( yield ( + x 2 ) ) ( yield ( + x 3 ) ) x ) ) ( set g ( generator f ) ) ( print ( g 1 ) ) ( print ( g ) ) ( print ( g ) ) ( print ( g ) ) ( print ( g ) )
Generators are also known as semicoroutines: specialized coroutines that only ever yield control back to their own callers. Sounds like an oddly academic distinction to make but it's actually a huge simplification that makes them much easier to not only understand but also to implement.
From delimited continuations to coroutines
Now, there is absolutely no doubt that delimited continuations are powerful abstractions. It's true. Generators could have been built on top of them. I think pretty much any sort of effects system can be built on top of them.
But just because you can doesn't mean you should. There is such a thing as having too much power. It often costs you. Powerful spells spend too much mana. Delimited continuations are no exception. In their case, that cost is called memcpy .
The point of generators is to generate values. That means iteration. Loops. Hot paths. Big lists. Infinite lists. Spinning. Round and round it goes. Over and over again. Eternally. Until it halts. Or not.
So it seems straightforward to conclude that maybe one should not be in the habit of memcpy ing entire stacks back and forth right in the middle of it all. I'll be the first to admit that lone is no paragon of speed but this fails even my considerably lax performance requirements. Can't build a foundation for iteration out of this.
... continue reading