While reading Peter Norvig's Python IAQ, I came across this code snippet:
def _if(test):
return lambda alternative: \
lambda result: \
[delay(result), delay(alternative)][not not test]()
def delay(f):
if callable(f): return f
else: return lambda: f
fact = lambda n: _if (n <= 1) (1) (lambda: n * fact(n-1))
fact(100)
I searched this in the internet and this code appeared in several forums but it seems that those who commented on it all understand how it works.
I am quite new to functional programming concepts. I know that if test is evaluated to True, delay(alternative) will be selected. But in fact, if test is true, result is returned. This seems counter-intuitive to me.
Let's see:
_if(True) is called, and immediately returns a lambda with the alternative parameteralternative set to 1 and returns the result lambdaresult lambda is called with result set to lambda: n * fact(n-1)
not not True evaluates to 1 (This example is from python 2.4 era!), which indexes the second list item, which is delay(alternative)
alternative was set to 1 earlierdelay(1) is called, which returns lambda: 1
lambda: 1 is called, it returns 1.TL/DR: 1 is the alternative.
Named functions version:
def _if(test):
def then_closure(expr_if_true):
def else_closure(expr_if_false):
if test:
delayed = delay(expr_if_true)
else:
delayed = delay(expr_if_false)
return delayed()
return else_closure
return then_closure
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With