# chapter=3 variant=concurrent 
def make_mutex():
    cell = llist(False)
    def the_mutex(m):
        return ((the_mutex("acquire")  # retry
                 if test_and_set(cell)
                 else True)
                if m == "acquire"
                else clear(cell) if m == "release"
                else error("unknown request -- mutex", m))
    return the_mutex

def clear(cell):
    set_head(cell, False)
def make_serializer():
    mutex = make_mutex()
    def serializer(f):
        def serialized_f():
            mutex("acquire")
            val = f()
            mutex("release")
            return val
        return serialized_f
    return serializer
def deposit(account, amount):
    account("deposit")(amount)
def make_account_and_serializer(balance):
    def withdraw(amount):
        nonlocal balance
        if balance > amount:
            balance = balance - amount
            return balance
        else:
            return "Insufficient funds"
    def deposit(amount):
        nonlocal balance
        balance = balance + amount
        return balance
    balance_serializer = make_serializer()
    return lambda m: (balance_serializer(withdraw) if m == "withdraw"
                      else balance_serializer(deposit) if m == "deposit"
                      else balance if m == "balance"
                      else balance_serializer if m == "serializer"
                      else error("unknown request -- make_account", m))

my_account = make_account_and_serializer(300)
deposit(my_account, 100)
print(display(my_account("balance")))
