kiến thức [Event Tặng Title] Hướng dẫn học Javascript từ 0-> Nâng cao.

Em chưa tìm hiểu sâu về Functional Programming là gì, là ntn nhưng đoạn đến đoạn "Khi bạn đưa triết lý FP vào JS nghĩa là bạn sẽ tạm biệt luôn những thứ dưới đây vốn rất quen thuộc với bạn"
Vậy khi code theo kiểu FP là mình ko nên sử dụng vòng lặp for để tính toán trực tiếp mà thay vào đó là phải tạo 1 function truyền tham số vào để xử lý đoạn for đó và trả về kết quả hả bác.
Sử dụng kỹ thuật recursive (đệ quy) bạn nhé
1636599411280.png
 
Có hai mô hình lập trình phổ biến là imperative declarative, mỗi ngôn ngữ lại có thiên hướng theo một trong hai nhánh mô hình lập trình như hình mô tả dưới đây. Vậy thì JS thực sự nó theo thiên hướng nào?
View attachment 861437
Câu trả lời là:
"JavaScript can function as both a procedural and an object oriented language" - theo mozilla.org. Vậy chính xác JS thuộc họ nhà imperative. Nghĩa là chẳng dính dáng gì đến họ nhà declarative ấy thế mà chúng ta lại đi cố tình đưa các triết lý của declarative vào JS. Vậy chẳng lẽ là áp đặt và gượng ép? Quả thực là JS vốn không phải ngôn ngữ sinh ra đã hỗ trợ cho functional programming (FP). Nhưng sau nhiều lần tiến hóa thì đến nay JS đã có những cải tiến để tương thích với các faner của FP qua một loạt thay đổi từ ES6 điển hình là bổ sung arrow function và const. Tóm lại lập trình FP trong JS nghĩa là ta sẽ bê nguyên các triết lý của mô hình FP với các hỗ trợ có sẵn của JS để triển khai. Mặc dù JS ngay đến bản ES6 này chỉ hỗ trợ lập trình FP tương đối nhưng với quan điểm cá nhân của tôi thì "nó cũng ổn đấy"
Nhắc lại thế nào là lập trình FP:
Lập trình chức năng (Functional programming) là một dạng của lập trình khai báo nhưng có chiều sâu hơn nghĩa là trong lập trình FP thì bạn đưa bài toán cho máy tính giải quyết (cái vấn đề bạn cần), song song là ẩn chứa ra cách giải quyết (như thế nào) kèm theo đó là coi việc tính toán là việc triển khai các hàm toán học chủ đích là để thực thi chương trình và tránh các dữ liệu, các trạng thái, luồng chương trình bị thay đổi. FP được hình thành từ cơ sở toán học lambda calculus.

Vì đây là seri viết về JS nên tôi sẽ chỉ tóm tắt nhanh thế nào là lập trình FP thôi.cụ thể thì các bạn cần dành nhiều thời gian nghiên cứu.

Bạn có thể xem ví dụ dưới đây:
View attachment 861597

Khi bạn đưa triết lý FP vào JS nghĩa là bạn sẽ tạm biệt luôn những thứ dưới đây vốn rất quen thuộc với bạn:
  • Loops
    • while
    • do...while
    • for
    • for...of
    • for...in
  • Variable declarations with var or let
  • Conditionals (if, else)

  • Void functions
  • Object mutation.
  • Array mutator methods
    • copyWithin
    • fill
    • pop
    • push
    • reverse
    • shift
    • sort
    • splice
    • unshift
  • Map mutator methods
    • clear
    • delete
    • set
  • Set mutator methods
    • add
    • clear
    • delete
Thay vào đó là chúng ta sẽ sử dụng các hàm toán học để tung hứng, kết hợp và tạo ra luồng chạy cho chương trình. Ngầm chỉ dẫn cho máy tính thực hiện ý đồ lập trình của bạn và máy tính trả kết quả theo đúng kết quả bạn mong muốn.

Cụ thể, mời các bạn xem phần 2 nhé.
những điều mà bác có đề cập đến trong phần "Khi bạn đưa triết lý FP vào JS nghĩa là bạn sẽ tạm biệt luôn những thứ dưới đây vốn rất quen thuộc với bạn"
thì em có thể hiểu là mình sẽ phải sử dụng 2 quy tắc immutable pure functions trong FP
nhưng tại sao lại ko được áp dụng Loop trong FP ạ? vậy trong FP ko dc dùng Loop hả bác?
 
