Seperti yang ditunjukkan Yannis , ada sejumlah faktor yang memengaruhi adopsi fungsi tingkat tinggi dalam bahasa yang sebelumnya tidak ada. Salah satu hal penting yang hanya disentuhnya sedikit adalah proliferasi prosesor multi-core dan, dengan itu, keinginan untuk pemrosesan yang lebih paralel dan bersamaan.
Peta / filter / pengurangan gaya pemrograman fungsional sangat ramah terhadap paralelisasi, yang memungkinkan programmer untuk dengan mudah menggunakan banyak core, tanpa menulis kode threading eksplisit.
Sebagai Giorgio mencatat, ada lebih banyak pemrograman fungsional dari sekedar fungsi tingkat tinggi. Fungsi, ditambah peta / filter / mengurangi pola pemrograman, dan imutabilitas adalah inti dari pemrograman fungsional. Bersama-sama hal-hal ini menjadi alat yang kuat untuk pemrograman paralel dan bersamaan. Untungnya, banyak bahasa sudah mendukung beberapa gagasan tentang kekekalan, dan, bahkan jika tidak, pemrogram dapat memperlakukan hal-hal sebagai kekal memungkinkan perpustakaan dan kompiler untuk membuat dan mengelola operasi asinkron atau paralel.
Menambahkan fungsi tingkat tinggi ke bahasa adalah langkah penting untuk menyederhanakan pemrograman bersamaan.
Memperbarui
Saya akan menambahkan beberapa contoh yang lebih rinci untuk mengatasi masalah yang dicatat Loki.
Pertimbangkan kode C # berikut yang melintasi koleksi widget, membuat daftar harga widget baru.
List<float> widgetPrices;
float salesTax = RetrieveLocalSalesTax();
foreach( Widget w in widgets ) {
widgetPrices.Add( CalculateWidgetPrice( w, salesTax ) );
}
Untuk koleksi besar widget, atau metode CalculateWidgetPrice (Widget) yang intensif secara komputasi, loop ini tidak akan memanfaatkan core yang tersedia dengan baik. Untuk melakukan perhitungan harga pada inti yang berbeda akan membutuhkan programmer untuk secara eksplisit membuat dan mengelola utas, melewati pekerjaan di sekitar, dan mengumpulkan hasilnya bersama-sama.
Pertimbangkan solusi setelah fungsi tingkat tinggi ditambahkan ke C #:
var widgetPrices = widgets.Select( w=> CalculateWidgetPrice( w, salesTax ) );
Foreach loop telah dipindahkan ke metode Select, menyembunyikan detail implementasinya. Yang tersisa bagi programmer adalah memberi tahu Pilih fungsi apa yang akan diterapkan pada setiap elemen. Ini akan memungkinkan implementasi Select untuk menjalankan perhitungan dalam parellel, menangani semua masalah sinkronisasi dan manajemen thread tanpa keterlibatan programmer.
Tapi, tentu saja, Select tidak melakukan itu secara paralel. Di situlah immutabilitas masuk. Implementasi Select tidak tahu bahwa fungsi yang disediakan (CalculateWidgets di atas) tidak memiliki efek samping. Fungsi ini dapat mengubah status program di luar tampilan Select dan sinkronisasi, merusak segalanya. Misalnya, dalam hal ini nilai salesTax dapat diubah karena kesalahan. Bahasa fungsional murni memberikan kekekalan, sehingga fungsi Select (peta) dapat mengetahui dengan pasti bahwa tidak ada keadaan yang berubah.
C # mengatasinya dengan menyediakan PLINQ sebagai alternatif untuk Linq. Itu akan terlihat seperti:
var widgetPrices = widgets.AsParallel().Select(w => CalculateWidgetPrice( w, salesTax) );
Yang memanfaatkan sepenuhnya semua inti dari sistem Anda tanpa manajemen eksplisit dari inti tersebut.