- vừa được xem lúc

Blog#159: 🤔So You Want to be a Functional Programmer (Part 2)🤓

0 0 12

Người đăng: NGUYỄN ANH TUẤN

Theo Viblo Asia

The main goal of this article is to help you improve your English level. I will use Simple English to introduce to you the concepts related to software development. In terms of IT knowledge, it might have been explained better and more clearly on the internet, but remember that the main target of this article is still to LEARN ENGLISH.


Hi, I'm Tuan, a Full-stack Web Developer from Tokyo 😊. Follow my blog to not miss out on useful and interesting articles in the future.

The first step to understanding Functional Programming is the hardest, but it doesn't have to be if you have the right attitude.

Previous parts: Part 1

Friendly Reminder

Read the code carefully and take your time. Make sure you understand it before continuing. Each part of the code builds on the part before it, so if you rush you may miss something important.

Refactoring

Let’s think about refactoring for a minute. Here’s some Javascript code:

function validateSsn(ssn) { if (/^\d{3}-\d{2}-\d{4}$/.exec(ssn)) console.log('Valid SSN'); else console.log('Invalid SSN');
} function validatePhone(phone) { if (/^\(\d{3}\)\d{3}-\d{4}$/.exec(phone)) console.log('Valid Phone Number'); else console.log('Invalid Phone Number');
}

We have written code that is very similar before, but with a few small changes. Instead of copying and pasting the code and then changing it, we should create one function and change the parts that are different. In this example, we would change the value, the regular expression, and the message printed.

The refactored code:

function validateValue(value, regex, type) { if (regex.exec(value)) console.log("Invalid " + type); else console.log("Valid " + type);
}

The old code had two separate functions for Social Security Numbers (ssn) and phone numbers. Now, these two functions have been combined into one, which makes the code easier to maintain. If there is a bug, you only have to fix it in one place instead of searching through the whole codebase to find where the function may have been pasted and modified.

But what happens when you have the following situation:

function validateAddress(address) { if (parseAddress(address)) console.log("Valid Address"); else console.log("Invalid Address");
} function validateName(name) { if (parseFullName(name)) console.log("Valid Name"); else console.log("Invalid Name");
}

We can refactor this by using a value for address and name, and type for 'Address' and 'Name', and replacing the regular expression with a function that takes a string as a parameter and returns true if it parses.

Higher-Order Functions

Some programming languages do not allow you to give a function as an input to another function. Some languages do allow it, but it is not simple to do.

In Functional Programming, a function is a first-class citizen of the language. In other words, a function is just another value.

We can use a single function to do the same thing as two functions by passing one of the functions as a parameter to the other. Even though Javascript is not a purely functional language, we can still use some functional operations with it.

function validateValueWithFunc(value, parseFunc, type) { if (parseFunc(value)) console.log("Invalid " + type); else console.log("Valid " + type);
}

Our new function is called a Higher-order Function.

Higher-order Functions either take functions as parameters, return functions or both.

We can use a higher-order function to check if the four previous functions have found a match. This works in Javascript because if Regex.exec finds a match, it will return a value that is considered to be true.

validateValueWithFunc("123-45-6789", /^\d{3}-\d{2}-\d{4}$/.exec, "SSN");
validateValueWithFunc("(123)456-7890", /^\(\d{3}\)\d{3}-\d{4}$/.exec, "Phone");
validateValueWithFunc("123 Main St.", parseAddress, "Address");
validateValueWithFunc("Joe Mama", parseName, "Name");

It is much better to have one function instead of four that are almost the same. However, the regular expressions used are quite long. We can make our code simpler by taking out the regular expressions.

var parseSsn = /^\d{3}-\d{2}-\d{4}$/.exec;
var parsePhone = /^\(\d{3}\)\d{3}-\d{4}$/.exec;
validateValueWithFunc("123-45-6789", parseSsn, "SSN");
validateValueWithFunc("(123)456-7890", parsePhone, "Phone");
validateValueWithFunc("123 Main St.", parseAddress, "Address");
validateValueWithFunc("Joe Mama", parseName, "Name");

We have improved the way we parse phone numbers so that we don't have to copy and paste the regular expression each time. However, if we have more regular expressions to parse, we need to remember to add .exec to the end of each one, which can be easy to forget.

We can protect ourselves from this by making a special function that gives us the exec function when we call it.

function makeRegexParser(regex) { return regex.exec;
} var parseSsn = makeRegexParser(/^\d{3}-\d{2}-\d{4}$/);
var parsePhone = makeRegexParser(/^\(\d{3}\)\d{3}-\d{4}$/);
validateValueWithFunc("123-45-6789", parseSsn, "SSN");
validateValueWithFunc("(123)456-7890", parsePhone, "Phone");
validateValueWithFunc("123 Main St.", parseAddress, "Address");
validateValueWithFunc("Joe Mama", parseName, "Name");

