Tại sao lập trình mệnh lệnh được ưa thích hơn lập trình chức năng? [đóng cửa]


13

Bối cảnh: Tôi là người đề xuất lập trình chức năng làm việc tại một cửa hàng VB.NET nơi mô hình tinh thần thịnh hành là lập trình bắt buộc. Là nền tảng của hệ thống của chúng tôi là WinForms Tôi có thể hiểu rằng chúng tôi sẽ không hoàn toàn rời khỏi lập trình bắt buộc, nhưng tôi vẫn cố gắng sử dụng FP (chủ yếu thông qua Linq) bất cứ khi nào có thể bởi vì tôi tin vào giá trị của nó.

Đối số & phản biện chống lại FP

  1. Người ta có thể nhận thấy rằng Linq trôi chảy kém hiệu quả hơn so với đối tác bắt buộc của nó ở chỗ phong cách này xử lý một chuỗi xuống một chuỗi khác và lặp lại điều đó. Nói chung, nó sẽ mất nhiều lượt hơn so với cách tiếp cận bắt buộc có thể được tối ưu hóa tốt hơn để tránh lặp lại qua một chuỗi. Vì lý do này, khách hàng tiềm năng không thể hiểu tại sao tôi lại chọn cách tiếp cận chức năng rõ ràng là "kém hiệu quả".

    • Đối số : Tôi lập luận rằng mặc dù đôi khi nó kém hiệu quả hơn về chu kỳ CPU, nhưng tôi cảm thấy nó dễ hiểu hơn về con người và dễ theo dõi vì mỗi dòng chỉ thực hiện một điều trong chuỗi. Đối với tôi điều này giống như có một dây chuyền lắp ráp trong đó mỗi người tại trạm của anh ta chỉ có một công việc phải làm. Tôi cảm thấy rằng sự đánh đổi không đáng kể về hiệu quả được bù lại bằng mã mà mối quan tâm của họ được phân tách gọn gàng.
  2. Đối số tiếp theo chống lại FP mà tôi nghe thấy trong cửa hàng của mình là khó gỡ lỗi hơn - đó là sự thật. Không dễ để bước qua mã Linq. Và đôi khi tôi phải làm sáng tỏ một chuỗi phương pháp để theo dõi và phân tích tốt hơn các vấn đề mà tôi không thể phát hiện ra ngay lập tức.

    • _Cách đối số: Đối với hầu hết các phần mặc dù tôi không có vấn đề gì với điều này bởi vì tôi nghĩ rằng kiểu chức năng mang tính khai báo nhiều hơn trong cách đọc và khi một lỗi được đưa ra trong chuỗi chức năng, tôi thường có thể phát hiện ra vấn đề ngay lập tức.

Câu hỏi của tôi

Tôi đã cố gắng quảng bá phong cách chức năng trong cửa hàng của chúng tôi và tôi không cảm thấy như mình đang tiến bộ. Tôi đã thực hiện cả hai phong cách lập trình và chỉ mới học được Haskell gần đây. Mặc dù có nhiều năm kinh nghiệm bắt buộc, nhưng bây giờ tôi đang sử dụng FP thường xuyên trong JavaScript, nó đã phát triển theo tôi. Nó ghi một lưu ý về sự đúng đắn trong cốt lõi của tôi khi tôi so sánh nó với những gì tôi có thể đã làm nếu tôi mắc kẹt với một phong cách bắt buộc. Tôi đã đào tạo lại bộ não của mình về tư duy chức năng, hướng tới thành phần chức năng.

Điều tôi không thể hiểu là khó đến mức nào để thuyết phục người khác về công trạng của FP.

Ví dụ: các nhà phát triển trong cửa hàng của tôi sử dụng Linq, nhưng tôi nghĩ họ thường sử dụng nó trong bối cảnh xử lý dữ liệu miền. Tôi sử dụng nó theo nghĩa chung hơn và thích nó bất cứ lúc nào tôi đang xử lý các chuỗi / danh sách hoặc cấu trúc dữ liệu liên tục. Tôi đã không thể thuyết phục các đồng đội của mình mở rộng việc sử dụng Linq.

Điều tôi đang cố gắng hiểu là điều gì khiến nhà phát triển không thích FP.

Tôi muốn thấy một câu trả lời từ một người có nhiều kinh nghiệm với FP nhưng đã quyết định ủng hộ phong cách cấp bách. Điều gì đã dẫn đến quyết định ở lại với mệnh lệnh thay vì sử dụng chức năng?


Dưới đây là một ví dụ bổ sung nêu bật sự khác biệt giữa lập trình mệnh lệnh và chức năng.

Tôi đã viết SelectedRowsphương pháp lưới của chúng tôi trong Linq như sau:

Public Property SelectedRows() As DataRow() Implements IDataSourceControl.SelectedRows
    Get
        Return Me.ugrBase.Selected.Rows.
            OfType(Of Infragistics.Win.UltraWinGrid.UltraGridRow)().
            Select(Function(ugr) ugr.ListObject).
            OfType(Of DataRowView)().
            Select(Function(drv) drv.Row).
            ToArray
    End Get

Tuy nhiên, kiểu mã này làm cho một số nhà phát triển của chúng tôi không thoải mái và do đó, khách hàng tiềm năng của chúng tôi đã viết lại nó cho quen thuộc hơn:

Public Property SelectedRows() As DataRow() Implements IDataSourceControl.SelectedRows
    Get
        Dim plstRows As New List(Of DataRow)
        For Each bugrLoop As Infragistics.Win.UltraWinGrid.UltraGridRow In Me.ugrBase.Selected.Rows
            If bugrLoop.ListObject IsNot Nothing Then
                plstRows.Add(CType(bugrLoop.ListObject, DataRowView).Row)
            End If
        Next
        Return plstRows.ToArray()
    End Get

