Tercih edilen veri yapısını neden işlevsel dillerde listeliyor?


45

Çoğu fonksiyonel dil, birincil değişken olmayan veri yapısı olarak bağlantılı listeleri kullanır. Ağaçları neden listeliyor, listelemiyor? Ağaçlar ayrıca yolları ve hatta model listelerini yeniden kullanabilir.



10
@gnat - bu, bu sorunun bir kopyası değil . Bu sorunun kabul edilen ve doğru cevabı esasen "değişmez bir bağlı liste güncellenmiş ve orijinal listeler arasında yazı paylaşımına izin verdiği için", bu sorunun arka planının bir parçası olarak gösterilen bir cevaptır ...
Jules

9
Bir açıklama noktası, bir "liste" nin (soyut programlama kavramı), bir programlama dilinin belirtilmesinden farklı olarak, "bir bağlantı listesinden" (bu kavramın belirli bir uygulamasından) farklı olmasıdır. "İşlevsel diller neden listeleri (soyut programlama kavramı) ana veri yapıları olarak kullanıyorlar?" Sorusu. ustaca ama temelde, "X, Y ve Z fonksiyonel dillerinin ortak uygulamaları neden bağlantılı listeleri ana veri yapıları olarak kullanıyorlar?"
RM

Ben (bir ağaç olarak uygulanan) scala Vector, List'e göre biraz tercih edilir. Stackoverflow.com/questions/6928327/… Uygulamada çoğu kişi hala (gördüklerimden) Listeleri kullanır.
Akavall

Scala'da Fonksiyonel Programlama dersleri aldım ve ağaçları olan bir LOT kullandım. Sadece bu liste örnekler için daha basittir. Ağaçlar performans problemleri için kullanılır. Değişmez listelere eleman eklerken, yaşlı ağaçların bir kısmını tekrar kullanarak değişmez ağaçlar oluşturabilirsiniz.
Borjab

Yanıtlar:


56

Çünkü listeler ağaçlardan daha basittir. (Bunu, bir listenin her düğümün yalnızca tek bir çocuğa sahip olduğu dejenere bir ağaç olduğu gerçeğiyle görebilirsiniz.)

Eksileri listesi keyfi boyutunda mümkün olan en basit özyinelemeli veri yapısıdır.

Guy Steele, Fortress programlama dilinin tasarımı sırasında geleceğin kitlesel paralel hesaplamaları için hem veri yapılarımızın hem de kontrol akışımızın şu anda olduğu gibi doğrusal değil, birden çok dalla ağaç şeklinde olması gerektiğini savundu. Ancak şimdilik, çekirdek veri yapı kütüphanelerimizin çoğu paralel işleme değil, sıralı, yinelemeli işlemlerle (ya da özyinelemeyle özdeşleşir, aslında önemli değil, aynı şeydir) tasarlandı.

Not mesela o kimin veri yapıları özel olarak tasarlanmış edildi Clojure, içinde için , bugünün "bulutlu" dünya, hatta diziler (Clojure denilen vektörler), muhtemelen hepsini veri yapısı "doğrusal" en dağıtılmış paralel, aslında olarak uygulanır ağaçlar.

Yani, kısacası: eksileri listesi mümkün olan en basit kalıcı özyinelemeli veri yapısıdır ve daha karmaşık bir "varsayılan" seçmeye gerek yoktu. Diğerleri elbette seçenekler olarak mevcut, örneğin Haskell'de diziler, öncelik sıraları, haritalar, yığınlar, ikramlar, denemeler ve hayal edebileceğiniz her şey var, ancak varsayılan basit eksiler listesi.


10
Evet, Clojure vektörleri ağaçlar olarak uygulanır - ancak standart ikili dosyalarınız için değil, eşlenmiş dizi eşlemesi denemeleri olduklarına dikkat çeker data Tree a = Leaf a | Branch a (Tree a) (Tree a). Bu "basitlik" argümanınızı güçlendirir.
wchargin

1
FWIW Clojure'un kalıcı vektörleri (@wchargin biraz karmaşık bir şekilde işaret ettiği gibi) hızlı bir şekilde (büyük bir tabana sahip logaritmik) ağaçlara erişim ve rastgele öğelerin güncellenmesi olarak uygulanmaktadır. derece, aşama). Diğer FP dilleri, her ikisini de istediklerinde (örneğin Haskell'in Sequenceveya Scala'nın Vector) aynı seçimi yapar (bazen farklı türdeki ağaçlarda) , ancak yalnızca gerçek zamanlı olarak başarabilecekleri için okumaya ihtiyaç duyduklarında ağaçları kullanmazlar (örn. Haskell'in Vectorveya F # ile. ImmutableArray
Net'in

