Lập trình hàm đã tồn tại trong hơn 60 năm qua, nhưng cho đến nay nó vẫn luôn là một hiện tượng. Mặc dù những thế hệ sau như Google dựa vào các khái niệm chính của lập trình hàm, nhưng các lập trình viên ngày nay đa phần không biết gì về nó. Điều đó sắp thay đổi khi không chỉ các ngôn ngữ lập trình như Java hay Python ngày càng áp dụng nhiều khái niệm từ lập trình hàm mà các ngôn ngữ mới hơn như Haskell cũng sẽ hoàn toàn hoạt động dựa trên cơ sở của lập trình hàm.
Nói một cách dễ hiểu, lập trình hàm là tất cả các việc xây dựng các hàm cho các biến bất biến. Ngược lại, lập trình hướng đối tượng là việc có một tập hợp các hàm tương đối cố định và chủ yếu sửa đổi hoặc thêm các biến mới. Vì bản chất của nó, lập trình hàm rất tốt cho các tác vụ theo yêu cầu như phân tích dữ liệu,... Điều này không có nghĩa là bạn phải tạm biệt lập trình hướng đối tượng mà thay vào đó chuyển sang hoàn toàn hoạt động. Tuy nhiên, sẽ rất hữu ích khi biết về các nguyên tắc cơ bản để bạn có thể sử dụng chúng khi thích hợp.
Loại bỏ các tác dụng phụ
Để hiểu lập trình hàm, trước tiên chúng ta cần hiểu về các hàm. Điều này nghe có vẻ nhàm chán, nhưng vào càng về sau, nó lại khá sâu sắc. Một hàm là một thứ biến đổi một số đầu vào thành một số đầu ra nhưng nó không phải lúc nào cũng đơn giản như vậy. Hãy xem xét hàm này trong Python:
Chức năng này khá đơn giản và dễ hiểu; nó nhận một biến x, có lẽ là int, hoặc có thể là float hoặc double, và chia ra bình phương của biến đó. Bây giờ hãy xem xét chức năng này:
Thoạt nhìn, nó có vẻ như hàm nhận một biến x, thuộc bất kỳ kiểu nào và không trả về gì vì không có câu lệnh trả về. Hàm sẽ không hoạt động nếu global_list không được xác định trước và đầu ra của nó là cùng một danh sách, mặc dù đã được sửa đổi. Mặc dù global_list chưa bao giờ được khai báo dưới dạng đầu vào, nhưng nó sẽ thay đổi khi chúng ta sử dụng hàm:
Thay vì một danh sách trống, nó trả về [1,2]. Điều này cho thấy danh sách thực sự là một đầu vào của hàm, và mặc dù không nói rõ về nó nhưng đó có thể là một vấn đề.
Không trung thực về chức năng
Những đầu vào tiềm ẩn này - hoặc đầu ra, trong các trường hợp khác - có tên chính thức: tác dụng phụ. Trong khi chúng tôi chỉ sử dụng một ví dụ đơn giản, trong với các chương trình phức tạp hơn, nó có thể gây ra những khó khăn thực sự. Hãy nghĩ về cách bạn kiểm tra append_to_list: Thay vì chỉ đọc dòng đầu tiên và kiểm tra hàm với bất kỳ dấu x nào, bạn cần đọc toàn bộ định nghĩa, hiểu nó đang làm gì, xác định global_list và kiểm tra theo cách đó. Điều đơn giản trong ví dụ này có thể nhanh chóng trở nên khủng hoảng khi bạn phải xử lý các chương trình với hàng nghìn dòng mã. Thuy niên có một cách khắc phục dễ dàng: trung thực về những gì hàm lấy làm đầu vào, như sau:
Chúng tôi không thực sự thay đổi nhiều vì đầu ra vẫn là [1,2] và mọi thứ khác cũng vậy.Tuy nhiên, chúng tôi đã thay đổi một điều: mã hiện không có tác dụng phụ. Bây giờ khi bạn nhìn vào khai báo hàm, bạn biết chính xác điều gì đang xảy ra. Do đó, nếu chương trình không hoạt động như mong đợi, bạn có thể dễ dàng tự kiểm tra từng chức năng và xác định chức năng nào bị lỗi.
Lập trình hàm là viết các hàm thuần túy
Một hàm có đầu vào và đầu ra được khai báo rõ ràng là một hàm không có tác dụng phụ và là một hàm thuần túy. Một định nghĩa rất đơn giản về lập trình hàm là: viết một chương trình chỉ với các hàm thuần túy. Các hàm thuần túy không bao giờ sửa đổi các biến mà chỉ tạo các biến mới như một đầu ra.
Hơn nữa, bạn có thể mong đợi một đầu ra nhất định từ một hàm thuần túy với đầu vào nhất định. Ngược lại, một hàm không thuần túy có thể phụ thuộc vào một số biến toàn cục; vì vậy các biến đầu vào giống nhau có thể dẫn đến các kết quả đầu ra khác nhau nếu biến tổng thể khác nhau. Sau này có thể làm cho việc gỡ lỗi và duy trì mã khó hơn rất nhiều.
Có một quy tắc dễ dàng để phát hiện tác dụng phụ: vì mọi hàm phải có một số loại đầu vào và đầu ra, các khai báo hàm không có bất kỳ đầu vào hoặc đầu ra nào phải không tinh khiết. Đây là những khai báo đầu tiên mà bạn có thể muốn thay đổi nếu đang áp dụng lập trình hàm .
Lập trình hàm không (chỉ)
Map và Reduce
Vòng lặp không phải là một thứ trong lập trìn hàm. Hãy xem xét các vòng lặp Python này:
Đối với các thao tác đơn giản mà bạn đang cố gắng thực hiện thì mã này vẫn khá dài. Nó cũng không sẽ hoạt động vì bạn đang sửa đổi các biến toàn cục. Thay vào đó, hãy xem xét điều này:
Điều này đầy đủ chức năng, ngắn và nhanh hơn vì bạn không lặp lại nhiều phần tử của một mảng. Và khi bạn đã hiểu cách lọc và giảm bớt công việc, thì mã cũng dễ hiểu hơn. Điều đó không có nghĩa là tất cả các mã hàm đều sử dụng map và reduce, cũng không có nghĩa là bạn cần lập trình hàm để hiểu map và reduce. Chỉ khi bạn tóm tắt các vòng lặp, các hàm này bật lên khá nhiều.
Ngôn ngữ lập trình Scala
Scala là một ngôn ngữ lập trình đa mẫu hình, được thiết kế để tích hợp các tính năng của lập trình hướng đối tượng với lập trình hàm. Tên Scala xuất phát từ chữ tiếng Anh scalable, có nghĩa là ngôn ngữ có khả năng mở rộng, được phát triển dựa trên nhu cầu sử dụng các tính năng mở rộng của nó.
Nguồn: Wikipedia
Các hàm lambda
Khi nói về lịch sử của lập trình hàm, nhiều người bắt đầu với việc phát minh ra các hàm lambda. Nhưng mặc dù lambdas chắc chắn là nền tảng của lập trình hàm, chúng không phải là nguyên nhân gốc rễ. Các hàm lambda là các công cụ có thể được sử dụng để làm cho một chương trình hoạt động. Nhưng bạn cũng có thể sử dụng lambdas trong lập trình hướng đối tượng.
Static typing
Ví dụ trên không phải là static typing nhưng nó là functional.
Mặc dù tính năng static typing bổ sung thêm một lớp bảo mật cho mã của bạn, nhưng không cần thiết phải làm cho nó hoạt động. Nó có thể là một bổ sung tốt đẹp, mặc dù.
Nguồn: tổng hợp
Hình ảnh: tổng hợp
Có thể bạn quan tâm: Những thủ thuật JavaScript có thể làm bạn bất ngờ
-------------------------------
JT1 - IT Recruitment Agency
Website: https://www.jt1.vn
Email: hi@jt1.vn
Điện thoại: +8428 6675 6685
Xem thêm các bài viết khác tại: https://www.jt1.vn/blog
Theo dõi chúng tôi tại: https://www.facebook.com/jt1asia/
Comments