如何实现编程中的拷贝功能
If you are reading this, then most probably you already know quite well what functions are in programming. A function is quite a common and spread programming construct that is present in almost all programming languages.
如果您正在阅读本文,那么很可能您已经非常了解编程中的功能。 函数是几乎所有编程语言中都存在的非常普遍且分散的编程结构。
Generally, a function is a block of code that takes some parameters from outside, executes some operations in which these parameters may be used, then it returns an output value. Actually, in many programming languages functions are allowed to not return something or to return multiple values, not only one. But these cases can be also be represented, for the sake of generality, as only one value. For the “no return” case we can use a special value to represent that (in Python that special value is None; whenever you don’t return something from a function it’s returned None). And for the case of more values, we can use a vector of multiple values as a single object.
通常,函数是一个代码块,它从外部获取一些参数,执行一些可以使用这些参数的操作,然后返回一个输出值。 实际上,在许多编程语言中,函数不返回任何值或返回多个值(不仅是一个值)。 但是为了通用起见,这些情况也可以表示为一个值。 对于“不返回”的情况,我们可以使用一个特殊值来表示该值(在Python中,该特殊值是None;每当您不从函数中返回任何内容时,它都将返回None)。 对于更多值,我们可以将多个值的向量用作单个对象。
For example, in Python a function definition looks like this:
例如,在Python中,函数定义如下所示:
def func_name(param1, param2, ...): # do some stuff with input parameters return output_value
Now, the question I want to ask: Are these functions from programming true mathematical functions?
现在,我要问的问题是:这些函数是否来自编程的真正数学函数?
Well…, let’s first recall what a mathematical function is.
好吧,让我们首先回顾一下数学函数是什么。
In mathematics, a function is just a mapping from a set A to a set B, in which any element from A has only one associated element in B.
在数学中,函数只是从集合A到集合B的映射,其中来自A的任何元素在B中只有一个关联元素。
The following is an example of a function in math, which has 2 integers as input and outputs one rational number:
下面是一个数学函数示例,该函数具有2个整数作为输入并输出一个有理数:
![Image for post](https://miro.medium.com/max/9999/1*wT9ycNzw5hXwuEQGhuU1_Q.png)
One key property of math functions is that each given pair of input values results in only one specific output, or in other words, it’s not possible to evaluate the same function with the same parameters twice and get two distinct outputs.
数学函数的一个关键特性是,每对给定的输入值对只能产生一个特定的输出,换句话说,不可能对具有相同参数的相同函数进行两次评估并获得两个不同的输出。
If we think about this property, it’s not hard to realize that this doesn’t hold for functions in programming.
如果我们考虑一下此属性,不难发现这对于编程中的函数不成立。
We can have functions in programming that return different things for distinct calls of the function, even when the input arguments are the same.
我们可以在编程中使用一些函数,即使输入参数相同,它们也会为函数的不同调用返回不同的内容。
For example, consider the following Python code:
例如,考虑以下Python代码:
i = 0def f(x): global i i += 1 return x+i
If we call f(10) we will get 11 as output value; I mean the first time when we call it. If we call f(10) the second time, we will get 12, then 13, and so on. The variable i is incremented at each function call.
如果调用f(10),我们将得到11作为输出值; 我的意思是第一次调用它。 如果我们第二次调用f(10),我们将得到12,然后是13,依此类推。 变量i在每次函数调用时增加。
So, what we had written above is not a function in the mathematical sense (or a pure function, as they are often called).
因此,我们上面写的不是数学意义上的函数(或者通常称为纯函数)。
The problem here is that our function f does not depend only on its input values; it also depends on a global variable and changes it. This behavior is the reason for which this “function” is not consistent in its output value.
这里的问题是我们的函数f不仅仅取决于它的输入值。 它也取决于全局变量并对其进行更改。 此行为是此“功能”的输出值不一致的原因。
So far, we identified a cause of inconsistent behavior of “functions”: depending on the outside world.
到目前为止,我们确定了“功能”行为不一致的原因: 取决于外部世界 。
Is this the only problem?
这是唯一的问题吗?
Let’s imagine a little bit that we define another Python function, and this time it depends only on its input parameters, no global variables. Think about this before continue reading. This time it is a mathematical function or not?
让我们想象一下,我们定义了另一个Python函数,这次它仅取决于其输入参数,而不取决于全局变量。 在继续阅读之前先考虑一下。 这次是不是数学函数?
![Image for post](https://miro.medium.com/max/9999/1*0pAERer2OJn49DgeMKrfDA.jpeg)
The answer is no. So, what else can go wrong?
答案是不。 那么,还有什么会出错?
The other thing that can be a problem is causing side-effects. That is, besides the process of obtaining the output from input, it is still possible to do things that affect other parts of the program and therefore can determine functions to have inconsistent outputs.
可能成为问题的另一件事是造成副作用 。 也就是说,除了从输入中获取输出的过程之外,还有可能做一些会影响程序其他部分的事情,因此可以确定功能具有不一致的输出。
For example, let’s say we have 2 functions f and g, and both of them take as input a list of integers. The function f adds 1 to the first integer in the list and returns it, and g adds 2 to the first integer and also returns it. But in many programming languages (including Python) lists are passed to functions by reference. This means that if we change the list inside a function, this change automatically takes effect everywhere else. In our example, if we call both f and g at the same time with the input list [1, 2, 3], the addition in f may be executed before the addition in g, and these may return 2, respectively 4, instead of 2 and 3 as we may expect. So, what happens in f may change the output of g or reversely. Therefore, f and g do not depend only on their input and they are not a pure function.
例如,假设我们有2个函数f和g,它们都将整数列表作为输入。 函数f将1与列表中的第一个整数相加并返回它,而g将2与第一个整数相加并返回。 但是在许多编程语言(包括Python)中,列表是通过引用传递给函数的。 这意味着,如果我们更改函数内的列表,则此更改将自动在其他地方生效。 在我们的示例中,如果我们同时使用输入列表[1、2、3]调用f和g,则f的加法可以在g的加法之前执行,并且它们可能分别返回2、4,正如我们所期望的2和3。 因此,在f中发生的事情可能会改变g的输出或相反。 因此,f和g不仅取决于它们的输入,而且它们也不是纯函数。
All right. So, we saw that functions in programming are not necessarily pure functions, and we also saw what the causes of this fact are: dependence on variables other than the input parameters and causing side-effects. But, what’s the problem with this? Why should we be concerned about these programming constructs not being pure functions?
行。 因此,我们看到编程中的函数不一定是纯函数,并且还看到了这一事实的原因是:依赖于除输入参数之外的变量并引起副作用。 但是,这有什么问题呢? 为什么我们要担心这些编程构造不是纯函数?
It turns out that non-pure functions, due to their side-effects, can produce lots of problems. Causing lots of side-effects can make the flow of a program much harder to predict. They can produce some unexpected results.
事实证明,非纯功能由于其副作用而会产生很多问题。 造成许多副作用会使程序的流程更难以预测。 它们可能会产生一些意外的结果。
Mathematical functions, unsurprisingly, had been extensively studied in mathematics, and we know more things about them, and their properties compared to the functions with side-effects which are harder to model mathematically and predict their behavior.
毫无疑问,数学函数已经在数学中进行了广泛的研究,与具有副作用的函数相比,我们对它们有更多的了解,以及它们的性质,而这些副作用很难用数学方法建模和预测其行为。
And those are some of the main reasons for which a new programming paradigm has been born: functional programming.
这些就是新的编程范例诞生的一些主要原因: 函数式编程。
![Image for post](https://miro.medium.com/max/9999/1*VLrblelEhwGRzSmajAjSdw.jpeg)
This paradigm of functional programming aims to use mostly pure functions and makes those it’s main characters. By using only pure functions, programs should have fewer bugs, be easier to debug, test, and prove their correctness.
函数式编程的这种范例旨在主要使用纯函数并将其作为主要特征。 通过仅使用纯函数,程序应具有较少的错误,更易于调试,测试和证明其正确性。
Many of the modern programming languages offer what’s needed for the programmer to be able to write functional code. To name some of them: Python, C++, Java, JavaScript. These languages are called impure functional languages. They are impure because they don’t “force” the programmer to write functional code, they just offer the tools that are needed; it’s up to the programmer to use only pure functions, or to mess around with side-effects.
许多现代编程语言提供了程序员能够编写功能代码所需的功能。 列举其中的一些:Python,C ++,Java,JavaScript。 这些语言称为不纯函数语言 。 它们是不纯净的,因为它们不会“强迫”程序员编写功能代码,而只是提供所需的工具。 程序员只能使用纯函数,也可以避免产生副作用。
There are also so-called pure functional languages, like Haskell, Lean, or PureScript. Contrary to impure languages, these do force the programmer to write the whole program by using only pure functions. Pure functional languages are not quite popular, probably because many people don’t like math, and due to the fact, that creating complex programs using only pure functions can be cumbersome in practice, despite the theoretical benefits.
也有所谓的纯函数式语言,例如Haskell,Lean或PureScript。 与不纯的语言相反,它们确实迫使程序员仅使用纯函数来编写整个程序。 纯函数语言不是很流行,可能是因为许多人不喜欢数学,并且由于这样的事实,尽管具有理论上的好处,但仅使用纯函数创建复杂的程序在实践中会很麻烦。
Pure functions can also have some drawbacks in terms of efficiency. Let’s say we have a big list of numbers (e.g. 1 million) that we want to pass as an argument to a pure function that should do just a little change in one specific term and return the resulting list. Such a function it’s not allowed to make the change directly in the existing list of numbers since that will be a side-effect. So, instead, this function should make first a copy of the original data (those 1 million numbers) into another memory location, make the required change in that copy, then return this new list as its result and let the original list unchanged. This is quite inefficient compared to a non-pure function.
纯函数在效率方面也可能有一些缺点。 假设我们有一个很大的数字列表(例如1百万个),我们希望将其作为参数传递给一个纯函数,该函数应该在一个特定术语中进行一些更改,然后返回结果列表。 这种功能不允许直接在现有数字列表中进行更改,因为这会产生副作用。 因此,该函数应该首先将原始数据(百万个数字)的副本复制到另一个存储位置,在该副本中进行所需的更改,然后返回此新列表作为其结果,并使原始列表保持不变。 与非纯函数相比,这是非常低效的。
So, in my opinion, if one wants to make use of the functional programming paradigm and its benefits, the best way would be to use an impure functional language, which allows more freedom to the style a programmer can adopt, and to simply try to use pure functions as often as it seems reasonable to do so. If at some point, you think that it is worth sacrificing a pure function for the sake of being more efficient or easy to implement, I think that would be fine.
因此,我认为,如果要利用函数式编程范式及其优势,最好的方法是使用一种不纯净的函数式语言,它可以给程序员可以采用的样式提供更多的自由,并且可以尝试尽可能合理地使用纯函数。 如果在某个时候,您认为为了提高效率或易于实现而有必要牺牲一个纯函数,那么我认为这很好。
Thanks for reading!
谢谢阅读!
翻译自: https://towardsdatascience.com/are-functions-from-programming-really-functions-e306fc2d509d
如何实现编程中的拷贝功能