Wikipedia nói rằng Ruby là một ngôn ngữ chức năng, nhưng tôi không bị thuyết phục. Tại sao hoặc tại sao không?
Wikipedia nói rằng Ruby là một ngôn ngữ chức năng, nhưng tôi không bị thuyết phục. Tại sao hoặc tại sao không?
Câu trả lời:
Tôi chắc chắn rằng bạn có thể sử dụng kiểu hàm trong Ruby.
Một trong những khía cạnh quan trọng nhất để có thể lập trình theo kiểu hàm là ngôn ngữ có hỗ trợ các hàm bậc cao hơn hay không ... mà Ruby làm.
Điều đó nói rằng, thật dễ dàng để lập trình trong Ruby theo kiểu phi chức năng. Một khía cạnh quan trọng khác của kiểu hàm là không có trạng thái và có các hàm toán học thực sự luôn trả về cùng một giá trị cho một tập hợp đầu vào nhất định. Điều này có thể được thực hiện trong Ruby, nhưng nó không được thực thi trong ngôn ngữ giống như một thứ có chức năng nghiêm ngặt hơn như Haskell.
Vì vậy, vâng, nó hỗ trợ phong cách chức năng, nhưng nó cũng sẽ cho phép bạn lập trình theo phong cách phi chức năng.
Is ruby a functional language?
và câu trả lời thẳng thắn là không. Ruby là một ngôn ngữ hướng đối tượng với một số tính năng chức năng.
Một ngôn ngữ có phải là ngôn ngữ chức năng hay không là điều không quan trọng. Lập trình chức năng là một luận án, được giải thích tốt nhất bởi Philip Wadler (Bản chất của Lập trình Chức năng) và John Hughes (Tại sao Các vấn đề Lập trình Chức năng).
Một câu hỏi có ý nghĩa là, 'Ruby có thể đạt được luận điểm về lập trình hàm như thế nào?' Câu trả lời là 'rất kém'.
Tôi đã nói chuyện về điều này vừa rồi. Đây là các slide.
Ruby có hỗ trợ các hàm cấp cao hơn (xem Array # map, injection, & select), nhưng nó vẫn là một ngôn ngữ hướng đối tượng, bắt buộc.
Một trong những đặc điểm chính của ngôn ngữ chức năng là nó tránh trạng thái có thể thay đổi. Các ngôn ngữ hàm không có khái niệm về một biến như bạn sẽ có trong Ruby, C, Java hoặc bất kỳ ngôn ngữ mệnh lệnh nào khác.
Một đặc điểm chính khác của ngôn ngữ chức năng là nó tập trung vào việc xác định một chương trình dưới dạng "cái gì", chứ không phải "như thế nào". Khi lập trình bằng ngôn ngữ OO, chúng ta viết các lớp & phương thức để ẩn việc triển khai ("cách") khỏi "cái gì" (tên lớp / phương thức), nhưng cuối cùng các phương thức này vẫn được viết bằng một chuỗi các câu lệnh. Trong ngôn ngữ chức năng, bạn không chỉ định trình tự thực thi, ngay cả ở cấp thấp nhất.
Tôi gửi rằng hỗ trợ hoặc có khả năng lập trình bằng một ngôn ngữ theo phong cách chức năng không phải là ngôn ngữ chức năng tạo ra.
Tôi thậm chí có thể viết mã Java theo kiểu chức năng nếu tôi muốn làm hại đồng nghiệp của mình và bản thân tôi sau vài tháng .
Có một ngôn ngữ chức năng không chỉ là về những gì bạn có thể làm, chẳng hạn như các chức năng bậc cao hơn, các chức năng hạng nhất và cách đọc. Nó cũng là về những gì bạn không thể làm, như tác dụng phụ trong các chức năng thuần túy.
Điều này rất quan trọng bởi vì nó là một phần lớn lý do tại sao các chương trình chức năng, hay mã chức năng trong genrel lại dễ lý giải hơn. Và khi mã dễ lập luận hơn, các lỗi trở nên nông hơn và nổi lên bề mặt khái niệm nơi chúng có thể được sửa chữa, do đó mang lại ít mã lỗi hơn.
Ruby là hướng đối tượng ở cốt lõi của nó, vì vậy mặc dù nó có hỗ trợ khá tốt cho một phong cách chức năng, nhưng bản thân nó không phải là một ngôn ngữ chức năng.
Dù sao đó cũng là ý kiến phi khoa học của tôi.
Chỉnh sửa: Khi nhìn lại và xem xét những nhận xét tốt mà tôi đã nhận được cho câu trả lời này cho đến nay, tôi nghĩ rằng so sánh hướng đối tượng so với chức năng là một trong những quả táo và trái cam.
Điểm khác biệt thực sự là có thể so sánh được trong thực thi hay không. Các ngôn ngữ chức năng có biểu thức là cấu trúc ngôn ngữ chính của chúng và thứ tự thực hiện thường không được xác định hoặc được định nghĩa là lười biếng. Có thể thực hiện nghiêm ngặt nhưng chỉ được sử dụng khi cần thiết. Trong một ngôn ngữ so sánh, thực thi nghiêm ngặt là mặc định và trong khi thực thi lười biếng là có thể xảy ra, việc thực hiện này thường khó thực hiện và có thể có kết quả không thể đoán trước trong nhiều trường hợp phức tạp.
Bây giờ, đó là ý kiến phi khoa học của tôi.
Ruby sẽ phải đáp ứng các yêu cầu sau để có thể hoạt động "THẬT SỰ".
Giá trị bất biến: một khi "biến" được đặt, nó không thể thay đổi được. Trong Ruby, điều này có nghĩa là bạn phải xử lý các biến như hằng số. Ngôn ngữ này không được hỗ trợ đầy đủ, bạn sẽ phải đóng băng từng biến theo cách thủ công.
Không có tác dụng phụ: khi được truyền một giá trị nhất định, một hàm phải luôn trả về cùng một kết quả. Điều này đi đôi với việc có những giá trị bất biến; một hàm không bao giờ có thể nhận một giá trị và thay đổi nó, vì điều này sẽ gây ra một tác dụng phụ có liên quan đến việc trả về một kết quả.
Các hàm bậc cao hơn: đây là các hàm cho phép các hàm làm đối số hoặc sử dụng các hàm làm giá trị trả về. Đây được cho là một trong những tính năng quan trọng nhất của bất kỳ ngôn ngữ chức năng nào.
Currying: được kích hoạt bởi các hàm bậc cao hơn, currying là biến đổi một hàm nhận nhiều đối số thành một hàm nhận một đối số. Điều này đi đôi với ứng dụng hàm từng phần, tức là chuyển đổi một hàm nhiều đối số thành một hàm nhận ít đối số hơn so với ban đầu.
Đệ quy: lặp lại bằng cách gọi một hàm từ bên trong chính nó. Khi bạn không có quyền truy cập vào dữ liệu có thể thay đổi, đệ quy được sử dụng để xây dựng và xây dựng chuỗi dữ liệu. Điều này là do vòng lặp không phải là một khái niệm chức năng, vì nó yêu cầu các biến được truyền xung quanh để lưu trữ trạng thái của vòng lặp tại một thời điểm nhất định.
Đánh giá chậm, hoặc đánh giá chậm : trì hoãn việc xử lý các giá trị cho đến thời điểm thực sự cần thiết. Ví dụ: nếu bạn có một số mã tạo danh sách các số Fibonacci với tính năng đánh giá lười biếng, điều này sẽ không thực sự được xử lý và tính toán cho đến khi một trong các giá trị trong kết quả được yêu cầu bởi một hàm khác, chẳng hạn như giá trị đặt.
Đề xuất (Chỉ là một suy nghĩ)
Tôi sẽ rất tuyệt nếu có một số loại định nghĩa để có một mode
chỉ thị để khai báo các tệp với mô hình chức năng, ví dụ
chế độ 'chức năng'
Ruby là một ngôn ngữ đa mô hình hỗ trợ một phong cách lập trình chức năng.
Nó phụ thuộc vào định nghĩa của bạn về “ngôn ngữ chức năng”. Cá nhân tôi nghĩ rằng bản thân thuật ngữ này khá có vấn đề khi được sử dụng như một điều tuyệt đối. Có nhiều khía cạnh để trở thành một “ngôn ngữ chức năng” hơn là các tính năng ngôn ngữ đơn thuần và hầu hết phụ thuộc vào nơi bạn đang tìm kiếm. Ví dụ, văn hóa xung quanh ngôn ngữ là khá quan trọng trong vấn đề này. Nó có khuyến khích một phong cách chức năng không? Điều gì về các thư viện có sẵn? Họ có khuyến khích bạn sử dụng chúng theo cách có chức năng không?
Ví dụ, hầu hết mọi người gọi Scheme là một ngôn ngữ chức năng. Nhưng những gì về Common Lisp? Ngoài vấn đề không gian tên nhiều / đơn và loại bỏ lệnh gọi đuôi được đảm bảo (mà một số triển khai CL cũng hỗ trợ, tùy thuộc vào cài đặt trình biên dịch), không có nhiều điều khiến Scheme trở thành một ngôn ngữ phù hợp với lập trình chức năng hơn Common Lisp, và vẫn còn, hầu hết các Lispers sẽ không gọi CL là một ngôn ngữ chức năng. Tại sao? Bởi vì văn hóa xung quanh nó phụ thuộc rất nhiều vào các tính năng bắt buộc của CL (ví dụ như macro LOOP, điều mà hầu hết các Lập trình viên có thể sẽ cau mày).
Mặt khác, một lập trình viên C cũng có thể coi CL là một ngôn ngữ chức năng. Hầu hết các mã được viết bằng bất kỳ phương ngữ Lisp nào chắc chắn có nhiều chức năng hơn nhiều so với khối mã C thông thường của bạn. Tương tự như vậy, Scheme là một ngôn ngữ bắt buộc rất nhiều so với Haskell. Do đó, tôi không nghĩ rằng có thể có một câu trả lời có / không rõ ràng. Việc gọi một ngôn ngữ có chức năng hay không phụ thuộc nhiều vào quan điểm của bạn.
Ruby cũng không thực sự là một ngôn ngữ đa mô hình, tôi nghĩ vậy. Đa mô hình có xu hướng được sử dụng bởi những người muốn gắn nhãn ngôn ngữ yêu thích của họ như một thứ hữu ích trong nhiều lĩnh vực khác nhau.
Tôi mô tả Ruby là một ngôn ngữ kịch bản hướng đối tượng. Đúng, các hàm là các đối tượng hạng nhất (loại), nhưng điều đó không thực sự khiến nó trở thành một ngôn ngữ hàm. IMO, tôi có thể thêm.
Đệ quy phổ biến trong lập trình hàm. Hầu hết mọi ngôn ngữ đều hỗ trợ đệ quy, nhưng các thuật toán đệ quy thường không hiệu quả nếu không có tối ưu hóa lệnh gọi đuôi (TCO).
Các ngôn ngữ lập trình hàm có khả năng tối ưu hóa đệ quy đuôi và có thể thực thi mã như vậy trong không gian không đổi. Một số triển khai Ruby tối ưu hóa đệ quy đuôi, một số khác thì không, nhưng nói chung các triển khai Ruby không bắt buộc phải thực hiện TCO. Xem Ruby có thực hiện Tối ưu hóa cuộc gọi đuôi không?
Vì vậy, nếu bạn viết một số kiểu hàm Ruby và dựa vào TCO của một số triển khai cụ thể, mã của bạn có thể rất kém hiệu quả trong một trình thông dịch Ruby khác. Tôi nghĩ đây là lý do tại sao Ruby không phải là một ngôn ngữ chức năng (Python cũng vậy).
Nói một cách chính xác, sẽ không hợp lý khi mô tả một ngôn ngữ là "chức năng"; hầu hết các ngôn ngữ đều có khả năng lập trình chức năng. Ngay cả C ++ cũng vậy.
Phong cách chức năng ít nhiều là một tập hợp con của các tính năng ngôn ngữ mệnh lệnh, được hỗ trợ với đường cú pháp và một số tối ưu hóa trình biên dịch như tính bất biến và làm phẳng đệ quy đuôi,
Điều sau được cho là một kỹ thuật nhỏ dành riêng cho việc triển khai và không liên quan gì đến ngôn ngữ thực tế. Trình biên dịch x64 C # 4.0 thực hiện tối ưu hóa đệ quy đuôi, trong khi trình biên dịch x86 không vì bất kỳ lý do ngu ngốc nào.
Đường cú pháp thường có thể hoạt động ở một mức độ nào đó hay cách khác, đặc biệt nếu ngôn ngữ có trình biên dịch trước có thể lập trình được (tức là #define của C).
Có thể có ý nghĩa hơn một chút khi hỏi, "ngôn ngữ __ có hỗ trợ lập trình mệnh lệnh không?", Và câu trả lời, chẳng hạn với Lisp, là "không".
Xin hãy xem phần đầu của cuốn sách: "A-Great-Ruby-eBook" . Nó thảo luận về chủ đề rất cụ thể mà bạn đang hỏi. Bạn có thể thực hiện các kiểu lập trình khác nhau trong Ruby. Nếu bạn muốn lập trình như chức năng, bạn có thể làm điều đó. Nếu bạn muốn lập trình giống như theo cấp bậc, bạn có thể làm điều đó. Cuối cùng thì đó là một câu hỏi định nghĩa về chức năng của Ruby. Vui lòng xem câu trả lời của người dùng ngụy trang.