Sebagian besar bahasa fungsional menggunakan daftar tertaut sebagai struktur data utama yang tidak dapat diubah. Mengapa daftar, dan bukan pohon misalnya? Pohon juga dapat menggunakan kembali jalur, dan bahkan daftar model.
Sebagian besar bahasa fungsional menggunakan daftar tertaut sebagai struktur data utama yang tidak dapat diubah. Mengapa daftar, dan bukan pohon misalnya? Pohon juga dapat menggunakan kembali jalur, dan bahkan daftar model.
Jawaban:
Karena daftar lebih sederhana daripada pohon. (Anda dapat melihat ini sepele dengan fakta bahwa daftar adalah pohon yang merosot, di mana setiap node hanya memiliki satu anak.)
Daftar kontra adalah struktur data rekursif paling sederhana yang mungkin dari ukuran sewenang-wenang.
Guy Steele berpendapat selama desain bahasa pemrograman Fortress bahwa untuk komputasi paralel masif masa depan, baik struktur data kami dan aliran kontrol kami harus berbentuk pohon dengan banyak cabang, tidak linier seperti sekarang. Tetapi untuk saat ini, sebagian besar pustaka struktur data inti kami dirancang dengan pemrosesan berurutan, iteratif (atau rekursi ekor, itu tidak terlalu penting, mereka adalah hal yang sama) dalam pikiran, bukan pemrosesan paralel.
Perhatikan bahwa misalnya dalam Clojure, yang struktur datanya dirancang khusus untuk dunia paralel, terdistribusi, "berawan" saat ini, bahkan array (disebut vektor dalam Clojure), mungkin struktur data yang paling "linier" dari semuanya, sebenarnya diimplementasikan sebagai pohon.
Jadi, singkatnya: daftar kontra adalah struktur data rekursif persisten yang paling sederhana, dan tidak perlu memilih "default" yang lebih rumit. Yang lain tentu saja tersedia sebagai opsi, misalnya Haskell memiliki array, antrian prioritas, peta, heaps, treaps, mencoba, dan semua yang dapat Anda bayangkan, tetapi defaultnya adalah daftar kontra sederhana.
data Tree a = Leaf a | Branch a (Tree a) (Tree a)
. Ini memperkuat argumen "kesederhanaan" Anda.
Sequence
atau Scala's Vector
), tetapi tidak menggunakan pohon ketika mereka hanya perlu membaca karena mereka dapat mencapainya dalam waktu konstan yang benar (mis. Haskell's Vector
atau F # via .Net's ImmutableArray
)
pmap
ping pada vektor di Clojure masih mengakses setiap elemen secara berurutan; struktur pohon vektor umumnya disembunyikan dari pengguna akhir.
Sebenarnya, daftar itu adalah pohon! Anda memiliki node dengan dua bidang, car
dan cdr
, yang dapat berisi lebih banyak node, atau daun. Satu-satunya hal yang membuat pohon-pohon ke dalam daftar, adalah konvensi untuk menafsirkan dengan cdr
link yang sebagai link ke node berikutnya dalam daftar linear, dan car
hubungan sebagai nilai node saat.
Yang mengatakan, saya kira bahwa prevalensi daftar terkait dalam pemrograman fungsional terkait dengan prevalensi rekursi atas iterasi. Ketika satu-satunya konstruksi looping yang Anda miliki adalah rekursi (tail-), Anda menginginkan struktur data yang mudah digunakan dengan itu; dan daftar tertaut sangat cocok untuk itu.