Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to understand this Python functional style code by Peter Norvig?

Tags:

python

lambda

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.

like image 825
foresightyj Avatar asked Jan 17 '13 01:01

foresightyj


1 Answers

Let's see:

  • _if(True) is called, and immediately returns a lambda with the alternative parameter
  • The returned lambda is called with alternative set to 1 and returns the result lambda
  • The result 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 earlier
  • delay(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
like image 194
Pavel Anossov Avatar answered Oct 05 '22 22:10

Pavel Anossov