If your language religiously omits loops, it's understandable why you'd need to emulate loops this way, but the alternative solution is: have loops in the language.
This leaves us with continuations, which is a great hack, but again, a hack, for languages which don't implement fibers/coroutines/generators natively (see Python generators, see C# await/async, etc.).
This is not the path we have to go down to. Layering hacks upon hacks, so we can implement other hacks on top of it.
If we need loops, have a language with loops. If we need coroutines, the language should implement coroutines.