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