Skip to content

Instantly share code, notes, and snippets.

@dhilst
Last active June 23, 2023 02:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dhilst/99bb93c38f5b71448ecd86620b66de98 to your computer and use it in GitHub Desktop.
Save dhilst/99bb93c38f5b71448ecd86620b66de98 to your computer and use it in GitHub Desktop.
tco python with exceptions
from typing import ParamSpec, TypeVar, Callable, reveal_type
T = TypeVar("T")
P = ParamSpec("P")
def tco(f: Callable[P, T]) -> Callable[P, T]:
unwind = False
class Unwind(Exception):
args: P.args
kwargs: P.kwargs
def __init__(self, *args: P.args, **kwargs: P.kwargs) -> None:
self.args = args
self.kwargs = kwargs
def _inner(*args: P.args, **kwargs: P.kwargs) -> T:
nonlocal unwind
if unwind:
raise Unwind(*args, **kwargs)
unwind = True
while True:
try:
result = f(*args, **kwargs)
except Unwind as s:
args = s.args
kwargs = s.kwargs
continue
else:
unwind = False
return result
return _inner
@tco
def recurse(x: int) -> str:
if x <= 0:
return "ok"
return recurse(x - 1)
@tco
def sum(x: int, acc: int) -> int:
if x <= 0:
return acc
return sum(x - 1, acc + x)
print(recurse(1001)) # ok
print(recurse(1001)) # ok
print(sum(1001, 0))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment