Python TCO

Ivan Molina Rebolledo
- 1 min read

This is just the Python version of https://ivmoreau.com/rust-tail-cail-functions-i/

It's horrible, and I love it. (I also did a pseudo-match "expression")

class TCO:
    pass

class Ret(TCO):
    def __init__(self, value):
        self.v = value

class Rec(TCO):
    def __init__(self, *args):
        self.v = args

def tco(f):
    def g(*args):
        c = f(*args)
        while True:
            if isinstance(c, Ret):
                return c.v
            else:
                c = f(*(c.v[0]))
    return g

def match(x):
    def g(*funs):
        for (cmp, fun) in funs:
            if cmp == x:
                return fun()
    return g

@tco
def fib(c, i, j):
    return match(c)(
        (0, lambda: Ret(i)),
        (1, lambda: Ret(j)),
        (2, lambda: Ret(i + j)),
        (c, lambda: Rec((c - 1, j, i + j))),
    )


print(fib(1000000, 0, 1))

Yes, this somehow works, though I don't understand Python tuple destructuring (the v[0] part) all that well.

Haskell and Rust are far superior, but we're not going to have that conversation right now.

It's funny tho. Python is supposed to be easy (I think, lmao), but I just can't get my head around that idea. It has so many weird things. Either you give me a low level language (Rust, C, asm) or a really high level (Haskell, Ocaml, Agda, F#, Scala). I don't like Java, but that's just me hating on bureaucracy, I'm totally fine with Dart/C#/Scala/Kotlin.