2010-02-12 24 views
36

Tôi biết rất nhiều người Java đã bắt đầu xem xét Scala kể từ khi nó chạy trên JVM, và rất nhiều người trong thế giới Microsoft đang xem F #, nhưng Ruby có một người kế nhiệm chức năng tự nhiên là gì?Nếu người Java đi đến Scala, C# đi đến F #, nơi mà người Ruby đi cho niết bàn chức năng?

Trong ý nghĩa FP thuần túy Ruby không thiếu bất kỳ thứ gì, thay vào đó, có quá nhiều người có thể nói. 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 và thành ngữ khác rất nhiều (mặc dù nó có thể sử dụng các hình cầu trong các ngôn ngữ chức năng)

+0

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? –

+0

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

+0

@ 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

Trả lời

74

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à 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à ErlangClojure. Đâ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ụ: PowerSetGitHub. 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ư ScubyHubris 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.)

+10

Đây là một phản ứng tuyệt vời - Tôi vui mừng khi thấy ai đó chạm vào ý tưởng rằng lập trình chức năng không chỉ là các cấu trúc ngôn ngữ như đóng cửa và chức năng hạng nhất. Bất cứ khi nào tôi nghe mọi người nói rằng "Ruby là đủ chức năng" tôi cringe một chút - như ghi chú viên đạn thứ hai của bạn, lập trình chức năng là nhiều hơn về một phong cách và phương pháp hơn các tính năng ngôn ngữ cụ thể. – mipadi

+0

Câu trả lời hay. Và để sao lưu gợi ý của bạn về Erlang như một ngôn ngữ FP Rubyists như: Những người sáng tạo của Ruby On Rails, 37signals, viết blog một lúc về cách họ đã viết lại một phần ứng dụng của họ ở Erlang để có được hiệu suất tốt hơn. – Chuck

+2

Nó phụ thuộc. Thuật ngữ "lập trình chức năng" được phát minh cho Lisp, điều này rất không tinh khiết, có trạng thái, hiệu quả, bắt buộc hay bất cứ điều gì bạn muốn gọi. (Ngoại trừ Đề án và Clojure, cả hai đều không tồn tại khi thuật ngữ được phát minh.) Lisp được sử dụng rộng rãi nhất là CommonLisp, không phải là chức năng * ở tất cả * theo định nghĩa toán học của "hàm". Mọi người đã đề xuất gọi loại thứ hai "lập trình theo định hướng giá trị" hoặc "lập trình chức năng thuần túy" để làm sáng tỏ sự nhầm lẫn. Martin Odersky (nhà thiết kế của Scala) gọi chúng là định nghĩa "bao gồm" và "độc quyền" –

6

Ruby nó là một loại Ngôn ngữ lập trình hàm, Vì vậy, tôi không thấy bất kỳ phương ngữ đặc biệt cho FP sử dụng ruby.

+5

Đó là một loại ngôn ngữ lập trình chức năng theo cùng một cách mà một nhãn dán trầy xước và sniff là một loại trái cây. Dấu hiệu của lập trình chức năng không có tác dụng phụ.Ruby là một trong những ngôn ngữ khó nhất (nếu không phải là khó nhất) để viết mã thực sự chức năng. Chỉ cần tạo một cấu trúc dữ liệu thực sự bất biến là không thể trong Ruby (thậm chí cả Fixnums có thể có các thuộc tính có thể thay đổi được). Ngoài ra, viết nhiều hàm thực sự (có nghĩa là, hàm lambda chứ không phải là phương thức) không đơn điệu trong Ruby và các hàm phải được chuyển đổi liên tục giữa các Procs và các khối. – Chuck

+4

Xem http://yellowlab.com.au/blog/2009/09/15/functional-programming-in-ruby/ Ruby không thực sự cắt nó liên quan đến FP. – Synesso

7

Mọi phiên bản của Lisp đều ổn.

+1

-1: Câu hỏi không phải là "tôi nên sử dụng ngôn ngữ lập trình chức năng nào?", Nó hỏi "những người dùng rubyists có khuynh hướng sử dụng ngôn ngữ nào?" –

+2

Cảm ơn bạn đã downvote, nhưng câu hỏi là (và tôi trích dẫn bản gốc): "Ruby có gì là một người kế nhiệm chức năng tự nhiên?" không phải "những người dùng rubyists ngôn ngữ nào có xu hướng sử dụng?". –

+0

Bạn được chào đón. –

15

Người Java đang sử dụng ngôn ngữ trên JVM và muốn có một ngôn ngữ chức năng hơn tương thích với thời gian chạy của họ, vì vậy họ truy cập Scala.

C# người đang sử dụng một ngôn ngữ trên CLR và muốn có một chức năng tương thích hơn với thời gian chạy của họ, vì vậy họ chuyển đến F #.

Ruby người đang sử dụng một ngôn ngữ đã được khá chức năng, và họ đang sử dụng nó trên một số runtimes cơ bản (JRuby, IronRuby, MRI, MacRuby, Rubinius, vv ...). Tôi không nghĩ rằng nó có một người kế nhiệm chức năng tự nhiên, hoặc thậm chí cần một.

3

Ở mức cường độ cao, Haskell.

+0

Tôi đã nhìn thấy Haskell, và nghĩ rằng đó là một ngôn ngữ đẹp, và hệ thống Type, Monads và Software Transactional Memory thật tuyệt vời. Tôi không chắc chắn nó tốt như thế nào cho các hệ thống phân phối mặc dù, tôi cần giáo dục về điều đó vẫn còn. – Zubair

+0

Typeclasses đặc biệt tốt đẹp nếu bạn quen với ruby ​​mixins. – singpolyma

3

Ruby không hoạt động như nói Lisp, nhưng nó chỉ đủ chức năng để bạn có thể thực hiện một số chương trình chức năng theo cách vui vẻ. (không giống như cố gắng lập trình chức năng trong một cái gì đó như C#)

Ngoài ra, nó thực sự buộc bạn vào các mô hình chức năng theo một số cú pháp của nó, chẳng hạn như sử dụng khối và năng suất. (mà tôi đã yêu sau khi học Ruby).

+0

Tại sao bạn không thể lập trình chức năng trong C# dễ dàng như vậy (chỉ với kiến ​​thức cá nhân của tôi, xin đừng bắt đầu một cuộc chiến chống lửa!)? – Zubair

+4

Chắc chắn, nó có thể .. C# thậm chí có các công cụ như lambda và các chức năng ẩn danh .. Nhưng thực sự, nó fugly và C# API cho. Net là hướng cho mã hóa phi chức năng. Chắc chắn bạn có thể phù hợp với một cái chốt tròn trong một lỗ vuông, nhưng nó có ý nghĩa hơn để sử dụng một hình vuông peg hoặc một gần như vuông (ví dụ, ruby) peg – Earlz

+0

Ok, có ý nghĩa. Nhưng không F # sử dụng cùng một thời gian chạy .NET như C#? – Zubair

3

Giả sử người Ruby không chỉ tự mình đến với JVM, tôi nghĩ rằng hầu hết sẽ áp dụng Erlang, một ngôn ngữ được nhập động khác.

+0

Vâng, tôi đã thấy rất nhiều người Ruby di chuyển đến Erlang. – Zubair

Các vấn đề liên quan