Fn.py: enjoy FP in Python

by Alexey Kachayev, 2013




  • Twitter: @kachayev
  • Github: @kachayev
  • What we are going to talk about?



      fn.py  


    Prehistory

    Lambdas


    Scala

    List(1,2,3).map(_*2)
    

    Clojure

    (map #(* % 2) '(1 2 3))
    

    Haskell

    map (2*) [1,2,3]
    

    Python ???

    Lambdas


    Python !!!

    from fn import _
    from fn.iters import zipwith
    from itertools import repeat
    
    assert list(map(_ * 2, range(5))) == [0,2,4,6,8]
    assert list(filter(_ < 10, [9,10,11])) == [9]
    assert list(zipwith(_ + _)([0,1,2], repeat(10))) == [10,11,12]
    

    • code readability
    • improve your vision
    • keyboard will work longer

    Streams


    from fn import Stream
    
    s = Stream() << [1,2,3,4,5]
    assert list(s) == [1,2,3,4,5]
    assert s[1] == 2
    assert s[0:2] == [1,2]
    
    s = Stream() << range(6) << [6,7]
    assert list(s) == [0,1,2,3,4,5,6,7]
    
    def gen():
        yield 1
        yield 2
        yield 3
    
    s = Stream() << gen << (4,5)
    assert list(s) == [1,2,3,4,5]

    Streams


    And that's it ???

    Fibonacci in Haskell


    fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
    

    Usage:

    Prelude> take 10 fibs
    [0,1,1,2,3,5,8,13,21,34]
    Prelude> take 20 fibs
    [0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181]

    Fibonacci in Clojure


    user> (def fib (lazy-cat [0 1] (map + fib (rest fib))))
    user> (take 10 fib)
    (0 1 1 2 3 5 8 13 21 34)
    user> (take 20 fib)
    (0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181)

    Fibonacci in Scala


    def fibs: Stream[Int] = 
        0 #:: 1 #:: fibs.zip(fibs.tail).map{case (a,b) => a + b} 

    Usage:

    scala> fibs(10)
    res0: Int = 55
    scala> fibs.take(10).toArray
    res1: Array[Int] = Array(0, 1, 1, 2, 3, 5, 8, 13, 21, 34)
    scala> fibs.take(20).toArray
    res2: Array[Int] = Array(0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181)

    Fibonacci in Python


    And what about Python ???

    Fibonacci in Python


    from fn import Stream
    from fn.iters import take, drop, map
    from operator import add
    
    f = Stream()
    fib = f << [0, 1] << map(add, f, drop(1, f))
    
    assert list(take(10, fib)) == [0,1,1,2,3,5,8,13,21,34]
    assert fib[20] == 6765
    assert fib[30:35] == [832040,1346269,2178309,3524578,5702887]

    Need more?


    • Simple syntax for partial application and composition
    • 22 additional itertools recipes
    • [TBD] Trampoline decorator
    • [TBD] Functional errors-handling
    • [TBD] Benchmarks, optimization, C-accelerators

    Want to help?


    • Use it and enjoy FP
    • Post bugs, ideas, advices, patches
    • Tell your friends



    Thanks for your attention