Mengapa pemrograman imperatif lebih disukai daripada pemrograman fungsional? [Tutup]

13

Latar Belakang: Saya pendukung pemrograman fungsional yang bekerja di toko VB.NET di mana model mental yang berlaku adalah pemrograman imperatif. Menjadi fondasi dari sistem kami adalah WinForms, saya dapat memahami bahwa kami tidak akan sepenuhnya menjauh dari pemrograman imperatif, tetapi tetap saya mencoba menggunakan FP (terutama melalui Linq) sedapat mungkin karena saya percaya pada manfaatnya.

Argumen & kontra-argumen melawan FP

  1. Orang mungkin memperhatikan bahwa Fasih Linq kurang efisien daripada rekan imperatifnya dalam gaya ini memproses urutan ke urutan lain dan mengulanginya. Secara umum, ini akan mengambil beberapa lintasan lebih banyak daripada pendekatan imperatif yang dapat dioptimalkan lebih baik untuk menghindari lintasan berulang pada suatu urutan. Untuk alasan ini, pemimpin tidak dapat memahami mengapa saya memilih pendekatan fungsional yang jelas "kurang efisien."

    • Kontra-argumen : Saya berpendapat bahwa meskipun kadang-kadang kurang efisien dalam hal siklus CPU, saya merasa lebih dapat dipahami secara manusiawi dan mudah diikuti karena setiap baris hanya melakukan satu hal saat melewati urutan. Bagi saya ini terasa seperti memiliki jalur perakitan di mana setiap orang di stasiunnya hanya memiliki satu pekerjaan untuk dilakukan. Saya merasa bahwa pertukaran efisiensi yang dapat diabaikan dikompensasi oleh kode yang kekhawatirannya dipisahkan dengan rapi.
  2. Argumen berikutnya terhadap FP yang saya dengar di toko saya adalah bahwa lebih sulit untuk debug - yang benar. Tidak mudah untuk melangkahi kode Linq. Dan saya kadang-kadang harus mengurai rantai metode untuk mengikuti dan membedah masalah yang saya tidak bisa segera temui.

    • _Counter-argumen: Sebagian besar meskipun saya tidak memiliki masalah dengan ini karena saya pikir gaya fungsional lebih deklaratif dalam cara membaca dan ketika kesalahan dilemparkan dalam rantai fungsional, saya biasanya dapat segera menemukan masalah.

Pertanyaan saya

Saya sudah mencoba mempromosikan gaya fungsional di toko kami dan saya tidak merasa sedang mengalami kemajuan. Saya telah melakukan kedua gaya pemrograman dan baru-baru ini mencoba-coba Haskell. Terlepas dari pengalaman bertahun-tahun yang penting, sekarang saya menggunakan FP secara rutin dalam JavaScript, sudah saya miliki. Itu berdering nada kebenaran di inti saya ketika saya membandingkannya dengan apa yang mungkin saya lakukan jika saya tetap pada gaya imperatif. Saya telah melatih kembali otak saya ke arah pemikiran fungsional, ke arah komposisi fungsional.

Yang tidak bisa saya pahami adalah betapa sulitnya meyakinkan orang lain tentang manfaat FP.

Sebagai contoh, para pengembang di toko saya memang menggunakan Linq, tapi saya pikir mereka umumnya menggunakannya dalam konteks berurusan dengan data domain. Saya menggunakannya dalam arti yang lebih umum dan lebih suka kapan saja saya berurusan dengan urutan / daftar atau struktur data yang persisten. Saya belum bisa meyakinkan rekan tim saya untuk memperluas penggunaan Linq.

Apa yang saya coba pahami adalah apa yang menyebabkan pengembang tidak menyukai FP.

Saya ingin melihat jawaban dari seseorang yang memiliki banyak pengalaman dengan FP tetapi memutuskan mendukung gaya imperatif. Apa yang mendorong keputusan untuk tetap menggunakan imperatif alih-alih menggunakan fungsional?


Berikut adalah contoh tambahan yang menyoroti perbedaan antara pemrograman imperatif & fungsional.

Saya menulis SelectedRowsmetode grid kami di Linq sebagai berikut:

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

