Học một ngôn ngữ chức năng làm cho một lập trình viên OOP tốt hơn? [đóng cửa]


28

Là một lập trình viên Java / C # / C ++, tôi nghe rất nhiều cuộc nói chuyện về các ngôn ngữ chức năng, nhưng chưa bao giờ thấy cần phải học một ngôn ngữ. Tôi cũng đã nghe nói rằng mức độ tư duy cao hơn được giới thiệu trong các ngôn ngữ chức năng giúp bạn trở thành một lập trình viên ngôn ngữ thủ tục / OOP tốt hơn.

bất cứ ai có thể xác nhận điều này? Những cách nào nó cải thiện kỹ năng lập trình của bạn?

Một lựa chọn tốt của ngôn ngữ để học với mục tiêu cải thiện kỹ năng trong một ngôn ngữ ít phức tạp hơn là gì?


3
Nếu bạn đang viết mã bằng C #, bạn đã biết một. LINQ là một điều khá chức năng.
SK-logic

Tôi nghĩ OOP tốt hơn cho việc mô hình hóa các đối tượng trong cuộc sống thực.
Tulains Córdova

1
@ user61852 Hầu hết các mẫu thiết kế OO không mô hình hóa bất cứ điều gì về các đối tượng "đời thực", nhưng thực sự là các khái niệm trừu tượng.
Andres F.

Không chỉ là một lập trình viên Java / C # (+ C ++). Có một sự khác biệt giữa một con dao quân đội khổng lồ với một cuốn sách nhỏ không hề nhỏ, trong đó nêu rõ lý do tại sao bạn chọn lưỡi kiếm X trong số 40 và một lưỡi kiếm bạn có thể khắc ra gần bất cứ thứ gì bạn muốn bởi vì nó vừa sắc bén vừa cong đúng như vậy mà bạn có thể áp dụng sức mạnh cắt của nó vào nhiều tình huống mà không cần suy nghĩ nhiều. (tất nhiên là có dụng cụ mở chai trong tay cầm)
Erik Reppen

Câu trả lời:


32

Về cơ bản, tôi đồng ý với câu trả lời của FrustratedWithFormsDesign , nhưng bạn cũng hỏi cách học mô hình mới giúp phát triển các kỹ năng của một người. Tôi có thể đưa ra một vài ví dụ từ kinh nghiệm của riêng tôi.

Kể từ khi học lập trình chức năng, tôi ý thức nhiều hơn về những khái niệm mà tôi làm việc được coi là "đối tượng" một cách tự nhiên hơn (nói chung là sự đột biến có ý nghĩa) và được coi là "giá trị" bất biến hơn (tôi nghĩ có một sự khác biệt quan trọng , chạm vào nơi OO có ý nghĩa so với khi FP có ý nghĩa, nhưng đó chỉ là ý kiến ​​của tôi).

Tôi nhận thấy nơi mã của tôi bao gồm các tác dụng phụ và tôi cẩn thận hơn khi cách ly những nơi đó, tạo ra nhiều chức năng "thuần túy" hơn. Điều này cải thiện đáng kể khả năng kiểm tra mã OO của tôi.

Tôi có ý thức hơn về các chu kỳ trong biểu diễn dữ liệu của tôi. . bạn cần thực hiện để các cấu trúc dữ liệu của bạn nhất quán trong nội bộ, giảm bớt gánh nặng trong việc chia sẻ các cấu trúc này giữa các luồng.

Tôi có nhiều khả năng dựa vào đệ quy (các cấu trúc lặp đệ quy của lược đồ là những thứ đẹp đẽ). Dijkstra đã chạm vào tầm quan trọng của điều này trong Ghi chú về Lập trình có cấu trúc - thuật toán đệ quy ánh xạ trực tiếp đến cảm ứng toán học, mà ông cho rằng đây là phương tiện duy nhất để chứng minh trí tuệ của chúng ta đúng. (Tôi không đề nghị rằng chúng ta phải chứng minh mã của mình đúng, nhưng chúng ta càng dễ dàng làm điều đó cho chính mình, thì càng có nhiều khả năng mã của chúng ta đúng.)