Tôi thích lập trình chức năng, nhưng từ cái nhìn nhanh về mã tôi sẽ thích cách tiếp cận bắt buộc (tôi gọi là khai báo ). Nó dễ đọc hơn nhiều đối với tôi - được cho rằng đây có thể là kinh nghiệm của tôi và là một sản phẩm của môi trường của tôi. Điều đó nói rằng, từ 5 giây nhanh chóng tôi có thể thấy các bước chuẩn bị và những gì được trả lại. Tôi có thể thấy có một vòng lặp và biết rằng việc điều chỉnh dữ liệu đó nhiều khả năng sẽ xảy ra trong đó. Tôi không phải theo dõi các định nghĩa chức năng; nó ở đó, nó đơn giản. Nhưng FP sạch hơn và một khi đã qua giai đoạn học tập, có lẽ sẽ nhanh như viết mã.
vol7ron

Đó là vấn đề học tập, đó là vấn đề, đặc biệt là khi làm việc với những người chỉ biết đến mức độ vừa đủ của nhiều ngôn ngữ. Nếu chuyên về bất kỳ ngôn ngữ cụ thể nào, tôi chắc chắn rằng FP sẽ là lần thử đầu tiên tốt hơn. Sau đó, nếu có sự không hiệu quả (hiệu suất thử nghiệm đơn vị), người ta có thể rõ ràng hơn trong việc triển khai của họ.
vol7ron

Câu trả lời:


11

Lập trình hàm là quá phức tạp đối với các lập trình viên thiếu kinh nghiệm . Một trong những minh họa là bức tranh này , trong đó các sinh viên tuyên bố rằng mớ hỗn độn 30-LỘC dễ hiểu và trực quan hơn so với bốn dòng tương tự FP.

(Đây là phiên bản gốc của ví dụ FP, vì câu trả lời trong liên kết đã được chỉnh sửa gần đây để dễ đọc hơn một chút.)

return this.Data.Products
    .Where(c => c.IsEnabled)
    .GroupBy(c => c.Category)
    .Select(c => new PricesPerCategory(category: c.Key, minimum: c.Min(d => d.Price), maximum: c.Max(d => d.Price)));

Lập trình chức năng đòi hỏi một cách suy nghĩ khác về cách chúng ta viết mã và cách thức thực thi mã này. Điều này hiếm khi theo cách các sinh viên được nói ở trường đại học, và một khi thói quen xấu được thực hiện, thật khó để thay đổi chúng.

Lập trình chức năng cũng có các tính năng cụ thể của riêng nó có thể xuất hiện rủi ro trong tay người mới bắt đầu . Đánh giá lười biếng là một trong số đó, và có thể mất vài tháng trước khi người ta bắt đầu hiểu tại sao đánh giá lười biếng là một tính năng tuyệt vời, và không phải là một phiền toái.

Đó cũng là lý do tại sao rất nhiều người mới bắt đầu lập trình với các ngôn ngữ như PHP chứ không phải các ngôn ngữ như Haskell.


8
Tôi đã có trải nghiệm ngược lại tại một trường đại học nơi Scheme được sử dụng cho khóa học giới thiệu. Khi sinh viên phải học Java hoặc C #, hầu hết đều phàn nàn rằng Scheme dễ đọc hơn
Daniel Gratzer

2
Điều đó chứng tỏ quan điểm của tôi. Những sinh viên đã học lập trình bắt buộc và OOP trong nhiều năm sẽ thấy nó dễ đọc hơn. Những người bắt đầu với FP sẽ thấy nó dễ đọc hơn so với lập trình bắt buộc. Sẽ rất thú vị khi biết điều gì xảy ra với những sinh viên biết rõ các mô hình FP và phi FP.
Arseni Mourzenko

1
Vấn đề chính là ngôn ngữ chức năng trừu tượng đến nhiều. Khi một Haskeller nói với bạn rằng bạn hết bộ nhớ vì bạn đã tích lũy những chiếc thun không có giá trị thì chắc chắn có điều gì đó không ổn. Rất nhiều thuật toán không hiệu quả khi chúng được viết theo kiểu chức năng. Bạn không thể thực hiện một Quicksort nhanh. trong Haskell thành ngữ. Mọi thuật toán tại chỗ kết thúc bằng việc thực hiện các mảng IO để có được hiệu năng tốt. Ngôn ngữ chức năng dành cho những người theo chủ nghĩa thuần túy ngôn ngữ, ngôn ngữ bắt buộc dành cho những người muốn suy nghĩ kịp thời.
Kr0e

3
@ Kr0e: người trừu tượng quá nhiều tranh luận về một ngôn ngữ hoặc một mô hình luôn có vẻ lạ đối với tôi. Lập luận tương tự đã được sử dụng đối với tất cả (hoặc hầu hết) ngôn ngữ; hy vọng rằng, hầu hết các phần mềm không được viết bằng Trình biên dịch ngày hôm nay.
Arseni Mourzenko

6
"Ngôn ngữ chức năng dành cho những người theo chủ nghĩa thuần túy ngôn ngữ, ngôn ngữ bắt buộc dành cho những người muốn thực hiện suy nghĩ kịp thời.": Theo kinh nghiệm của tôi thì điều này không đúng. Tôi có thể hoàn thành công việc nhanh hơn bằng ngôn ngữ chức năng. Phong cách mệnh lệnh dài dòng hơn và ít khai báo hơn và khi tôi phải sử dụng một ngôn ngữ bắt buộc, tôi chắc chắn cần nhiều lần lặp lại trước khi tôi làm mọi thứ đúng.
Giorgio
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.