JavaScript and functional programming

Source: Internet
Author: User
Tags javascript currying

Author: yueying
Remember: function programming is not a function programming !!!
23.4 functional programming
23.4.1 what is functional programming

What is functional programming? If you ask in such a straightforward way, you will find that it is a concept that is not easy to explain. Many veterans who have years of experience in programming cannot clearly understand what functional programming is studying. Functional programming is indeed a strange field for programmers familiar with procedural programming. closure, continuation, and currying) these concepts seem so strange that they have no similarities with the if, else, And while concepts we are familiar. Although functional programming has a beautiful mathematical prototype that is incomparable to procedural programming, it is so profound that it seems that only people with a doctorate degree can play it.

Tip: This section is a bit difficult, but it is not necessary to master JavaScript. If you don't want JavaScript to do the work with Lisp, or if you don't want to learn the esoteric techniques of functional programming, you can skip them and enter the next chapter.

So back to this question, what is functional programming? The answer is long ......

The first law of functional programming: The function is the first type.

How can this sentence be understood? What is the real first type? Let's look at the following mathematical concepts:

The binary equation F (x, y) = 0, x, y is a variable, which is written as y = f (x), x is a parameter, and y is the return value, f is a ing from x to y, which is called a function. If G (x, y, z) is 0, or is recorded as z = g (x, y), g is the ing between x, y and z, and is also a function. If the x and y parameters of g meet the preceding relationship y = f (x), then z = g (x, y) = g (x, f (x) is obtained )), here there are two meanings. One is that f (x) is a function on x, and the other is a function at a higher level than f.
In this way, we use z = g (x, f (x) to represent the equations F (x, y) = 0 and G (x, y, z) = 0. It is an iterative function. We can also use another form to represent g and remember z = g (x, y, f). In this way, we generalize function g into a higher-order function. Compared with the previous one, the advantage of this representation is that it is a more general model, such as T (x, y) = 0 and G (x, y, z) we can use the same form to represent the Association solution with = 0 (as long as f = t ). In a language system that supports converting the solution to a problem into a Higher-Order Function Iteration, a function is called the "first type ".
The functions in JavaScript are obviously the "first type ". The following is a typical example:

Array. prototype. each = function (closure)
{
Return this. length? [Closure (this [0])]. concat (this. slice (1). each (closure): [];
}

This is really a Magic Code. It gives full play to the charm of the function type. In the whole code, there is only function and Symbol ). It is simple and powerful.
[1, 2, 3, 4]. each (function (x) {return x * 2}) Returns [2, 4, 6, 8], and [1, 2, 3, 4]. each (function (x) {return X-1}) Returns [, 2, 3].

The essence of function and object orientation is "natural ". If object orientation is a simulation of the real world, the functional model is the simulation of the mathematical world. In a sense, it is more abstract than the object-oriented model, because the mathematical system is inherently abstract beyond the natural world.

Function programming Second Law: closure is a friend of function programming.

Closure, which we have explained in the previous chapter, is very important for functional programming. Its biggest feature is that it can directly access the outer environment from the inner layer without passing variables (symbols), which brings great convenience to function programs under multiple nesting conditions, the following is an example:

(Function outerFun (x)
{
Return function innerFun (y)
{
Return x * y;
}
}) (2) (3 );

Function programming's third law: functions can be curryized ).

What is Currying? It is an interesting concept. Let's start with mathematics: Let's say, consider a three-dimensional spatial equation F (x, y, z) = 0. If we limit z = 0, then we get F (x, y, 0) = 0 is recorded as f' (x, y ). Here f' is obviously a new equation, which represents a two-dimensional projection of the three-dimensional spatial curve F (x, y, z) on the z = 0 plane. Note y = f (x, z), and make z = 0. Then, y = f (x, 0) is obtained, which is recorded as y = f' (x ), let's say that the F' function is a Currying solution of f.
The following is an example of JavaScript Currying:
Function add (x, y)
{
If (x! = Null & y! = Null) return x + y;
Else if (x! = Null & y = null) return function (y)
{
Return x + y;
}
Else if (x = null & y! = Null) return function (x)
{
Return x + y;
}
}
Var a = add (3, 4 );
Var B = add (2 );
Var c = B (10 );

In the above example, B = add (2) is a Currying function of add (), which is a function related to the parameter y when x = 2, note that the closure feature is also used above.

Interestingly, we can generalize Currying for any function, for example:

Function Foo (x, y, z, w)
{
Var args = arguments;

If (Foo. length <args. length)
Return function ()
{
Return
Args. callee. apply (Array. apply ([], args). concat (Array. apply ([], arguments )));
}
Else
Return x + y-z * w;
}

Function programming's fourth law: latency evaluation and continuation.
// TODO


23.4.2 advantages of functional programming

Unit Test

Every symbol in strictly functional programming is a reference to the direct amount or expression result, without the function side effects. Because the value has never been modified somewhere, and no function has modified the amount outside its scope and is used by other functions (such as class members or global variables ). This means that the result of function evaluation is only the return value, and the only parameter that affects the return value is the function parameter.
This is wet dream in the unit tester's dream ). For each function in the tested program, you only need to care about its parameters, instead of considering the function call sequence, and do not need to set the external State with caution. All you need to do is to pass parameters that represent the marginal condition. If every function in the program passes the unit test, you will have a considerable confidence in the quality of the software. However, imperative programming cannot be so optimistic. In Java or C ++, it is not enough to check the function's return value. We must also verify the external state that the function may have modified.

Debugging

If a functional program is not as easy to run as you expected, debugging is also easy. Because the bugs in functional programs do not depend on the Code paths unrelated to them before execution, the problems you encounter can always be reproduced. In imperative programs, bugs are hidden, because the functional dependencies of functions and the side effects of other functions in these programs, you may be exploring for a long time in a direction unrelated to the generation of bugs without any gain. This is not the case for functional programs-if the result of a function is incorrect, no matter what you have previously executed, this function always returns the same error result.
Once you reproduce the problem, finding its root cause will be effortless and even make you happy. Interrupt the execution of that program and check the stack. Like imperative programming, the parameters of each worker function call in the stack are displayed to you. However, in an imperative program, these parameters are not enough. The function also depends on the member variables, global variables, and the state of the class (which in turn depends on many cases ). In a functional program, the function only depends on its parameters, and the information is under your eyes! Also, in an imperative program, checking only the return value of a function does not make you sure that the function is working properly, you also need to check the status of dozens of objects out of the function scope to confirm. All you need to do for a functional program is to view its return value!
Check the function parameters and return values along the stack. If an unreasonable result is found, enter the function and trace it step by step to repeat the process, until it allows you to discover the bug generation point.

Parallel
Function programs can be executed in parallel without any modifications. Don't worry about deadlocks and critical zones, because you have never used locks! No data in a functional program is modified twice by the same thread, let alone two different threads. This means that you can simply add threads without thinking, without causing traditional problems that plague parallel applications.
In fact, why not all applications that require highly parallel jobs use functional programs? Well, they are doing this. Ericsson has designed a functional language called Erlang and used it on Telecom switches that require extremely high error resistance and scalability. Many people have also discovered the advantages of Erlang and started to use it. We are talking about telecom communication control systems, which have higher requirements on reliability and scalability than the typical systems designed for Wall Street. In fact, the Erlang system is not reliable and easy to expand. JavaScript is. The Erlang system is rock solid.
The story about parallelism hasn't stopped yet. Even if your program itself is single-threaded, the compiler of a functional program can still optimize it to run on multiple CPUs. See the following code:

String s1 = somewhatLongOperation1 ();
String s2 = somewhatLongOperation2 ();
String s3 = concatenate (s1, s2 );

In function programming languages, the compiler analyzes the code, identifies potentially time-consuming functions that create strings s1 and s2, and then runs them in parallel. This is not possible in imperative languages, because each function may modify the State outside the function scope and its subsequent functions will depend on these modifications. In functional languages, automatically analyzes functions and finds out the candidates for parallel execution functions, which are simply like automatic function inner join! In this sense, functional-style programs are "future technologies" (even if you don't like industrial terms, but this is an exception ). Hardware vendors are no longer able to make the CPU run faster, so they have increased the processor core speed and increased the speed by four times for parallel processing. Of course, they also forgot to mention that our spending is only on software that solves parallel problems. A small part of imperative software and 100% of functional software can run directly on these machines in parallel.

Code hot deployment

In the past, we had to install updates on Windows. It was inevitable to restart the computer, even if we had installed a new version of media player. Windows XP has greatly improved this status, but it is still not ideal (I run Windows Update when I work today, and now an annoying icon is always displayed in the tray unless I restart the machine once ). Unix systems have been running in a better mode. When installing updates, you only need to stop system-related components, rather than the entire operating system. Even so, this is not satisfactory for a large-scale server application. The telecommunications system must run at 100% of the time, because if an emergency dial failure occurs when the system is updated, it may cause a loss of life. Wall Street companies have no reason to stop the service over the weekend to install updates.
Ideally, no system components are stopped at all to update the relevant code. This is impossible in the imperative world. Consider uploading a Java class at runtime and reloading a new definition, so all instances of this class will be unavailable because they are lost in the Saved state. We can solve this problem by writing some tedious version control code, serialize all instances of this class, and then destroy these instances, then use the new definition of this class to re-create these instances, then load the previously serialized data and want to load the code to just port the data to the new instance. In this case, you need to manually write the code for porting each update, and be cautious in preventing the relationship between objects from being broken. The theory is simple, but the practice is not easy.
For functional programs, all the States that are passed to the function parameters are saved on the stack, which makes hot deployment easy! In fact, all we need to do is compare the code at work with the code of the new version, and then deploy the new code. Other tasks will be automatically completed by one language tool! If you think this is a sci-fi story, think about it again. For many years, Erlang engineers have updated their operating systems without interrupting them.

Machine-assisted reasoning and Optimization

An interesting property of Functional Languages is that they can be inferred in mathematical ways. Because a functional language is just a form of system implementation, all calculations completed on paper can be applied to programs written in this language. The compiler can use mathematical theory to convert a piece of code into equivalent but more efficient code [7]. Relational databases have been doing this kind of Optimization for many years. There is no reason not to apply this technology to conventional software.
In addition, these technologies can be used to prove that some programs are correct, or even tools can be created to analyze code and automatically generate border cases for unit tests! It has no value for the functionality of a solid system, but it is indispensable if you want to design a pace maker or air traffic control system. If the applications you write are not the core task of the industry, such tools are also the killer of your competitors.

23.4.3 functional programming disadvantages

Side effects of closures

In non-strictly functional programming, closures can rewrite the external environment (as we have seen in the previous chapter), which brings side effects. When such side effects frequently occur and often change the running environment, errors become difficult to track.
// TODO:

Recursive form

Although recursion is usually the most concise expression, it is really not as intuitive as a non-recursive loop.
// TODO:

Weakness of the delay Value

// TODO:

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.