Pertanyaannya adalah:
- Apakah generator melanggar paradigma pemrograman fungsional? Mengapa atau mengapa tidak?
- Jika ya, dapatkah generator digunakan dalam pemrograman fungsional dan bagaimana caranya?
Pertimbangkan yang berikut ini:
function * downCounter(maxValue) {
yield maxValue;
yield * downCounter(maxValue > 0 ? maxValue - 1 : 0);
}
let counter = downCounter(26);
counter.next().value; // 26
counter.next().value; // 25
// ...etc
The downCounter
Metode muncul bernegara. Selain itu, panggilan downCounter
dengan input yang sama, akan selalu menghasilkan output yang sama. Namun, pada saat yang sama, panggilan next()
tidak menghasilkan hasil yang konsisten.
Saya tidak yakin apakah generator merusak paradigma pemrograman fungsional atau tidak karena dalam contoh ini counter
adalah objek generator dan pemanggilan next()
akan menghasilkan hasil yang sama seperti objek generator lain yang dibuat dengan sama persis maxValue
.
Selain itu, memanggil someCollection[3]
array akan selalu mengembalikan elemen keempat. Demikian pula, memanggil next()
empat kali pada objek generator juga akan selalu mengembalikan elemen keempat.
Untuk lebih banyak konteks, pertanyaan-pertanyaan ini muncul saat mengerjakan kata pemrograman . Orang yang menjawab pertanyaan, mengajukan pertanyaan apakah generator dapat digunakan dalam pemrograman fungsional atau tidak.
Jawaban:
Fungsi generator tidak terlalu istimewa. Kita dapat menerapkan mekanisme serupa sendiri dengan menulis ulang fungsi generator dengan gaya berbasis panggilan balik:
Jelas,
downCounter
itu murni dan fungsional karena mendapat. Tidak ada masalah di sini.Protokol generator yang digunakan oleh JavaScript melibatkan objek yang bisa berubah. Ini tidak perlu, lihat kode di atas. Secara khusus, objek yang bisa berubah berarti kita kehilangan transparansi referensial - kemampuan untuk mengganti ekspresi dengan nilainya. Sementara dalam contoh saya,
counter.next().value
akan selalu mengevaluasi ke25
mana pun itu terjadi dan seberapa sering kita mengulanginya, ini tidak terjadi dengan generator JS - pada satu titik itu26
, maka25
, dan itu bisa benar-benar nomor apa pun. Ini bermasalah jika kita meneruskan referensi ke generator ke fungsi lain:Jadi jelas, generator memegang keadaan dan karenanya tidak cocok untuk pemrograman fungsional "murni". Untungnya, Anda tidak harus melakukan pemrograman fungsional murni, dan mungkin lebih pragmatis. Jika generator membuat kode Anda lebih jelas, Anda harus menggunakannya tanpa hati nurani yang buruk. Lagipula, JavaScript bukanlah bahasa fungsional murni, tidak seperti misalnya Haskell.
Omong-omong, di Haskell tidak ada perbedaan antara mengembalikan daftar dan generator, karena menggunakan evaluasi malas:
sumber