1
Örneğin pmap, Clojure'deki bir vektöre ping işlemi, her bir elemana sırayla erişir; vektörün ağaç yapısı genellikle son kullanıcıdan gizlenir.
badcook

5

Aslında bu listelere olan ağaçlar! İki alana sahip olan carve cdrbu gibi düğümleri veya yaprakları daha fazla içerebilen düğümleriniz var. Bu ağaçları listeler haline getiren tek şey , bağlantıyı doğrusal bir listedeki bir sonraki düğüme bağlantı olarak ve bağlantıyı da geçerli düğümün değeri olarak yorumlama kuralıdır .cdrcar

Bununla birlikte, işlevsel programlamada bağlantılı listelerin prevalansının yineleme üzerindeki yineleme prevalansı ile ilişkili olduğunu tahmin ediyorum. Eldeki tek döngü yapınız (kuyruk) özyineleme olduğunda, bununla kullanımı kolay veri yapılarını istersiniz; ve bağlantılı listeler bunun için mükemmeldir.


5
bu dile bağlıdır. Elbette, eksilerini kullanarak LISP-seviyor bir ağacı uygulayabilirsiniz, ancak Haskell'de, örneğin, tamamen ayrı bir yapıya ihtiyacınız olacaktır. Ayrıca, çoğu işlevsel dilin kuyruk özyinelemeden çok daha fazla döngüsel yapıya sahip olduğunu unutmayın . Örneğin Haskell çekirdek kütüphaneleri, kıvrımlar (sol ve sağ), taramalar, ağaçlar üzerinde geçişler, haritaların anahtar ve değerlerinin yinelenmesi ve daha birçok özel yapı sağlar. Elbette, sahnelerin arkasına özyinelemeyle uygulandılar, ancak kullanıcının çalışması için bunu düşünmesine bile gerek yok.
Jules

@Jules Yine de, fonksiyonel programlama geliştirildi ve LISP gibi dillerden oldukça etkilendi. Açıkçası, tüm bu liste yinelemeyi kaputun altındaki dizileri kullanarak daha verimli hale getirmek veya bir listenin doğasını gizleyen sözdizimsel şeker eklemek mümkündür, ancak saf fonksiyonel programlama yapabilir ve yapabilir. Ayrıca, Haskell oldukça işlevsel bir dildir (LISP'den 32 yaş küçük), tamamen işlevsel bir tarza biraz başka fikirler, sözdizimsel şeker vb. Ekler. Sanırım, işlevsel programlamayı Haskell'i değerlendirerek yargılamak biraz mikserleri yargılayarak yargılamak gibi ...
cmaster

2
@cmaster Haskell daha gençken hala 27 yaşında ve pek çok dili etkiledi (Python, Java ve C # dahil olmak üzere birkaç etkili). Fonksiyonel programlamanın LISP tarafından yargılanması, ALGOL tarafından yapılan zorunlu programlamanın yargılanması gibidir - her ikisi de tanınmayacak kadar uzun bir yol kat eder. TAMAM. Lisp tartışmaya açık bir şekilde hala konuyla ilgili, ancak 'ana akım' olduğunu düşünmezdim ve daha sonra ML tipleri de dahil olmak üzere pek çok anlayışı özlüyorum.
Maciej Piechotka

1
Tüm ağaca dokunmak istiyorsanız, tek tek bağlantılı ağaçları kuyruk tekrarlı olarak veya tekrarlı olarak açık bir yığın olmadan işleyemezsiniz, bu nedenle kuyruk özyinelemenin bununla bir ilgisi olduğunu sanmıyorum.
k_g

@ MaciejPiechotka Ne Python, Java, ne de C # fonksiyonel dil olarak görülemez, zorunludur ve fonksiyonel programlamadan ilham alan birkaç özellik ekler. Durumunuz değiştikten sonra, zorunlu programlama yerine işlevsel programlama alanının içindesinizdir. Bununla birlikte, LISP'nin kesinlikle ana akım olmadığı konusunda hemfikiriz.
cmaster
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.