Thật khó để xác định chính xác "ngôn ngữ chức năng" là gì - trong số các ngôn ngữ bạn đã liệt kê, chỉ có Haskell hoàn toàn là chức năng (tất cả các ngôn ngữ khác đều áp dụng một cách tiếp cận hỗn hợp nào đó). Tuy nhiên, có một số tính năng ngôn ngữ rất hữu ích cho lập trình chức năng, và Ruby và Python không có đủ chúng để trở thành môi trường rất tốt cho FP. Dưới đây là danh sách kiểm tra cá nhân của tôi, theo thứ tự quan trọng:
- Các hàm và đóng cửa hạng nhất (Ruby, Python và tất cả các hàm khác mà bạn liệt kê có cái này).
- Đảm bảo tối ưu hóa cuộc gọi đuôi (Erlang, Haskell, Scala và Scheme có điều này, nhưng không phải Python, Ruby hoặc Clojure (chưa)).
- Hỗ trợ tính bất biến trong ngôn ngữ và thư viện chuẩn (đây là một ngôn ngữ lớn mà tất cả các "ngôn ngữ chức năng" bạn liệt kê đều có (ngoại trừ Lược đồ) nhưng Ruby và Python thì không).
- Hỗ trợ cấp độ ngôn ngữ cho các hàm trong suốt (hoặc thuần túy) tham chiếu (theo như tôi biết, hiện tại chỉ có Haskell có chức năng này).
Nhu cầu về (1) nên rõ ràng - các hàm bậc cao là cực kỳ khó khăn nếu không có các hàm hạng nhất. Khi mọi người nói về Ruby và Python là ngôn ngữ tốt cho FP, họ thường nói về điều này. Tuy nhiên, tính năng đặc biệt này là cần thiết nhưng không đủ để tạo ra một ngôn ngữ tốt cho FP.
(2) là một nhu cầu truyền thống đối với FP kể từ khi Scheme được phát minh. Không có TCO, không thể lập trình với đệ quy sâu, đây là một trong những nền tảng của FP, bởi vì bạn có được ngăn xếp tràn. Ngôn ngữ "chức năng" (theo định nghĩa phổ biến) không có ngôn ngữ này là Clojure (vì các hạn chế của JVM), nhưng Clojure có nhiều cách hack để mô phỏng TCO. (FYI, Ruby TCO là dành riêng cho triển khai , nhưng Python đặc biệt không hỗ trợ nó .) Lý do TCO phải được đảm bảo là nếu nó là đặc thù của triển khai, các hàm đệ quy sâu sẽ bị hỏng với một số triển khai, vì vậy bạn thực sự không thể sử dụng chúng cả
(3) là một điều quan trọng khác mà các ngôn ngữ chức năng hiện đại (đặc biệt là Haskell, Erlang, Clojure và Scala) có mà Ruby và Python không có. Không đi sâu vào chi tiết, tính bất biến được đảm bảo sẽ loại bỏ toàn bộ các lớp lỗi, đặc biệt là trong các tình huống xảy ra đồng thời và cho phép mọi thứ gọn gàng như cấu trúc dữ liệu liên tục . Rất khó tận dụng những lợi ích này nếu không có sự hỗ trợ ở cấp độ ngôn ngữ.
(4), đối với tôi, điều thú vị nhất về các ngôn ngữ hoàn toàn chức năng (trái ngược với các ngôn ngữ lai). Hãy xem xét hàm Ruby cực kỳ đơn giản sau:
def add(a, b)
a + b
end
Đây trông giống như một hàm thuần túy, nhưng do quá tải toán tử, nó có thể làm thay đổi tham số hoặc gây ra các tác dụng phụ như in ra bàn điều khiển. Không chắc ai đó sẽ làm quá tải +
nhà điều hành để có tác dụng phụ, nhưng ngôn ngữ không đảm bảo. (Điều tương tự cũng áp dụng với Python, mặc dù có thể không phải với ví dụ cụ thể này.)
Trong một ngôn ngữ chức năng thuần túy, mặt khác, có các đảm bảo cấp độ ngôn ngữ mà các chức năng được minh bạch tham chiếu. Điều này có nhiều lợi thế: các hàm thuần túy có thể dễ dàng ghi nhớ; chúng có thể dễ dàng được kiểm tra mà không cần dựa vào bất kỳ loại trạng thái toàn cầu nào; và các giá trị trong hàm có thể được đánh giá một cách lười biếng hoặc song song mà không phải lo lắng về các vấn đề tương tranh. Haskell tận dụng tối đa lợi thế này, nhưng tôi không biết đủ về các ngôn ngữ chức năng khác để biết nếu chúng có.
Tất cả những gì đang được nói, có thể sử dụng các kỹ thuật FP trong hầu hết mọi ngôn ngữ (ngay cả Java). Chẳng hạn, MapReduce của Google được lấy cảm hứng từ các ý tưởng chức năng, nhưng theo tôi biết họ không sử dụng bất kỳ ngôn ngữ "chức năng" nào cho các dự án lớn của họ (tôi nghĩ rằng họ chủ yếu sử dụng C ++, Java và Python).