Python Functional Programming Guide (i): Overview of Functional programming

Source: Internet
Author: User
Tags anonymous closure data structures sort versions in python

This article mainly introduces Python functional Programming Guide (i): Functional Programming Overview, this article explains what is functional programming overview, what is functional programming, why the use of functional programming, how to identify functional style and other core knowledge, the need for friends can refer to the

1. Functional Programming Overview

1.1. What is functional programming?

Functional programming uses a series of functions to solve the problem. The function only accepts input and produces output, and does not contain any internal state that can affect the resulting output. In any case, invoking a function with the same parameters always produces the same result.

In a functional program, the input data "flows through" a series of functions, each of which produces output according to its input. Functional style avoids writing a function that has a "boundary effect" (side effects): Modifying the internal state, or other changes that cannot be reflected on the output. Functions that have absolutely no boundary effects are called "pure functional" (purely functional). Avoiding the boundary effect means that the data structure that is mutable when the program is run is not used, and the output depends only on the input.

Functional programming can be thought to stand on the opposite side of object-oriented programming. Objects typically contain internal states (fields), and many functions that modify these states, and programs are composed of constantly changing states; functional programming avoids state changes and works by passing data streams between functions. But that's not to say that you can't use both functional programming and object-oriented programming, and in fact, complex systems typically use object-oriented technology, but mixing functional styles gives you the added benefit of functional style.

1.2. Why use functional programming?

Functional styles are often considered to have the following advantages:

1. Logic can be verified

This is an academic advantage: no boundary effect makes it easier to logically prove that the program is correct (rather than passing the test).

2. Modular

Functional programming advocates the simple principle that a function only does one thing, splitting large functions into as small a module as possible. Small functions are easier to read and check for errors.

3. Modular

Small functions are more likely to be combined to form new functions.

4. Easy to debug

Fine-grained, well-defined functions make debugging easier. When the program is not running properly, each function is to check the data is correct interface, can be faster to eliminate the problem of code, to locate the problem where.

5. Easy to test

Functions that do not depend on the state of the system do not need to construct test piles before testing, making it easier to write unit tests.

6. Higher productivity

Functional programming produces less code than other technologies (often about half of other technologies) and is easier to read and maintain.

1.3. How to identify functional style?

Languages that support functional programming typically have the following characteristics, and code that uses these features in large numbers can be considered functional:

function is a first-class citizen

The function can be passed as a parameter or returned as a return value. This feature makes the template-method pattern very easy to write, which also prompts the pattern to be used more frequently.

Take a simple set sort as an example, assuming that LST is a set of numbers, and that you have a sort method sort needs to determine the order as an argument.

If a function cannot be used as an argument, then the LST sort method can only accept ordinary objects as arguments. So we need to first define an interface, then define a class that implements the interface, and finally pass an instance of the class to the sort method, which calls the Compare method of the instance by sort, like this:

The code is as follows:

#伪代码

Interface Comparator {

Compare (O1, O2)

}

LST = List (range (5))

