suned / pfun

Functional, composable, asynchronous, type-safe Python.

Home Page:https://pfun.dev/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

IO Monad should be stack safe

suned opened this issue · comments

There are currently multiple ways to produce RecursionError when working with IO.

Some IO classes hold a "continuation" function to pass the result to, once the IO action is run (such as ReadFile). When composing a large number of ReadFiles with and_then calling run will unfold this large stack of recursive calls to the lambda created in and_then and cause a RecursionError:

from pfun.io import read_file, sequence

action = sequence([read_file('test.txt') for _ in range(5000)])
action.run()  # RecursionError

Other instances hold references to other IO actions (such as Put). Composing a large number of these instances will cause a RecursionError while building the structure because it calls and_then recursively.

from pfun.io import put_line, sequence

sequence([put_line('test') for _ in range(5000)])  # RecursionError

Ideally both types of calls should never cause a RecursionError. This should be achievable by trampolining appropriately (see pfun.trampoline and e.g pfun.reader for a usage example). Ideally this should be solved without changing the api.