Mengapa beberapa bahasa fungsional memerlukan memori transaksional perangkat lunak?

24

Bahasa fungsional, menurut definisi, seharusnya tidak mempertahankan variabel status. Lalu, mengapa Haskell, Clojure, dan lainnya menyediakan implementasi perangkat lunak memori transaksional (STM)? Apakah ada konflik antara dua pendekatan?

Michael Spector
sumber
Saya hanya ingin menghubungkan makalah menarik ini yang menjelaskan banyak hal.
Falcon
1
Agar lebih jelas, semua bahasa fungsional mempertahankan status, tetapi kemurnian menentukan bahwa nilai variabel tidak berubah setelah ditetapkan.
Robert Harvey

Jawaban:

13

Tidak ada yang salah dengan bahasa fungsional yang mempertahankan status bisa berubah. Bahkan bahasa fungsional "murni" seperti Haskell perlu mempertahankan status untuk berinteraksi dengan dunia nyata. Bahasa fungsional "Najis" seperti Clojure memungkinkan efek samping yang dapat mencakup keadaan bermutasi.

Poin utamanya adalah bahwa bahasa-bahasa fungsional mencegah negara yang tidak bisa berubah kecuali Anda benar-benar membutuhkannya . Gaya umum adalah memprogram menggunakan fungsi murni dan data yang tidak dapat diubah, dan hanya berinteraksi dengan keadaan tidak berubah yang "tidak murni" di bagian spesifik kode Anda yang memerlukannya. Dengan begitu, Anda dapat menjaga sisa basis kode Anda "murni".

Saya pikir ada beberapa alasan mengapa STM lebih umum dalam bahasa fungsional:

  • Penelitian : STM adalah topik penelitian yang panas, dan peneliti bahasa pemrograman sering lebih suka bekerja dengan bahasa fungsional (topik penelitian ulang sendiri, plus lebih mudah untuk membuat "bukti" tentang perilaku program)
  • Kunci tidak disusun : STM dapat dilihat sebagai alternatif untuk pendekatan berbasis kunci untuk konkurensi, yang mulai mengalami masalah ketika Anda meningkatkan sistem yang kompleks dengan menyusun komponen yang berbeda. Ini bisa dibilang alasan "pragmatis" utama untuk STM
  • STM sangat cocok dengan kekekalan : Jika Anda memiliki struktur kekal yang besar, Anda ingin memastikannya tetap kekal, jadi Anda tidak ingin ada utas lain masuk dan memutasi beberapa sub-elemen. Demikian juga, jika Anda dapat menjamin kekekalan dari struktur data tersebut, Anda dapat andal memperlakukan sebagai "nilai" yang stabil di sistem STM Anda.

Saya pribadi menyukai pendekatan Clojure yang memungkinkan mutabilitas, tetapi hanya dalam konteks "referensi terkelola" yang dikendalikan secara ketat yang dapat berpartisipasi dalam transaksi STM. Segala hal lain dalam bahasa ini "murni fungsional".

  ;; define two accounts as managed references
  (def account-a (ref 100))
  (def account-b (ref 100))

  ;; define a transactional "transfer" function
  (defn transfer [ref-1 ref-2 amount]
    (dosync
      (if (>= @ref-1 amount)
        (do 
          (alter ref-1 - amount)
          (alter ref-2 + amount))
        (throw (Error. "Insufficient balance!")))))

  ;; make a stranfer
  (transfer account-a account-b 75)

  ;; inspect the accounts
  @account-a
  => 25

  @account-b
  => 175

Perhatikan bahwa kode di atas sepenuhnya transaksional dan atomik - pengamat eksternal yang membaca dua saldo dalam transaksi lain akan selalu melihat keadaan atom yang konsisten, yaitu dua saldo akan selalu berjumlah 200. Dengan konkurensi berbasis kunci, ini merupakan masalah yang sangat sulit. untuk menyelesaikan dalam sistem kompleks besar dengan banyak entitas transaksional.

Untuk beberapa pencerahan tambahan, Rich Hickey melakukan pekerjaan yang sangat baik untuk menjelaskan STM Clojure dalam video ini

mikera
sumber
3

Bahasa fungsional, menurut definisi, seharusnya tidak mempertahankan variabel status

Definisi Anda salah. Bahasa yang tidak dapat mempertahankan status tidak bisa digunakan.

Perbedaan antara bahasa fungsional dan imperatif bukanlah bahwa salah satu dari mereka memiliki negara dan yang lainnya tidak. Dengan cara mereka mempertahankan negara.

Bahasa imperatif memiliki status penyebaran di seluruh program.

Bahasa fungsional mengisolasi dan mempertahankan status secara eksplisit melalui tanda tangan jenis. Dan itulah alasan mereka menyediakan mekanisme manajemen negara yang canggih seperti STM.

Vagif Verdi
sumber
2

Terkadang suatu program membutuhkan keadaan yang bisa berubah-ubah (misalnya, isi basis data untuk aplikasi web) dan akan bagus untuk dapat menggunakannya tanpa kehilangan manfaat pemrograman fungsional. Dalam bahasa non-fungsional, keadaan yang bisa berubah merasuki segalanya. Jika Anda membuatnya eksplisit dengan semacam API khusus , maka Anda dapat membatasinya ke wilayah kecil yang dapat diidentifikasi sementara yang lainnya tetap berfungsi murni. Manfaat FP termasuk debugging yang lebih mudah, pengujian unit berulang, konkurensi tanpa rasa sakit, dan keramahan multicore / GPU.

Will Ware
sumber
Anda mungkin berarti keadaan bisa berubah. Semua program mempertahankan keadaan, bahkan yang fungsional.
Robert Harvey
Kamu benar. Jelas saya tidak menghabiskan cukup waktu melakukan pemrograman fungsional, untuk melewatkan itu.
Will Ware