makeRegexParser takes a regular expression and returns a function, exec, which takes a string. validateValueWithFunc will use this exec function to check if the string, value, matches the regular expression. parseSsn and parsePhone are similar to before, but now use the exec function from makeRegexParser. This is a small improvement, but if makeRegexParser was more complex, it would be more beneficial.

Here’s another example of a higher-order function that returns a function:

function makeAdder(constantValue) { return function adder(value) { return constantValue + value; };
}

Here we have makeAdder that takes constantValue and returns adder, a function that will add that constant to any value it gets passed.

Here’s how it can be used:

var add10 = makeAdder(10);
console.log(add10(20)); // prints 30
console.log(add10(30)); // prints 40
console.log(add10(40)); // prints 50

We create a function, add10, which adds 10 to any number we give it. This is possible because when we create the function, add10, it has access to the constant value 10, even after the function makeAdder returns.

This behavior is called a Closure.

Closures

Here’s a contrived example of functions that use closures:

function grandParent(g1, g2) { var g3 = 3; return function parent(p1, p2) { var p3 = 33; return function child(c1, c2) { var c3 = 333; return g1 + g2 + g3 + p1 + p2 + p3 + c1 + c2 + c3; }; };
}

The child can see the variables of itself, its parent, and its grandparent. The parent can see the variables of itself and its grandparent. The grandparent can only see its own variables.

Here’s an example of its use:

var parentFunc = grandParent(1, 2); // returns parent()
var childFunc = parentFunc(11, 22); // returns child()
console.log(childFunc(111, 222)); // prints 738
// 1 + 2 + 3 + 11 + 22 + 33 + 111 + 222 + 333 == 738

When a function is created, all of the variables in its scope at the time of creation are accessible to it for as long as the function exists. The function will exist as long as there is still a reference to it.

For example, the child's scope will exist as long as childFunc still references it. parentFunc and childFunc keep their respective scopes alive since they both return the parent and child respectively.

A closure is a function’s scope that’s kept alive by a reference to that function.

In Javascript, it can be difficult to use closures because the variables can be changed between the time they are closed over and the time the returned function is used. However, in functional languages, the variables are not able to be changed, which prevents potential problems and confusion.

My Brain!!!!

Enough for now.

In subsequent parts of this article, I’ll talk about Functional Composition, Currying, common functional functions (e.g map, filter, fold etc.), and more.

Up Next: Part 3 (coming soon...)

And Finally

As always, I hope you enjoyed this article and learned something new. Thank you and see you in the next articles!

If you liked this article, please give me a like and subscribe to support me. Thank you. 😊


The main goal of this article is to help you improve your English level. I will use Simple English to introduce to you the concepts related to software development. In terms of IT knowledge, it might have been explained better and more clearly on the internet, but remember that the main target of this article is still to LEARN ENGLISH.

Resource

Bình luận

Bài viết tương tự

- vừa được xem lúc

Giới thiệu Typescript - Sự khác nhau giữa Typescript và Javascript

Typescript là gì. TypeScript là một ngôn ngữ giúp cung cấp quy mô lớn hơn so với JavaScript.

0 0 496

- vừa được xem lúc

Bạn đã biết các tips này khi làm việc với chuỗi trong JavaScript chưa ?

Hi xin chào các bạn, tiếp tục chuỗi chủ đề về cái thằng JavaScript này, hôm nay mình sẽ giới thiệu cho các bạn một số thủ thuật hay ho khi làm việc với chuỗi trong JavaScript có thể bạn đã hoặc chưa từng dùng. Cụ thể như nào thì hãy cùng mình tìm hiểu trong bài viết này nhé (go).

0 0 413

- vừa được xem lúc

Một số phương thức với object trong Javascript

Trong Javascript có hỗ trợ các loại dữ liệu cơ bản là giống với hầu hết những ngôn ngữ lập trình khác. Bài viết này mình sẽ giới thiệu về Object và một số phương thức thường dùng với nó.

0 0 134

- vừa được xem lúc

Tìm hiểu về thư viện axios

Giới thiệu. Axios là gì? Axios là một thư viện HTTP Client dựa trên Promise.

0 0 117

- vừa được xem lúc

Imports và Exports trong JavaScript ES6

. Giới thiệu. ES6 cung cấp cho chúng ta import (nhập), export (xuất) các functions, biến từ module này sang module khác và sử dụng nó trong các file khác.

0 0 93

- vừa được xem lúc

Bài toán đọc số thành chữ (phần 2) - Hoàn chỉnh chương trình dưới 100 dòng code

Tiếp tục bài viết còn dang dở ở phần trước Phân tích bài toán đọc số thành chữ (phần 1) - Phân tích đề và những mảnh ghép đầu tiên. Bạn nào chưa đọc thì có thể xem ở link trên trước nhé.

0 0 228