Tôi có nhiều khả năng sử dụng các hàm bậc cao hơn. Bài viết của John Hughes, Tại sao lại là vấn đề lập trình chức năng . Nó nhấn mạnh khả năng kết hợp bạn có được từ việc sử dụng các kỹ thuật lập trình chức năng, các hàm bậc cao hơn đóng vai trò chính.

Ngoài ra, như đã chạm vào câu trả lời của Jetti , bạn sẽ thấy rằng rất nhiều ý tưởng FP đang được kết hợp vào các ngôn ngữ OO mới hơn. Cả Ruby và Python đều cung cấp nhiều hàm bậc cao hơn, tôi đã nghe LINQ được mô tả là một nỗ lực nhằm mang lại sự hỗ trợ cho sự hiểu biết đơn điệu vào C #, thậm chí C ++ hiện có các biểu thức lambda.


@Aidan: wrt lambdas trong C ++ 0x, với bất kỳ giá nào, trình biên dịch C ++ mới đã kết hợp chúng với nhau.
Matthieu M.

1
"Đối tượng" là "thứ giữ trạng thái có thể thay đổi" là rất phổ biến, nhưng mẫu Đối tượng Giá trị đã tồn tại trong nhiều năm.
Frank Shearar

@Matthieu, cảm ơn, tôi đã cập nhật văn bản để phản ánh điều đó.
Aidan Cully

@Frank: cảm ơn con trỏ. Tôi không bao gồm điều này trong câu trả lời, nhưng sự phản đối chính mà tôi phải đưa Giá trị vào Đối tượng phải thực hiện với các giao diện đối tượng b / w phân biệt (thuộc sở hữu của các đối tượng) và các hoạt động (trong đó mối quan hệ giữa các đối tượng là nhiều hơn chính hơn các đối tượng tự). 1 + 2về mặt toán học tương đương với 2 + 1, nhưng 1.+(2)được thực hiện khác với 2.+(1). Tồn tại một số vấn đề SW hơn có thể được hiểu một cách tự nhiên hơn bằng cách sử dụng các hoạt động hơn là sử dụng giao diện đối tượng.
Aidan Cully

1
@Aidan Bạn đã đọc "Hiểu về trừu tượng dữ liệu, xem lại" của William Cook chưa? Nó đi sâu vào sự khác biệt giữa các đối tượng và ADT, đó là những gì bạn gợi ý.
Frank Shearar

32

Tôi không nói rằng nó đảm bảo sẽ giúp bạn trở thành một lập trình viên OOP tốt hơn, nhưng nó sẽ giới thiệu cho bạn một cách suy nghĩ mới, và điều đó có thể giúp bạn giải quyết vấn đề nói chung tốt hơn, không chỉ về mặt OOP.


3
Cho rằng các đối tượng thực sự là các hàm bậc cao hơn, tôi thấy rằng việc học các công cụ FP đã giúp trực tiếp với OOP của tôi. Đó là, như bạn nói, nói chung có thể áp dụng / hữu ích hơn.
Frank Shearar

12

Học một ngôn ngữ chức năng - Lisp cho tôi - thực sự hữu ích khi xây dựng các ứng dụng song song. Các phương thức chức năng (dựa trên trạng thái, không có tác dụng phụ) dễ dàng đồng bộ hóa hơn nhiều và dễ dàng hơn để tạo luồng an toàn vì chúng chỉ phụ thuộc vào đầu vào của chúng. Điều đó có nghĩa là dữ liệu duy nhất bạn cần xem cho một vùng mã nhất định là các tham số bạn truyền vào. Điều này cũng giúp việc gỡ lỗi dễ dàng hơn.


