Continuation Passing Paradigm#

Initial Set-Up#

from typing import Callable, Any
from functools import partial


def validate_result(expected: int) -> Callable[[int], None]:
    def validate_input(actual: int) -> None:
        assert actual == expected, actual

    return validate_input


def loop(
    function: Callable[[int, Callable[[int], None]], None],
    n: int,
    continuation: Callable[[int], None],
    *args: int
) -> None:
    if n <= 0:
        continuation(*args)
        return

    aux = partial(function, continuation=continuation)
    for _ in range(n - 1):
        aux = partial(function, continuation=aux)
    aux(*args)

Predecessor and Successor#

def predecessor(a: int, continuation: Callable[[int], Any]) -> None:
    continuation(a - 1)


predecessor(1, validate_result(0))
predecessor(10, validate_result(9))
def successor(a: int, continuation: Callable[[int], Any]) -> None:
    continuation(a + 1)


successor(0, validate_result(1))
successor(10, validate_result(11))

Addition#

def addition(addend_1: int, addend_2: int, continuation: Callable[[int], Any]) -> None:
    loop(successor, addend_2, continuation, addend_1)


addition(0, 0, validate_result(0))
addition(1, 0, validate_result(1))
addition(0, 1, validate_result(1))
addition(10, 10, validate_result(20))

Multiplication#

def multiplication(
    multiplicand: int, multiplier: int, continuation: Callable[[int], Any]
) -> None:
    if multiplicand == 0 or multiplier == 0:
        continuation(0)
        return

    fixed_addition = partial(addition, addend_2=multiplicand)
    loop(fixed_addition, multiplier, continuation, 0)


multiplication(0, 0, validate_result(0))
multiplication(2, 0, validate_result(0))
multiplication(0, 2, validate_result(0))
multiplication(10, 10, validate_result(100))

Exponentiation#

def exponentiation(
    base: int, exponent: int, continuation: Callable[[int], Any]
) -> None:
    fixed_multiplication = partial(multiplication, multiplier=base)
    loop(fixed_multiplication, exponent, continuation, 1)


exponentiation(1, 0, validate_result(1))
exponentiation(0, 1, validate_result(0))
exponentiation(3, 3, validate_result(27))