Dạo này mình đang chuyển sang học tiếp Javascript, tình cờ xem video của anh Hoàng bên toidicodedao thấy có một đoạn ngắn nói về Funcional Programming hay còn gọi là lập trình hàm, mình thấy đây là một xu hướng khá hay. Mình tìm trên các trang nước ngoài thì thấy nó cũng đã được xuất hiện từ vài năm gần đây rồi, nhưng chắc vẫn chưa được nổi lắm ở Việt Nam. Thực sự thì mình không có nhiều kiến thức về nó nên vừa dịch vừa hiểu cho anh em cùng đọc.
Funcional Programming là gì ?
Funcional Programming là quá trình xây dựng phần mềm, mà chỉ dùng hàm thuần, tránh việc chia sẻ trạng thái dữ liệu, dữ liệu có thể thay đổi và các tác động ảnh hưởng đến các thành phần khác. Lập trình hàm là một mô hình mới không hề giống với hướng đối tượng (OOP) hay hướng thủ tục. Trong hướng đối tượng thì trạng thái của dữ liệu luôn được chia sẻ và sử dụng trong các phương thức của đối tượng còn funcional programming thì hoàn toàn ngược lại. Lập trình hàm là sự xây dựng cấu trúc và thành phần của chương trình thay vì sử dụng các câu lệnh để thay đổi trạng thái của chương trình , bạn hoàn toàn có thể dùng nó song song với hướng đối tượng và các trạng thái của ứng dụng được truyền qua các hàm thuần tuý.
Trong lập trình hàm, kết quả trả về chỉ phụ thuộc vào tham số truyền vào, do vậy gọi hàm increase 2 lần với cùng một tham số thì sẽ trả về cùng một giá trị trong mỗi lần.
Như vậy lập trình hàm thì sẽ có những đặc điểm chính sau:
– Sử dụng hàm thuần tuý.
– Tránh việc chia sẻ trạng thái.
– Tránh việc thay đổi trạng thái.
– Tránh sự ảnh hưởng tới các thành phần khác ngoài phạm vi của nó.
Khi sử dụng lập trình hàm thì bạn có thể thay đổi suy nghĩ của mình trong việc viết code, xây dựng ứng dụng mà chỉ dựa trên những thứ cơ bản và định nghĩa các nguyên tắc.
Lập trình hàm chính xác hơn, dễ đoán hơn và đơn giản hơn để kiểm tra hơn các mô hình lập trình khác. Nhưng với một người mới tìm hiểu về mô hình này thì bạn sẽ cảm thấy nó thật rối và dày đặc, và khó hiểu. Một câu được in đậm trong bài viết trên medium.com mà mình thấy khá hay:
Don’t let all the new words scare you away. It’s a lot easier than it sounds.
Pure Functions – Hàm thuần tuý là gì ?
Theo định nghĩa trên Wikipedia thì hàm thuần tuý không có các sự ảnh hưởng tới các thành phần khác, như bộ nhớ của các biến hay input, output.
– Nếu kết quả của một hàm thuần tuý không được sử dụng, nó sẽ được bỏ đi mà không làm ảnh hưởng tới các hàm khác.
– Nếu một hàm thuần tuý được sử dụng với tham số thì sẽ không có sự ảnh hưởng tới tham số truyền vào, có thể được gọi là referential transparency. Do đó nếu bạn gọi hàm này bao nhiêu lần đi nữa thì kết quả vẫn không thay đổi.
– Nếu không có sự phụ thuộc dữ liệu giữ 2 biểu thức thì thứ tự biểu thức hoàn toàn có thể thay đổi nncho nhau hoặc thực hiện song song mà không làm cản trở biểu thức còn lại. Biểu thức ở đây có thể là một hàm hay một phép tính.
Ví dụ như x = x + 1
với giá trị x ban đầu là 1 thì sau 2 lần gọi thì giá trị của x sẽ lần lượt là 2 và 3. Như vậy đã vi phạm vì nó ảnh hưởng tới tham số truyền vào. Do đó cần một hàm như sau int plusOne(int x) { return x + 1; }
, để thực hiện việc tăng thêm 1 cho một giá trị, rõ ràng bạn gọi bao nhiêu lần thì với x bằng 1 thì kết quả vẫn mãi chỉ là 2.
Avoid Shared State – Tránh việc chia sẻ trạng thái
Funcional Programming sử dụng những dữ liệu đã có để thực hiện chuỗi các phép tính và nhận được dữ liệu mới, tránh việc chia sẻ trạng thái.
Một ví dụ nhỏ như sau: Bạn làm phần quản lí thông tin người dùng và có 2 hàm saveUser() và updateAvatar() trong đó hàm updateAvatar() ảnh hưởng tới hàm saveUser(). Trong khi đang thực hiện request saveUser() thì người dùng updateAvatar() và gọi đến hàm saveUser(). Trong khi lưu thì server gửi lại dữ liệu để đồng bộ hết toàn bộ thông tin user với client, mọi sự thay đổi trên server cũng thay đổi trên client. Và thật không may, một lí do nguy hiểm nào đó khiến resquest thứ 2 đến trước request thứ nhất, do vậy mà tự dưng Avatar không được thay đổi, và nó đã được thay thế bởi avatar cũ.
So sánh giữa lập trình hàm và lập trình hướng đối tượng.
Functional Programming | OOP |
---|---|
Sử dụng dữ liệu không thể thay đổi | Sử dụng dữ liệu thay đổi |
Theo Declarative Programming Model. (xây dựng thuộc tính và cấu trúc của chương trình) | Theo Imperative Programming Model (câu lệnh thay đổi trạng thái thái chương trình) |
Tập trung vào: “What you are doing” | Tập trung vào: “How you are doing” |
Hỗ trợ hoạt động song song | Không hỗ trợ hoạt động song song |
Trong hàm không có sự ảnh hưởng ra ngoài | Có sự ảnh hưởng tới các thành phần khác |
Các hàm gọi hàm và đệ quy | Thực hiện trên các vòng lặp và câu lệnh điều kiện |
Sử dụng đệ quy để lặp lại dư liệu (list, array..) | Sử dụng các vòng lặp (for, while, forEach…) |
Thứ tự các câu lệnh không quan trọng vì không có sự ảnh hưởng lẫn nhau | Thứ tự thực hiện cực kỳ quan trọng |
Hỗ trợ “Abstraction over Data” và “Abstraction over Behavior” (trìu tượng hoá dữ liệu và hành động) | Chỉ hỗ trợ “Abstraction over Data”. (trìu tượng hoá dữ liệu) |
Ví dụ về Funcional Programming – Lập trình hàm
Ví dụ in 10 số Fibonaci đầu tiên bằng lập trình hàm bằng PHP và JavaScript:
function fib(int $n) : int { return ($n === 0 || $n === 1) ? $n : fib($n - 1) + fib($n - 2); } for ($i = 0; $i <= 10; $i++) echo fib($i) . PHP_EOL;
Javascipt:
var fib = (x) => (x === 0 || x === 1) ? x : fib(x - 1) + fib(x - 2); fib(10);
Trong React thì bạn có thể thấy một số hàm khá quen thuộc:
.map(); .filter(); .reduce();
Thực sự khi tìm hiểu về phần này mình thấy khá choáng ngợp vì nhiều kiến thức mới với một sinh viên như mình, nhưng qua đó mình cũng thấy được sự rộng lớn của kiến thức, bên ngoài những thứ mình đang sử dụng thì bên trong nó cũng còn nhiều kiến thức sâu mà cần nhiều thời gian mới có thể tìm hiểu được. Bài viết này mình sẽ tiếp tục cập nhật, mình và các bạn tiếp tục tìm hiểu về những công nghệ mới nhé.
Nguồn: Wikipedia, Medium, ToturialsPoint