Bạn sẽ thấy nó cũng giúp với các thư viện luồng, có xu hướng mong đợi các hàm thuần túy là nhiệm vụ của chúng. Nó cũng có thể giúp gián tiếp, có những nơi tôi sẽ viết mã OO theo kiểu "kiểu chức năng" trong đó có "tham số sở hữu" có khóa ẩn trên một loạt các đối tượng mà nó tham chiếu và được hàm sử dụng . Miễn là bạn ghi lại các kỳ vọng của mình (và kiểm tra đơn vị chúng), điều này có thể cung cấp cho bạn mã đa luồng tốt hơn với một vài vấn đề khóa. Và vài ổ khóa rõ ràng.

Tôi chưa bao giờ nghe nói Prolog được gọi là ngôn ngữ chức năng. Nếu tôi nheo mắt đủ, tôi có thể mơ hồ thấy làm thế nào (một phần của) Prolog có thể giúp với FP.
Frank Shearar

1
Prolog không phải là một ngôn ngữ chức năng. Đó là một ngôn ngữ logic. Nếu bạn muốn có một ngôn ngữ logic giống như Prolog cũng được tích hợp lập trình chức năng, bạn có thể lấy một người thích ở Mercury . Cảnh báo: Nó sẽ làm tổn thương não của bạn một chút ngay cả khi bạn đã biết Prolog.
CHỈ CẦN HOẠT ĐỘNG CỦA TÔI đúng

@ CHỈ CẦN HOẠT ĐỘNG CỦA TÔI: Vâng, tôi nghĩ bạn đúng. Tôi cần tìm hiểu thêm về các ngôn ngữ chức năng!
Michael K

1
@moz: Vâng, tôi ước Java có lambdas. ThreadĐối tượng ẩn danh là ... vụng về.
Michael K

9

Học bất kỳ mô hình lập trình nào khác sẽ cải thiện kỹ năng lập trình của bạn nói chung. Lập trình, khi nó không phải là công cụ cấp nghiên cứu học thuật (và thậm chí sau đó, thường xuyên), về cơ bản là giải quyết vấn đề. Suy nghĩ, trong một từ. Các mô hình khác nhau là cách suy nghĩ khác nhau về các vấn đề và giải pháp của họ. Vì vậy, đừng nghĩ đó là "học một ngôn ngữ chức năng". Hãy nghĩ về nó như là "học một cách khác để suy nghĩ về các vấn đề và giải pháp của họ". Sau đó, bạn sẽ thấy những lợi ích của việc học một ngôn ngữ ngay cả khi bạn không bao giờ thực sự sử dụng nó.

Để giải quyết câu hỏi cụ thể của bạn, tôi đã trở thành một lập trình viên C ++ trong những ngày mới (trở lại trước khi có một tiêu chuẩn cho C ++). Tôi đã làm theo tất cả những thứ thông thường với các đối tượng giữ trạng thái thao túng bằng các phương thức, v.v. Sau đó, tôi tình cờ gặp Haskell và học (phần lớn) nó. (Tôi không nghĩ có ai từng thực sự học Haskell.) Bài tập có vẻ hơi lãng phí vào thời điểm đó cho đến khi một trong những đồng nghiệp của tôi, người kiểm tra được chỉ định cho nhóm của tôi, đưa ra nhận xét trái ngược rằng mã của tôi dễ kiểm tra hơn.

Điều đã xảy ra là tôi bắt đầu làm cho đồ vật của mình ngày càng bất biến. Các lớp với trạng thái đột biến phức tạp bắt đầu được thay thế bằng các lớp tự nhân bản với các thay đổi, trả về các đối tượng mới. Các đối tượng được chia sẻ bắt đầu được thay thế bằng các đối tượng có ngữ nghĩa sao chép trên ghi (do đó tạo ảo giác về rất nhiều bản sao đối tượng mà không cần chi phí bộ nhớ). Chức năng không có tác dụng phụ trừ khi thực sự cần thiết; định nghĩa thuần túy, toán học của "hàm" ngày càng trở thành chuẩn mực. Tất cả điều này bắt đầu xảy ra trong mã của tôi một cách tự nhiên - không có ý nghĩ có ý thức nào tham gia - khi tôi khám phá ngày càng nhiều không gian lập trình chức năng.

