Although Python is in fact not a purely functional programming language, it is itself a multilingual language and gives you enough freedom to use functional programming. Functional style has a variety of theoretical and practical benefits (you can find this list in Python's documentation):
form can be verified
Modular Nature
Combination of
Easy to debug and test
Although this list has been described clearly enough, I still like Michael O.church's description of the benefits of functional programming in his article, "Very few functional programs decay (functional programs rarely rot)". I talked about the use of functional methods in Python in "functional programming with Python" during the Pycon UA No. 2012 session. I also mentioned that when you try to write readable and maintainable functional code in Python, you'll quickly find a lot of problems.
The Fn.py class Library was born to deal with these problems. Although it is not possible to solve all the problems, it is a "battery" for developers who want to get the most value from functional programming, even if it is in the command-style dominant program. So, what does it all have?
Scala-style lambda definition
The syntax for creating lambda functions in Python is very lengthy, to compare:
Python
Map (Lambda x:x*2, [1,2,3])
Scala
List (1,2,3). Map (_*2)
Clojure
(Map # (*% 2) ' (1 2 3))
Haskell
Map (2*) [1,2,3]
Inspired by Scala, fn.py provides a special _ object to simplify the lambda syntax.
From FN Import _
Assert (_ + _) (5) =
assert List (Map (_ * 2, Range (5)) = = [0,2,4,6,8]
assert list (filte R (_ < 10, [9,10,11]) = = [9]
In addition, there are many scenarios where you can use _: all arithmetic operations, attribute parsing, method invocation, and slicing algorithms. If you're not sure what your function will do, you can print the results:
From FN Import _
Print (_ + 2) # (x1) => (x1 + 2) "
Print (_ + _ * _) #" (X1, x2, x3) => (x1 + (x2 * x3)) "
Flow (stream) and the declaration of an infinite sequence
A Scala-style lazy evaluation (lazy-evaluated) stream. The basic idea is to take the value on demand for each new element and share the calculated element values in all the iterations that are created. The Stream object supports the << operator, which represents the push of new elements as needed.
The processing of an infinite sequence by an inert value stream is a powerful abstraction. Let's take a look at how to compute a Fibonacci sequence in a functional programming language.
Haskell
fibs = 0:1: Zipwith (+) fibs (tail fibs)
Clojure
(Def fib (lazy-cat [0 1] (map + fib (rest fib)))
Scala
def fibs:stream[int] =
0 #:: 1 #:: Fibs.zip (Fibs.tail). Map{case (a,b) => A + b}
Now you can use the same way in Python:
From the FN import Stream
from the Fn.iters import take, drop, map from
operator import add
f = Stream ()
fib = f & lt;< [0, 1] << map (add, F, drop (1, f))
assert list (take, fib) = = [0,1,1,2,3,5,8,13,21,34]
assert fib[ = = = 6765
assert list (fib[30:35]) = = [832040,1346269,2178309,3524578,5702887]
Trampoline (trampolines) modifier
Fn.recur.tco is a temporary solution that does not require large stack space allocations to handle TCO. Let's start with a recursive factorial calculation example:
def fact (n):
If n = 0:return 1 return
N * Fact (N-1)