Unravelling `lambda` expressions

When I first wrote my series on Python's syntactic sugar, I left out lambda expressions as I knew I couldn't unravel them without unravelling assignment expressions. Luckily, I solved that problem, so now I can unravel lambda!

If you read the language specification it tells you how a lambda expression unravels semantically. Going from lambda A: B gets you:

def <lambda>(A):
    return B
Simple unravelling of lambda A: B

Now in a proper unravelling, that function would be given a temporary name and then you would call it in the appropriate place, e.g. x + (lambda A: A)(y) would unravel to:

def _lambda(A):
    return A

x + _lambda(y)
Simple unravelling of x + (lambda A: A)(y)

But the one small detail we are missing is the function name: it technically needs to be <lambda>. Now we could be thorough and change the function and code object's names to match, but I don't think many people will check the code object for the name, so we will keep this simple and only worry about the function name:

def _lambda(A):
    return A
_lambda.__name__ = "<lambda>"
Unravelling of lambda A: A

With the unravelling to a function complete, the only other detail to mention is unravelling for everything else still needs to be applied, including assignment expressions. That way any created variable due to an assignment expression operates as expected.