những điều mà bác có đề cập đến trong phần "Khi bạn đưa triết lý FP vào JS nghĩa là bạn sẽ tạm biệt luôn những thứ dưới đây vốn rất quen thuộc với bạn"
thì em có thể hiểu là mình sẽ phải sử dụng 2 quy tắc immutable pure functions trong FP
nhưng tại sao lại ko được áp dụng Loop trong FP ạ? vậy trong FP ko dc dùng Loop hả bác?
Bạn dùng loop (kiểu while, for, forEach..) cũng chẳng sao miễn là bạn blocked được variable scope trong function miễn nó k tác động đến các scope khác thì vẫn đảm bảo immutable. Đấy là phong cách lập trình của cá nhân của bạn (cũng có thể gọi là FP kiểu mới), EX:

JavaScript:
function destroyCompleted() {
 _todos.forEach(function(todo) {
  if (todo.complete) {
   destroy(todo.id)
  }
});
}

còn FP thuần túy nó vốn sử dụng nền tảng toán học lambda nên người ta dùng đệ quy để lặp (immutable inside immutable = pure function), thỏa mãn Yf=f(Yf). Nghĩa là đã FP nguyên thủy thì nó bám theo nguyên tắc toán học lambda calculus.

1636620340897.png
 
Last edited:
Chốt hạ phần Functional programming JS.
Thú thực với ae là tôi không theo đạo phái nào sấc. Functional, Object-Oriented, và Procedural Programming tôi code tất. Nhiều ae sinh viên chưa đi làm thì còn mộng mơ theo phái này phái kia nhưng đi làm rồi thì đồng tiền nó quyền lực hơn tất cả, nó mới là cú quyết định bạn làm cái gì, theo cái gì. Lý do:

Boss cùng team dev thống nhất (biểu quyết hơn 50%) project này code theo style OOP, project kia code theo stype FP... bạn làm dever có dám bật lại cả cty để ép mọi người code theo style của bạn không? Trừ phi bạn là Messi :big_smile: Rồi cả team chốt với nhau project theo OOP, khách hàng cứ một mực Procedural Programming thì làm sao? không theo thì khách đi chỗ khác.

Còn thế này nữa.... bạn vào dự án vốn dự án ấy theo OOP nhưng bạn lại cứ code theo Procedural Programming hay FP thì cũng team cũng cho bạn out thôi.

Thôi thì là vozer-dever lương 350 củ thì mô hình nào cũng nên vững vàng để là một chiến binh dev. Đi làm nó lại không dễ dàng theo đam mê trừ phi bạn làm startup.

Còn với JS, lập trình FP nó cũng có nhiều cái hay ho. Hay nhất là giảm sự phức tạp của chương trình bằng cách phân tán ra các function, áp dụng tốt được phép tính lambda cho các bài toán phức tạp trở nên đơn giản. Mà bản thân JS là dynamic language nên xuyên suốt project, chỗ nào bạn cần blocked lại dữ liệu tránh bị đột biến thì lập trình FP cực kỳ hữu dụng (các mô hình khác vẫn làm được nhưng FP nó đơn giản hơn).

Ngoài ra thì FP nó còn giải quyết được vấn đề xử lý dữ liệu lớn. Vì concept là Data is immutable nên thích hợp cho việc chạy nền web worker tạo parallel programming (lập trình song song).
...
Thế thôi, có mấy cái ý chính là vậy! Trên mạng viết nhiều về FP for JS rồi, ae thoải mái tham khảo. Nhưng có một lưu ý là muốn đi sâu vào FP thì nên hiểu kỹ về các biểu thức lambda.

:p ok!
 
Last edited:
Em chưa tìm hiểu sâu về Functional Programming là gì, là ntn nhưng đoạn đến đoạn "Khi bạn đưa triết lý FP vào JS nghĩa là bạn sẽ tạm biệt luôn những thứ dưới đây vốn rất quen thuộc với bạn"
Vậy khi code theo kiểu FP là mình ko nên sử dụng vòng lặp for để tính toán trực tiếp mà thay vào đó là phải tạo 1 function truyền tham số vào để xử lý đoạn for đó và trả về kết quả hả bác.
Cháu chưa được thầy dạy đệ quy tính Fibocanoci, tính Giai Thừa ở môn nhập môn lập trình C à ? Hay tiết đó cháu không đi học:amazed:
 
Cháu chưa được thầy dạy đệ quy tính Fibocanoci, tính Giai Thừa ở môn nhập môn lập trình C à ? Hay tiết đó cháu không đi học:amazed:
Cái đó cháu giỏi lắm chú. Mấy cái đó dư sức làm đc. Nhưng cháu vẫn chưa hiểu là chú muốn nói gì.
Hay mấy cái chú nói chính là lập trình theo hướng FP ạ
 
