Water pipe model

In this chapter, we want to return to a question, where are the functional and procedural programming ideas? Here we provide an image metaphor.

Process-house objects

In procedural thinking, every variable, function/procedure refers to a symbol that tells you the name of a house. For a static language, we may also need to put something in the room. Then, every time we call a function/procedure, we take out the functions in the corresponding room and the objects in other rooms, rearrange them in the way of functions, and put the results in the original room or in the new room. . (Note that this description is actually similar to a Turing machine.)

However, this house may be more complicated. We may sometimes refer to the situation in another house, or even a house in another house (other modules, third-party plug-ins), or even weather and social news (environmental variables, Hardware) to calculate the logic (ie function) of each sorting object. This is the most confusing thing in the "house-object" model. If the weather is bad, or there is a problem with the condition of other houses, your rules for organizing objects may be very problematic, and it is difficult to trace the cause. We also introduced this issue in 001.

Functional - water pipes and data flow

In functional programming, our model is to fabricate a series of water pipes, and the water pipe is the function in the functional formula. Our goal is to set up the piping system with various function water pipes in advance. Then pour the water (data/immutable parameters) in and wait for the result to flow out from the other end of the water pipe. As shown in the figure below:

stateDiagram-v2

    [*] --> function
    function --> [*]

compose

So far, the easiest thing we can think of is to connect the water pipes. For example, when doing text processing, we are likely to have the following operations. This is a typical water pipe splicing process, we only need to maintain the participle , to lowercase , delete , stemming these functions.

stateDiagram-v2

    [*] --> 分词
    分词 --> 变小写
    变小写 --> 删除stopwords
    删除stopwords --> 词干化
    词干化 --> [*]

Of course, we can pour water into the water pipe step by step, take it out and pour it into another water pipe. Then why don't we just put the water pipes together in advance. This operation is also called compose (represented by the symbol \(\circ\)), and the mathematical expression is as follows:

$$(f \circ g) x = f(g(x))$$

We give a simple implementation Python

from functools import reduce

def compose(*args):
    """数学中的compose

    >>> from fppy.base import compose
    >>> compose(lambda x: x+1, lambda x: x**2)(1)
    >>> 4

    """
    return reduce(lambda f, g: lambda x: f(g(x)), args, lambda x: x)

For example, we can string together the f1 , f2 , f3

>>> f1 = lambda x: x + 1
>>> f2 = lambda y: y * 2
>>> f3 = lambda z: z / 3

>>> compose(f3, f2, f1)(1)
1.3333333333333333

>>> h(g(f(1)))
1.3333333333333333

But sometimes, compose can be confusing. I personally like the following statement of and_then

def and_then(*args):
    return reduce(lambda f, g: lambda x: g(f(x)), args)

Personally, it would be more clear like this:

>>> and_then(f, g, h)(1)
1.3333333333333333

However, in the specific implementation, we have practically realized the concept of functions as parameters. This is also the expression of "functions are first-class citizens" in functional programming, and the specific various plumbing modes (it sounds like we are French plumbers with long beards) We will show them one by one in the following articles.


三次方根
1.2k 声望101 粉丝