Bây giờ tôi đặt mục tiêu học ít nhất một mô hình lập trình mới mỗi hai năm (ngay cả khi đó chỉ là một mô hình mở rộng nhỏ như AOP) và ít nhất hai ngôn ngữ mới trong mỗi mô hình (một ngôn ngữ thuần túy nhất có thể, thêm một ngôn ngữ lai / thực tế ). Mỗi người đã cho tôi các công cụ trí tuệ mới để áp dụng cho tất cả các chương trình của tôi bằng bất kỳ ngôn ngữ nào, vì vậy, thời gian dành cho việc học chúng, theo tôi, thậm chí còn hơi lãng phí.


3

Tôi đã nói điều đó trước đây và tôi sẽ nói lại, học ngôn ngữ chức năng chắc chắn đã cải thiện C # của tôi. Nó giúp tôi hiểu lambdas (và giúp tôi yêu chúng). Nó cũng khiến tôi nhận ra mình thích lập trình chức năng (F #) đến mức nào khi làm việc với các hoạt động không đồng bộ!


3

Mã máy không có gì khác sau đó là danh sách các tác dụng phụ - các lệnh được bộ xử lý trực tiếp thực hiện. Các tác dụng phụ trong C là khác nhau, thay vì xử lý các thanh ghi và phần cứng vật lý, bạn xử lý một tập hợp trừu tượng và để trình biên dịch thực hiện tất cả các công việc bẩn. C cũng cho phép bạn cấu trúc các tác dụng phụ của bạn trong các vòng lặp và sau đó là các câu lệnh. C ++ cải thiện C bằng cách thêm OOP và một số tính năng rất cần thiết vào ngôn ngữ. Java và C # thêm bộ sưu tập rác và Python thêm kiểu gõ động.

Ngay cả với tất cả các tính năng này - gõ động, bộ sưu tập rác, vv các chương trình trong các ngôn ngữ này vẫn hoàn toàn dựa trên các tác dụng phụ. Các ngôn ngữ lập trình chức năng, như Scheme, Clojure, Haskell và ML là một cái gì đó hoàn toàn khác, các ngôn ngữ này gần với toán học hơn sau đó là mã máy. Thay vào đó, sau đó sử dụng các tác dụng phụ, bạn chuyển các giá trị xung quanh các hàm.

Một lựa chọn tốt của ngôn ngữ để học với mục tiêu cải thiện kỹ năng trong một ngôn ngữ ít phức tạp hơn là gì?

Tôi đề nghị Scheme , nó là tối thiểu và nó được sử dụng trong các lớp lập trình giới thiệu cũ của MIT. Các ngôn ngữ lập trình chức năng khác khó học hơn nhiều. Clojure mang theo tất cả những điều phức tạp của Java với nó, ML mang theo một hệ thống kiểu tĩnh phức tạp, đôi khi Haskell được gọi là một ngôn ngữ học thuật - nó không lý tưởng cho người mới bắt đầu, v.v. Mặt khác, sơ đồ dễ học và dễ hiểu.

Những cách nào nó cải thiện kỹ năng lập trình của bạn?

Hầu như tất cả các ngôn ngữ lập trình cấp cao đều có chức năng và đệ quy - các khái niệm mà lập trình hàm dựa trên. Do đó, kiến ​​thức về FP của bạn sẽ hữu ích ở hầu hết mọi nơi, tuy nhiên, nếu bạn thực sự muốn lập trình theo chức năng, bạn nên sử dụng một ngôn ngữ tự nhiên và hiệu quả thay vì cố gắng uốn cong thiết kế ngôn ngữ của người khác theo ý thích của bạn, nghĩa là bạn nên sử dụng một ngôn ngữ lập trình chức năng để làm lập trình chức năng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.