Namun, gaya kode ini membuat beberapa pengembang kami merasa tidak nyaman dan karenanya pemimpin kami menulis ulang untuk yang lebih akrab:

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
Mario T. Lanza
sumber
Saya suka pemrograman fungsional, tetapi dari melihat sekilas kode saya lebih suka pendekatan "imperatif" (saya sebut deklaratif ). Jauh lebih mudah bagi saya untuk membaca - mengingat ini bisa menjadi pengalaman saya dan menjadi produk dari lingkungan saya. Yang mengatakan, dari 5 detik cepat saya bisa melihat langkah persiapan dan apa yang dikembalikan. Saya bisa melihat ada loop dan tahu bahwa penyesuaian data itu kemungkinan besar akan terjadi di dalamnya. Saya tidak perlu melacak definisi fungsi; itu ada di sana, sederhana. Tetapi FP lebih bersih dan sekali melewati kurva belajar, mungkin akan lebih cepat untuk kode.
vol7ron
Kurva pembelajaran itulah masalahnya, terutama ketika bekerja dengan orang-orang yang hanya tahu "cukup" dari banyak bahasa. Jika berspesialisasi dalam bahasa tertentu saya yakin FP akan menjadi upaya pertama yang lebih baik. Kemudian jika ada inefisiensi (unit test performance), seseorang bisa lebih eksplisit dalam implementasinya.
vol7ron

Jawaban:

11

Pemrograman fungsional terlalu rumit untuk programmer yang tidak berpengalaman . Salah satu ilustrasinya adalah yang ini , di mana siswa menyatakan bahwa kekacauan 30-LOC lebih mudah dan lebih intuitif untuk dipahami dibandingkan dengan empat baris FP analog.

(Ini adalah versi asli dari contoh FP, karena jawaban di tautan baru-baru ini diedit untuk membuatnya sedikit lebih mudah dibaca.)

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)));

Pemrograman fungsional membutuhkan cara berpikir yang berbeda tentang cara kita membuat kode dan cara menjalankan kode ini. Ini jarang seperti cara siswa diberitahu di perguruan tinggi, dan begitu kebiasaan buruk diambil, sulit untuk mengubahnya.

Pemrograman fungsional juga memiliki fitur spesifiknya sendiri yang mungkin tampak berisiko di tangan pemula . Evaluasi malas adalah salah satunya, dan mungkin butuh berbulan-bulan sebelum orang mulai memahami mengapa evaluasi malas adalah fitur yang sangat baik, dan bukan gangguan.

Itu juga mengapa begitu banyak pemula memulai pemrograman dengan bahasa seperti PHP dan bukan bahasa seperti Haskell.

Arseni Mourzenko
sumber
8
Saya memiliki pengalaman sebaliknya di universitas tempat Skema digunakan untuk kursus intro. Ketika siswa harus belajar Java atau C # kebanyakan mengeluh bahwa Skema lebih mudah dibaca
Daniel Gratzer
2
Itu membuktikan maksud saya. Siswa yang belajar pemrograman imperatif dan OOP selama bertahun-tahun akan merasa lebih mudah dibaca. Orang yang memulai dengan FP akan merasa lebih mudah dibaca dibandingkan dengan pemrograman imperatif. Akan menarik untuk mengetahui apa yang terjadi dengan siswa yang mengetahui dengan baik FP dan non-FP paradigma.
Arseni Mourzenko
1
Masalah utama adalah bahwa bahasa fungsional banyak abstrak. Ketika seorang Haskeller memberi tahu Anda bahwa Anda kehabisan memori karena Anda mengumpulkan barang tidak terevaluasi maka pasti ada sesuatu yang salah. Banyak algoritma tidak efisien ketika ditulis dengan gaya fungsional. Anda tidak dapat mengimplementasikan impl Quicksort cepat. dalam Haskell idiomatik. Setiap algoritma di tempat berakhir dalam melakukan array IO untuk mendapatkan kinerja yang baik. Bahasa fungsional adalah untuk puritan bahasa, bahasa imperatif adalah untuk orang yang ingin menyelesaikan pemikiran pada waktunya.
Kr0e
3
@ Kr0e: argumen "abstrak terlalu banyak" terhadap suatu bahasa atau paradigma selalu terlihat aneh bagi saya. Argumen yang sama digunakan terhadap semua (atau sebagian besar) bahasa; semoga sebagian besar perangkat lunak tidak ditulis dalam Assembler hari ini.
Arseni Mourzenko
6
"Bahasa fungsional untuk puritan bahasa, bahasa imperatif adalah untuk orang yang ingin menyelesaikan pemikiran pada waktunya.": Menurut pengalaman saya ini tidak benar. Saya bisa menyelesaikan sesuatu dengan lebih cepat menggunakan bahasa fungsional. Gaya imperatif jauh lebih verbose dan kurang deklaratif dan ketika saya harus menggunakan bahasa imperatif saya pasti membutuhkan lebih banyak iterasi sebelum saya melakukan sesuatu dengan benar.
Giorgio