Có hai rất các định nghĩa khác nhau về ý nghĩa của "lập trình chức năng". Bạn có thể làm một điều trong Ruby, nhưng bạn không thể làm điều kia.
Hai định nghĩa là:
- lập trình với các chức năng hạng nhất và
- lập trình với các chức năng toán học
Bạn có thể loại của chương trình với các chức năng hạng nhất trong Ruby. Nó có hỗ trợ cho các chức năng hạng nhất. Trong thực tế, nó có quá nhiều hỗ trợ cho họ: có Proc.new
, proc
, lambda
, Method
, UnboundMethod
, khối, #to_proc
và ->()
(và có lẽ một số người khác mà tôi quên).
Tất cả các số behave slightly differently, có cú pháp hơi khác, hành vi hơi khác và các giới hạn hơi khác nhau. Ví dụ: chỉ một trong số đó là cú pháp nhẹ đủ để bạn thực sự có thể sử dụng nó một cách mật độ, là các khối. Nhưng các khối có một số hạn chế khá nghiêm trọng: bạn chỉ có thể truyền một khối tới phương thức, khối không phải là đối tượng (trong ngôn ngữ hướng đối tượng trong đó "mọi thứ là đối tượng" là giới hạn nghiêm trọng rất) và ít nhất trong Ruby 1.8 cũng có một số hạn chế tham số wrt.
Đề cập đến một phương pháp là một điều khác khá là khó xử. Ví dụ: Python hoặc ECMAScript, tôi chỉ có thể nói baz = foo.bar
để tham chiếu phương pháp bar
của đối tượng foo
. Trong Ruby, foo.bar
là một phương thức gọi, nếu tôi muốn tham khảo phương pháp bar
của foo
, tôi phải nói baz = foo.method(:bar)
. Và nếu bây giờ tôi muốn gọi phương thức đó, tôi không thể chỉ nói baz()
, tôi phải nói baz.call
hoặc baz[]
hoặc (trong Ruby 1.9) baz.()
.
Vì vậy, các hàm hạng nhất trong Ruby không phải là thực sự là hạng nhất. Chúng tốt hơn nhiều so với hạng nhì, và chúng là đủ tốt ™, nhưng chúng không hoàn toàn hạng nhất.
Nhưng nói chung, người Ruby không để Ruby chỉ cho các chức năng hạng nhất. Sự hỗ trợ của Ruby đủ tốt đến mức bạn có thể nhận được bất kỳ lợi thế nào từ việc hỗ trợ tốt hơn bằng ngôn ngữ khác thường được thực hiện bởi nỗ lực đào tạo cho ngôn ngữ mới hoặc bởi một cái gì đó khác mà bạn đã quen với việc bạn phải bỏ cuộc. Giống như, nói RubyGems hoặc tích hợp Unix chặt chẽ hoặc Ruby on Rails hoặc cú pháp hoặc & hellip;
Tuy nhiên, giây thứ hai định nghĩa của FP là nơi Ruby rơi phẳng trên khuôn mặt của nó. Nếu bạn muốn lập trình với các hàm toán học trong Ruby, bạn đang ở trong một thế giới đau đớn. Bạn không thể sử dụng đa số các thư viện Ruby tuyệt đối, bởi vì hầu hết trong số đó là trạng thái có hiệu lực, có hiệu lực, khuyến khích đột biến hoặc không tinh khiết. Bạn không thể sử dụng thư viện chuẩn vì những lý do tương tự. Bạn không thể sử dụng thư viện lõi. Bạn không thể sử dụng bất kỳ kiểu dữ liệu cốt lõi nào, vì chúng đều có thể thay đổi được. Bạn chỉ có thể nói "Tôi không quan tâm rằng chúng có thể thay đổi được, tôi sẽ không biến đổi chúng và luôn sao chép chúng", nhưng vấn đề là: người khác vẫn có thể thay đổi chúng. Ngoài ra, vì chúng có thể thay đổi được, Ruby không thể tối ưu hóa việc sao chép và bộ thu gom rác không được điều chỉnh cho loại tải công việc đó.
Nó không hoạt động.
Ngoài ra còn có một số tính năng không thực sự liên quan đến lập trình hàm nhưng hầu hết các ngôn ngữ chức năng có xu hướng có, mà Ruby bị thiếu. Ví dụ, đối sánh mẫu. Sự lười biếng cũng không dễ dàng đạt được trước khi Enumerator
được sử dụng tích cực hơn trong Ruby 1.9. Và vẫn có một số nội dung hoạt động với các mức độ nghiêm ngặt Enumerable
s hoặc Array
s nhưng không hoạt động với mức độ Enumerator
s lười biếng, mặc dù thực tế không có lý do nào khiến chúng yêu cầu mức độ nghiêm ngặt.
Và đối với định nghĩa này là định nghĩa của FP, chắc chắn có ý nghĩa khi để Ruby ở phía sau.
Hai ngôn ngữ chính mà người Ruby đã đổ xô đến, là Erlang và Clojure. Đây là cả hai đối thủ tương đối tốt cho Ruby, bởi vì cả hai đều được gõ động, có một nền văn bản REPL tương tự như Ruby, và (điều này là một điều Rails hơn là một điều Ruby) cũng rất tốt trên web. Họ vẫn còn khá nhỏ và chào đón cộng đồng, những người sáng tạo ngôn ngữ ban đầu vẫn còn hoạt động trong cộng đồng, tập trung mạnh vào việc làm những điều mới mẻ, thú vị và sắc sảo, tất cả đều là những đặc điểm mà cộng đồng Ruby cũng có.
Sự quan tâm đến Erlang bắt đầu, khi ai đó đã chiếu video giới thiệu ban đầu năm 1993 "Erlang: The Movie" tại RubyConf 2006.Một vài dự án Rails cao cấp đã bắt đầu sử dụng Erlang, ví dụ: PowerSet và GitHub. Erlang cũng dễ dàng để làm chủ cho Rubyists, bởi vì nó không có độ tinh khiết khá xa như Haskell hoặc Clean. Các bên trong của một diễn viên là khá tinh khiết, nhưng hành động gửi tin nhắn chính nó là tất nhiên một tác dụng phụ. Một điều khác làm cho Erlang dễ nắm bắt, là các diễn viên và các đối tượng thực sự là giống nhau, khi bạn theo dõi Alan Kay's definition of object-oriented programming.
Clojure đã được bổ sung gần đây vào thanh công cụ của Rubyist. Tính phổ biến của nó là tôi đoán chủ yếu là do cộng đồng Ruby cuối cùng đã ấm lên với ý tưởng rằng JVM ≠ Java và ôm JRuby và sau đó họ bắt đầu xem xét những gì khác những thứ thú vị đã có trên JVM. Và một lần nữa, Clojure thực dụng hơn nhiều so với các ngôn ngữ chức năng khác như Haskell và các Lisps khác như Scheme và đơn giản hơn và hiện đại hơn nhiều so với CommonLisp, vì vậy nó phù hợp với Rubyists.
Một điều thú vị khác về Clojure là vì cả Clojure và Ruby chạy trên JVM, bạn có thể kết hợp chúng.
Tác giả của "Programming Clojure" (Stuart Halloway) là một (cựu?) Rubyist, ví dụ, như là Phil Hagelberg, tác giả của công cụ Leiningen xây dựng cho Clojure.
Tuy nhiên, Rubyists cũng đang xem xét cả hai Scala (là một trong những ngôn ngữ FP được gõ thực dụng hơn) và Haskell (là một trong những thứ trang nhã hơn). Sau đó, có những dự án như Scuby và Hubris là những cây cầu cho phép bạn tích hợp Ruby với Scala và Haskell tương ứng. Quyết định của Twitter để chuyển một phần cơ sở hạ tầng nhắn tin cấp thấp của họ từ MySQL sang Ruby, sau đó từ Ruby sang Scala cũng được biết đến rộng rãi.
F# dường như không đóng bất kỳ vai trò nào, có thể là do một nỗi sợ không hợp lý đối với tất cả mọi thứ mà cộng đồng Ruby của Microsoft có. (Mà, BTW, có vẻ hầu như không có cơ sở, cho rằng nhóm F # có luôn luôn đã tạo sẵn các phiên bản cho Mono.)
Chức năng FP nào của Ruby thiếu để nó cần bất kỳ "người kế nhiệm chức năng" nào? –
Tôi đoán cái gì đó chạy như là một ngôn ngữ chức năng "phân tán" tốt đẹp là một cái gì đó Ruby thiếu. Ngoài ra, theo nghĩa FP, bạn có quyền ở chỗ Ruby không thiếu bất cứ thứ gì, thay vào đó nó có quá nhiều. Một ngôn ngữ chức năng buộc các lập trình viên không sử dụng các biến toàn cầu rất nhiều (mặc dù nó có thể) – Zubair
@ Zubair, vâng đó là về cảm giác của tôi .. Ruby được thiết kế như ngôn ngữ đa mô hình. Bạn có thể lập trình trong đó cho bất kỳ mô hình nào bạn muốn .. Mặc dù bạn không thể thoát khỏi OOP rất dễ dàng với nó. – Earlz