Lst.sort (Comparator () {

Compare (O1, O2) {

return O2-O1//reverse order

})

As we can see, we define a new interface, a new type (here is an anonymous class), and a new object to invoke only one method. What if this method can be passed directly as a parameter? It should look like this:

The code is as follows:

def compare (O1, O2):

return O2-o1 #逆序

LST = List (range (5))

Lst.sort (Compare)

Note that the previous code has used anonymous class techniques to save a lot of code, but it's still not as simple and natural as the direct transfer function.

anonymous function (lambda)

Lambda provides the ability to quickly write simple functions. For occasional acts, lambda lets you no longer need to jump to another location to write a function while coding.

A lambda expression defines an anonymous function, and if the function is used only in the coded position, you can define it in the field and use it directly:

The code is as follows:

Lst.sort (Lambda O1, O2:o1.compareTo (O2))

Believe from this small example you can also feel the strong production efficiency:

Built-in template functions for encapsulating control structures

In order to avoid the boundary effect, functional style avoids the use of variables as much as possible, and the only temporary variables that are defined in order to control the process are undoubtedly the most unavoidable.

If we need to filter just a few sets to get all the positive numbers, the instruction-style code should look like this:

The code is as follows:

Lst2 = List ()

For I in range (len (LST)): #模拟经典for循环

If Lst[i] > 0:

Lst2.append (Lst[i])

This code shows the whole process of creating a new list, looping, taking out elements, judging, adding to a new list, as if the interpreter were a fool who needed hands-on guidance. However, the "filter" action is very common, why can't the interpreter master the filtering process, and we just need to tell it the filter rules?

In Python, filtering is implemented by a built-in function named filter. With this function, the interpreter learns how to "filter", and we just have to tell it to the rule:

The code is as follows:

Lst2 = filter (lambda n:n > 0, LST)

The benefits of this function are more than simply writing a few lines of code.

After encapsulating the control structure, the code simply needs to describe the functionality rather than the practice, so that the code is clearer and more readable. Because it avoids the interference of the control structure, the second piece of code clearly makes it easier to understand its intent.

In addition, because the index is bypassed, it is unlikely that the code will trigger the subscript to cross this anomaly unless you manually create one.

Functional programming languages typically encapsulate several common actions such as "filtering" as template functions. The only drawback is that these functions require a small amount of learning costs, but this should not obscure the benefits of using them.

Closure (closure)

A closure is a function of a variable (but not a global variable) that is bound to an external scope. In most cases, an external scope refers to an external function.

The closure contains a reference to the variable name in the body of the function and in the external function required. Referencing a variable name means that the variable name is bound, not the object to which the variable actually points, and if the variable is assigned a value, the new value will be accessible to the closure.

Closures make functions more flexible and powerful. Even if the program runs to leave the external function, the bound variable is still valid if the closure is still visible, and each time you run to the external function, the closure is recreated, the bound variable is different, and you do not have to worry about the variable bound in the old closure to be overwritten by the new value.

Go back to the example of just filtering the set of numbers. Suppose that the 0 boundary value in the filter condition is no longer fixed, but is controlled by the user. If there is no closure, then the code must be modified to:

The code is as follows:

Class Greater_than_helper:

def __init__ (self, minval):

Self.minval = Minval

def Is_greater_than (Self, Val):

return val > Self.minval

def my_filter (LST, minval):

Helper = Greater_than_helper (minval)

Return filter (Helper.is_greater_than, LST)

Please note that we have now written a function my_filter for the filtering function. As you can see, we need to hold another operand minval elsewhere (in this case, class Greater_than_helper).

If closures are supported, because closures can directly use external scope variables, we no longer need to greater_than_helper:

The code is as follows:

def my_filter (LST, minval):

Return filter (lambda n:n > Minval, LST)

It can be seen that closures do not affect readability but also save a lot of code.

Functional programming languages provide varying degrees of support for closures. In Python 2.x, closures cannot modify the values of bound variables, and all modification of bound variables is considered to create a new local variable with the same name and to hide the bound variable. A new keyword nonlocal is added to the Python 3.x to support modifying the binding variable. However, you can always access (read) a binding variable regardless of the level of support.

Built-in immutable data structures

In order to avoid the boundary effect, immutable data structure is an integral part of functional programming. Immutable data structures ensure consistency and greatly reduce the difficulty of troubleshooting problems.

For example, a tuple (tuple) in Python is immutable, and all operations on tuples cannot change the contents of tuples, and all attempts to modify the contents of a tuple will produce an exception.

Functional programming languages typically provide two versions of the data structure (mutable and immutable) and are recommended for immutable versions.

Recursion

Recursion is another way to replace loops. Recursion is actually a common form of functional programming, and can often be seen in some algorithms. But the reason we put it in the end is that we rarely use recursion in general. If a recursive cannot be optimized by a compiler or interpreter, it is easy to generate a stack overflow; on the other hand, complex recursion tends to confuse people, rather than looping clearly, so many best practices point to the use of loops rather than recursion.

The use of recursion is not a concern in this series of essays.

< end of the first section >

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.