tail calling many resumes

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

tail calling many resumes

Marcus Mason
Hello, I need a way to resume a coroutine in a way that does not blow out my stack in a tail call chain of many calls. Right now when i "return resume(..)" I consume the stack pretty quickly. Would it even be possible to do some sort of "tail resume"?
Reply | Threaded
Open this post in threaded view
|

Re: tail calling many resumes

Roberto Ierusalimschy
> Hello, I need a way to resume a coroutine in a way that does not blow out
> my stack in a tail call chain of many calls. Right now when i "return
> resume(..)" I consume the stack pretty quickly. Would it even be possible
> to do some sort of "tail resume"?

The standard way to handle that kind of scenario is to have some
dispatcher calling the coroutines in a loop. When one coroutine
wants to transfer control to another, it yields with some specific
value that instructs the dispatcher to resume that other coroutine.

-- Roberto
Reply | Threaded
Open this post in threaded view
|

Re: tail calling many resumes

Marcus Mason
Mhm, I'm using a tuple in yield like `yield("flag", value)` sending messages outward which is has been a nice so far. However my issue is I have a tail recursive function call (necessarily so too), and due to some control flow I ended up needing in those recursive calls I have ended up with a resume in the tail position wrapping the old call.
After thinking hard about it I cannot see a way in which lua could prevent a c overflow here which is not necessarily a problem.
All told I'll probably have take another approach, although I do wonder if some construct like a non-local return with a delimited extent (a single use coroutine effectively) would be a fun experiment.

On Tue, Mar 23, 2021 at 4:02 PM Roberto Ierusalimschy <[hidden email]> wrote:
> Hello, I need a way to resume a coroutine in a way that does not blow out
> my stack in a tail call chain of many calls. Right now when i "return
> resume(..)" I consume the stack pretty quickly. Would it even be possible
> to do some sort of "tail resume"?

The standard way to handle that kind of scenario is to have some
dispatcher calling the coroutines in a loop. When one coroutine
wants to transfer control to another, it yields with some specific
value that instructs the dispatcher to resume that other coroutine.

-- Roberto
Reply | Threaded
Open this post in threaded view
|

Re: tail calling many resumes

Robert Burke
Hello,

A while ago I created a fake version of the coroutine functions that
wrap the real ones and behave like the real ones, but which use their
own internal stack, and which expose a way to go back and forth
between a deeply nested coroutine and the main thread. I thought it
would be a nice way to solve an issue where Hammerspoon assumed that
there would only ever be one lua_State. It may also help solve the
long-open problem of "How do I periodically interrupt the execution of
an arbitrary Lua program (after running some initialization code) to
run my C code, then go back to running the Lua program?"

That said, I haven't really used it for anything substantial, so it
may have issues.

You can get the code here:
https://github.com/sharpobject/co_wrap/blob/master/co_wrap.lua

On Wed, Mar 24, 2021 at 8:21 AM Marcus Mason <[hidden email]> wrote:

>
> Mhm, I'm using a tuple in yield like `yield("flag", value)` sending messages outward which is has been a nice so far. However my issue is I have a tail recursive function call (necessarily so too), and due to some control flow I ended up needing in those recursive calls I have ended up with a resume in the tail position wrapping the old call.
> After thinking hard about it I cannot see a way in which lua could prevent a c overflow here which is not necessarily a problem.
> All told I'll probably have take another approach, although I do wonder if some construct like a non-local return with a delimited extent (a single use coroutine effectively) would be a fun experiment.
>
> On Tue, Mar 23, 2021 at 4:02 PM Roberto Ierusalimschy <[hidden email]> wrote:
>>
>> > Hello, I need a way to resume a coroutine in a way that does not blow out
>> > my stack in a tail call chain of many calls. Right now when i "return
>> > resume(..)" I consume the stack pretty quickly. Would it even be possible
>> > to do some sort of "tail resume"?
>>
>> The standard way to handle that kind of scenario is to have some
>> dispatcher calling the coroutines in a loop. When one coroutine
>> wants to transfer control to another, it yields with some specific
>> value that instructs the dispatcher to resume that other coroutine.
>>
>> -- Roberto