Concepts, forms, and applications of closures

Source: Internet
Author: User
Article Title: Concepts, forms, and applications of closures. Linux is a technology channel of the IT lab in China. Includes basic categories such as desktop applications, Linux system management, kernel research, embedded systems, and open source.

With the improvement of hardware performance, compilation technology, and virtual machine technology, some dynamic languages that have been restricted by performance problems have been concerned, python, Ruby, and Lua have all begun to emerge in applications. Dynamic language has become a favorite programming language for its convenient and fast development method. With the popularity of Dynamic Language, we often hear a term called closure. Many people will ask what the closure is? What is a closure? This article brings together the concepts, applications, and expressions of closures in some programming languages for your reference.
What is a closure?

Closure is not a novel concept. It came into being as early as the age when advanced languages began to develop. Closure is short for Lexical Closure. There are many specific definitions of closures, which can be divided into two types:

One statement is that a closure is a function that meets certain conditions. For example, a closure is defined by reference to a resource. A closure references a function of a free variable (Note 1) in its lexical context.
Another argument is that a closure is a combination of a function and its reference environment. For example, there is a definition in reference resources: When implementing deep constraints (note 2), you need to create something that explicitly represents the reference environment, and bind it with the relevant subroutine, so that the bundled overall is called closure.
These two definitions are opposite in a sense. One considers closure as a function, and the other considers closure as a whole composed of a function and a reference environment. Although I have a bit of information, I can be sure that the second statement is more accurate. Closures are just like functions in form and form, but they are not actually functions. A function is executable code that is determined after the function is defined and does not change during execution. Therefore, a function has only one instance. A closure can have multiple instances at runtime. Different reference environments and the same function combination can generate different instances. The reference environment refers to a set of all the active constraints at a point in the execution of a program. The constraint refers to the relationship between the name of a variable and the object it represents. So why should we combine the referenced environment and functions? This is mainly because sometimes the reference environment of a function cannot be determined directly in languages that support nested scopes. Such a language has the following features:

A function is a First-class value, that is, a function can be used as the return value or parameter of another function, or as the value of a variable.
A function can be nested, that is, another function can be defined within a function.
These concepts are hard to understand. Obviously, a practical example can better illustrate the problem. The syntax of Lua is close to pseudocode. Let's look at a piece of Lua code:


Listing 1. Closure Example 1

Function make_counter ()
Local count = 0

Function inc_count ()
Count = count + 1
Return count

End
Return inc_countendc1 = make_counter () c2 = make_counter () print (c1 () print (c2 ())

In this program, the inc_count function is defined in the make_counter function and serves as the return value of make_counter. The variable count is not a local variable in inc_count. According to the rule of the most nested scope, count in inc_count references the local variable count in the outer function. In the following code, make_counter () is called twice, and the return values are assigned to c1 and c2 respectively. Then, the return values obtained by calling c1 and c2 are printed in sequence.

There is a problem here. When make_counter is called, an instance of the local variable count is generated in its execution context, so the count in the inc_count function references this instance. However, inc_count is not executed at this time, but is returned as a return value. When make_counter returns, its execution context will expire, and the life cycle of the count instance will end. After that, c1 and c2 calls actually call inc_count, this is not in the scope of count, which does not seem to be executed correctly.

The example above illustrates the problems that need to be faced when using a function as the return value. When using a function as a parameter, there are similar problems. The following example shows how to use a function as a parameter.


Listing 2. Closure Example 2

Function do10times (fn)
For I = 0, 9 do
Fn (I)
End
End

Sum = 0
Function addsum (I)
Sum = sum + I
End

Do10times (addsum)
Print (sum)


Here we can see that the function addsum is passed to the function do10times and is called 10 times in do10times. It is not hard to see that the actual execution point of addsum is inside do10times. It needs to access non-local variable sum, while do10times is not within the scope of sum. This does not seem to work properly.

The problems faced by these two situations are essentially the same. In such a language, if the referenced environment of a function is determined during execution according to the scope rules, the referenced environment may be different from the function definition. To make the two programs run normally, a simple method is to capture the referenced environment at that time during Function Definition and combine it with the function code into a whole. When we call this function as a function, we first overwrite the reference environment to the current reference environment, then execute the specific code, and restore the original reference environment after the call is complete. This ensures that the reference environment for function definition and execution is the same. The entity composed of the reference environment and function code is the closure. Of course, if the compiler or interpreter can determine that the referenced environment of a function in the definition and runtime is the same (note 3), there is no need to combine the referenced environment and code, in this case, you only need to pass the common function. Now we can conclude that the closure is not a function, but similar to the function. Not all passed functions need to be converted to the closure, this is only required for reference functions that may change the environment.

Looking at the above two examples, we will find that the inc_count and addsum functions are not called by name in the code, so they do not need a name at all. Taking the first code as an example, it can be rewritten as follows:


 

[1] [2] [3] [4] [5] Next page

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.