Nhưng cháu vẫn chưa hiểu là chú muốn nói gì.
Tao muốn rep câu bên dưới của mày đó
Vậy khi code theo kiểu FP là mình ko nên sử dụng vòng lặp for để tính toán trực tiếp mà thay vào đó là phải tạo 1 function truyền tham số vào để xử lý đoạn for đó và trả về kết quả hả bác.
 
Tao muốn rep câu bên dưới của mày đó
Vậy khi code theo kiểu FP là mình ko nên sử dụng vòng lặp for để tính toán trực tiếp mà thay vào đó là phải tạo 1 function truyền tham số vào để xử lý đoạn for đó và trả về kết quả hả bác.
À sau khi chú nói thì hình như sau 1 lúc suy ngẫm thì con nghiệm ra đc 2 điều như sau về FP:
1- Tạo ra 1 FP mà nó thực hiện các phép toán, tính toán với các tham số truyền vào nhưng không làm thay đổi giá trị của chúng. Thì đây đc gọi là pure function.
2- Một function nhận tham số là 1 function khác và nó thực hiện cái function được truyền vào đó => Điều này hơi na ná giống đệ quy.
Không biết mấy thứ cháu ngộ ra có đúng ko chú. Chú góp ý cho cháu với chú
 
Em chưa đi sâu vào FP bao giờ, cho em hỏi dùng đệ quy trên một tập dữ liệu lớn quá stack size của JS thì xử lý thế nào nhỉ?
Stack Overflow nếu bạn không sử dụng tail recursion. Còn sử dụng tail recursion nó nhanh hơn vòng lặp for-loop ở vài case, còn đâu ngang ngang nhau.

JavaScript:
function Fibonacci2 (n , ac1 = 1 , ac2 = 1) {
    if( n <= 1 ) {return ac2};
    return Fibonacci2 (n - 1, ac2, ac1 + ac2); // đệ quy đuôi
}
console.time("looping #2");
console.log(Fibonacci2(45)); 
console.timeEnd("looping #2");
 
@cs_50i Nodejs vẫn chưa optimize cho tail call thì phải. Code vầy báo stackover flow. Em copy từ đây thôi: https://stackoverflow.com/questions/33923/what-is-tail-recursion
Notice của thím trên đấy
while tail call optimization is part of the ECMAScript 2015 spec, most JavaScript interpreters don't support it.

JavaScript:
function recursionSumTailCall(x, total){
  if(x === 0){
    return total;
  }
  return recursionSumTailCall(x - 1, total + x);
}
var res = recursionSumTailCall(33000, 0);
console.log(res);
--------------------------
function recursionSumTailCall(x, total = 0){
                             ^
                             
RangeError: Maximum call stack size exceeded
 
@cs_50i Nodejs vẫn chưa optimize cho tail call thì phải. Code vầy báo stackover flow. Em copy từ đây thôi: https://stackoverflow.com/questions/33923/what-is-tail-recursion
Notice của thím trên đấy


JavaScript:
function recursionSumTailCall(x, total){
  if(x === 0){
    return total;
  }
  return recursionSumTailCall(x - 1, total + x);
}
var res = recursionSumTailCall(33000, 0);
console.log(res);
--------------------------
function recursionSumTailCall(x, total = 0){
                             ^
                           
RangeError: Maximum call stack size exceeded
Vậy thì bạn phải chờ thôi. Dù sao JS nó cũng đang dần dần update để thích hợp với FP. Đợi nó hoàn thiện thì chắc k lâu lắm đâu, các engine liên quan đến JS nhanh nhạy update phết.
 
Vậy thì bạn phải chờ thôi. Dù sao JS nó cũng đang dần dần update để thích hợp với FP. Đợi nó hoàn thiện thì chắc k lâu lắm đâu, các engine liên quan đến JS nhanh nhạy update phết.
Bác xem cái sự "dần dần update" ở đâu vậy ạ
 
Vậy thì bạn phải chờ thôi. Dù sao JS nó cũng đang dần dần update để thích hợp với FP. Đợi nó hoàn thiện thì chắc k lâu lắm đâu, các engine liên quan đến JS nhanh nhạy update phết.
Em hỏi cho vui thôi, chứ muốn code FP em sẽ không chọn JS, nên chờ làm gì đâu :v Trước có làm dự án Elixir rồi mà không thích trường phái này lắm.
 
Back
Top