2016-04-08 8 views
5

Rich, vektörü, haritayı ve set işlevlerini oluştururken, liste ve sıra işlevler değildir. Neden tüm bu koleksiyonlar tutarlı hale getirmek için çalışamaz? Bu da iç veri var etmek pozisyonunu eşleştiren bir fonksiyonu olarak veri oluşturan tümTasarımcı niçin clojure'da vektör, harita ve işlevler yaptı?

Dahası, neden yapmazlar? Biz fonksiyonu olarak bütün bu oluşturma verileri yaparsanız

sonra Clojure tek fonksiyonu ve atom verisi olacak. Bu, bu dilde temel unsurları en aza indirecek?

inanıyorum minimal, iyi sadece 2, dil, daha basit daha etkileyici ve daha esnek kılacak temel unsurlarından ayarlayın. Bu doğru mu?

+0

Liste ve sıra arasında fark var mı? –

+0

Yığın akışına hoş geldiniz, başkalarının zihninin durumuyla ilgili soruları "doğru" veya "yanlış" olarak işaretleyebilmenizi sağlayacak şekilde yanıtlamak zordur, bu nedenle nesnel olarak bu soruyu yanıtlamak zordur. –

+0

@BobJarvis dizisi, liste dahil olmak üzere tüm koleksiyon türleri tarafından uygulanan bir arabirimdir. –

cevap

9

Vektörler, haritalar ve setler tüm ilişkisel veri yapılarıdır. Haritalar en belirgin olanıdır; sadece keyfi anahtarları keyfi değerlerle ilişkilendirirler. Bir vektör, anahtar kümesi, vektörün boyutundan daha az olan tüm negatif olmayan tam sayıların kümesi olması gereken bir harita olarak düşünülebilir. Son olarak, kümeler kendilerine anahtarlar eşleyen haritalar olarak düşünülebilir.

Bir vektör ve vektör ilişkisel doğanın sıralı doğası iki ortogonal şeyler olduğunu anlamak önemlidir. Her iki soyutlamayı desteklemek için iyi tasarlanmış bir veri yapısıdır (örneğin bir vektörün başlangıcına etkili bir şekilde yerleştiremezsiniz).

Listeler vektörlere daha basittir; Sonlu sıralı veri yapılarıdır, başka bir şey değildir. Bir liste, öğeyi belirli bir dizinde verimli bir şekilde döndüremez, bu nedenle bu işlevselliği çekirdek arabiriminin bir parçası olarak göstermez. Tabii ki, , nth kullanarak dizine göre bir listenin bir öğesini alabilir, ancak bu durumda, bir ilişkisel yapı olarak dizisi olarak açıkça işleme tabi tutuyorsunuz demektir.

Sorunuzu yanıtlamak için, vektörler, haritalar ve kümeler için IFn uygulamaları, ilişkisel veri yapısı fikri ile salt işlev fikri arasındaki son derece yakın ilişki nedeniyle ortaya çıkmıştır. Listeler ve diğer diziler doğası gereği birleştirici değildir; dolayısıyla tutarlılık için IFn uygulanmaz.

+0

Clojure'daki setin özelliklerini kontrol ettim, ilişkisel bir yapı değil gibi görünüyor. Çalıştır: (# 1 {1 2} 1 inc'i güncellemeniz) istisna alırsınız: PersistentHashSet clojure.lang.Associative 'e dönüştürülemez – Shark

+0

@Shark "İlişkilendirme" ile, tam anlamıyla "[Associative"]' in uygulanması anlamına gelmedim (https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Associative.java) arayüz "; daha ziyade, anahtarlardan değerlere kadar sorguları verimli bir şekilde desteklediklerini kastettim. Clojure'de, sadece [özel bir durum] olarak ele alınacak ayarlar (https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/RT.java#L746-L749), ancak Bu, doğal olarak verimli aramaları desteklediklerini ve listelemelerini değiştirmez. –

+0

Teşekkürler kaynak kodunu göster. Şimdi, Set'in clojure'daki tip tanımında bir kusur olduğunu söyleyebilir miyim? Oluşmasını sağlamak için Birleştirici uygulamak için varsayalım? – Shark

2

Elogent cevabı mükemmel. Listelerin fonksiyon olması mantıklı olmayacak bir neden daha vardır:

Literal listeler zaten farklı, çok önemli bir role sahiptir, bu yüzden bunlar, vektörlerin olduğu şekilde fonksiyon olarak ele alınamazlar.

İki işlev içeren bir vektörle başlayalım: partial ve + ve bir sayı, 5. Bildiğiniz gibi onun argüman tarafından dizine değeri döndürmek için, bir fonksiyon olarak vektör tedavi edebiliriz, o kadar iyi

user=> ([partial + 5] 2) 
5 

Şimdiye kadar. 5 değerini döndürmek için, önerdiğiniz gibi vektör yerine (partial + 5) numaralı bir listeyi kullanmak istediğimizi varsayalım. Bir hata mesajı alır mıyız? Yok hayır!

user=> ((partial + 5) 2) 
7 

ne oldu: Ama biz, ya sonucunda 5 almazsınız? (partial + 5) bir işlevi döndürdü - tek bağımsız değişkenine 5 ekleyen işlev - ve bu işlev 2 argümanına uygulandı.

Bir liste değerlendirildiğinde, ilk öğesi değerlendirilir ve bir işlev döndürmelidir. İlk öğe bir sembolse, değerlendirilir ve sonra değerinin, listenin diğer öğeleri olan argümanlara uygulandığı işlevdir. Bir listenin ilk argümanı bir listenin kendisi ise, o zaman en üst seviyede olsaydı değerlendirilmesiyle aynı şekilde değerlendirilir. Bu iç listedeki tüm ifade, bir dış fonksiyonun diğer öğelerine uygulanacak bir işlev döndürmelidir.

Değerlendirilmekte olan listenin ilk öğesi olan bir iç liste zaten bu role sahip olduğundan, ilk öğeleri olan vektörlerin oynadığı rol türünü de oynayamaz.

+0

Sanırım iblisini değiştirmek zorundasın ('(parsiyel + 5) 2) – Shark

+0

Kote edilmemeyi istemedim, ve eğer öyleyse, verdiğim kod benim söylediğimi yapmazdı. Ama iyi bir noktanız var: '' ([: a: b] 1) 'ya da' ('[: a: b] 1) '' ye benzer, '(' (: a: b) 1)', bir hata oluşturur. O zaman Elogent'in cevabının alakalı olduğunu düşünüyorum - özellikle verimlilik hakkında. Bir vektör girişine erişmek hızlıdır; indeksleme veya başka bir hızlı yöntemi içerir. Haritalar ve kümelere erişmek hızlıdır çünkü bunlar karma kullanmaktadır. Bu erişim, basit bir işlev gibi basit bir hesaplamayı içerir. Liste erişimi yavaştır, çünkü bir işaretçiyi tekrar tekrar birbiri ardına kapmak olabilir. – Mars