Veri yapıları dile (Python'da olduğu gibi) entegre edilmeli mi veya standart kütüphanede (Java'da olduğu gibi) sunulmalı mı?


21

Python'da ve büyük olasılıkla birçok diğer programlama dilinde, ortak veri yapıları kendi dillerinin sözdizimi ile çekirdek dilin bütünleşmiş bir parçası olarak bulunabilir . LISP'nin tümleşik liste sözdizimini bir kenara koyarsak, dizinin üstünde bir tür veri yapısı sağlayan, başka bir deyişle, sözdizimlerinin bütünleşik bir parçası olarak bildiğim diğer dilleri düşünemiyorum (ama C, sanırım) Standart kütüphanede onları sağlamak gibi görünüyor.

Dil tasarımı açısından bakıldığında, çekirdek dilde veri yapıları için belirli bir sözdizimine sahip olma hakkındaki görüşleriniz nelerdir? Bu iyi bir fikir midir ve dilin (vb.) Amacı bunun bir seçimde ne kadar iyi olabileceğini değiştirir mi?

Düzenleme: (görünüşe göre) hangi veri yapıları hakkında bazı karışıklığa neden olduğu için üzgünüm. Temel ve sık kullanılanlar hakkında konuşurum, ancak hala en temelleri değil. Bu, ağaçları (çok karmaşık, nadir), yığınları (nadiren kullanılan), dizileri (çok basit) içermez, ancak örneğin kümeleri, listeleri ve hasheleri içerir.


1
Nesneyi ve hashipi dışlıyor muyuz?
Orbling

3
@Anto: Pek çok dil, ortak diziler, Perl, PHP, JS (teknik olarak burada bir nesne) vb.
Şeklinde hashpalara sahiptir

1
Belki de, diziler, listeler dışında, hashpalar / ilişkisel diziler dışında, hangi veri yapılarını düşündüğünüz hakkında daha spesifik olabilirsiniz?
SinirliFormsDesigner ile

1
"Karmaşık veri yapıları" olarak hashmapler, listeler ve daha gelişmiş olanları ekleyin ve dizileri çok basit bir şekilde atın.
Anto

1
Daha mantıklı bir unvanın şöyle bir şey olacağını düşünüyorum: “Dilde hangi veri yapıları yer almalı ve kütüphanede ne var?” Anlamlı bir cevap yine de dile bağlıdır: Kütüphane dilin ne kadar net bir şekilde bütünleştirilirse, yapıları kütüphaneye taşımanın o kadar makul bir yolu vardır.
Jerry Coffin

Yanıtlar:


13

Bu dilin ne için olduğuna bağlı.

Bazı örnekler (diğer cevaplardan biraz çalındı):

  • Perl'de karma, diziler ve dizgiler için özel bir sözdizimi vardır. Perl komut dosyası için genellikle kullanılır, bunlar komut dosyası için kullanışlıdır.
  • Matlab, listeler, matrisler, yapılar için özel bir sözdizimine sahiptir. Matlab mühendislik için matris ve vektörel matematik yapmak içindir.
  • Java / .NET destek dizesi ve dizileri. Bunlar, dizilerin ve dizgelerin sıklıkla kullanıldığı (yeni koleksiyon sınıflarının kullanılmasıyla daha az) genel amaçlı dillerdir.
  • C / C ++ destek dizileri. Bunlar sizden donanım saklamayan dillerdir. Dizeler kısmen desteklenir (birleştirme, strcpy vb. Kullanma)

Sanırım, dilinizin amacının / ruhunun / izleyicisinin ne olduğuna bağlı; donanımdan ne kadar soyut ve ne kadar uzak olmasını istersiniz. Genelde listeleri ilkel olarak destekleyen diller, sonsuz uzun listeler oluşturmanıza olanak sağlar. C / C ++ gibi düşük seviye asla buna sahip olmaz, çünkü amaç bu değil, bu dillerin ruhu.

Bana göre, çöp toplama aynı mantığı izler: dilinizdeki izleyici tam olarak ne zaman ve bellek tahsis edilip edilmediğini veya serbest bırakıldığını bilmekle ilgilenir mi? Eğer öyleyse, malloc / ücretsiz; eğer değilse, o zaman çöp toplama.


6
Burası "C / C ++" terimini kullanmak için kötü bir yer çünkü C ++ 'da üst düzey şablon türlerinin varlığı iki dil arasında büyük bir fark var.
dan04

Çöp toplama işlemi deterministik bir şekilde yapılabilir, sadece lineer tiplere ihtiyacınız var (veya onların fakir adamlarının yerine koyması: RAII).
pyon

@ EduardoLeón, çöp toplama alanını deterministik bir noktada çağırabilseniz de, ne kadar süre çalışacağının deterministik olduğunu sanmıyorum (aynı nedenle mallocve newC / C ++ 'da deterministik değil).
earnNameless

@earlNameless: Kaynağın kullanımına göre belirleyicidir: lineer türler (veya benzer olan benzersiz türler), kaynakları serbest bırakmamak için bir tür hatası yapar (ve dolayısıyla derleme hatası) tür tarafından yakalanmamış (modulo olasılığı) sistemi, herhangi bir anormal program sonlandırmasının) veya imha edildikten sonra kullanmak.
pyon

5

Perl'de hashmaps var ve PL / SQL kayıtları destekliyor ve her farklı boyuttaki vektörleri ve matrisleri desteklemek için sözdizimi olan matlabın sisli hatıraları var (bununla ilgili yanılıyor olabilirim ve bunların veri türü olmadığını iddia ediyor olabilirim) yapılar )… Çok yaygın yapılar için bazı yerel desteğe sahip olmanın güzel olduğunu söyleyebilirim. Genellikle, diziler ve hashpalar / ilişkisel diziler, en yaygın şekilde doğal olarak desteklenen yapılardır ve muhtemelen en sık kullanılanlarıdır.

Unutmayın, ikili ağaçlar gibi diğer yapılar için yerel sözdizimi desteği eklerseniz, bu yapıların dilin destekleyici araçları (compiler / runtime / etc) tarafından da uygulandığını unutmayın. Kaç tane yapı için destek oluşturmak istiyorsun?

Daha az yerel olarak desteklenen yapılar için yeni gösterimler icat etmeniz gerekecek ... Basitleştirin!


Ağaçlar için gerçek bir sözdizimi icat etmeye gerek yok - ağaçlar daha nadir, pek çok dilin stdlibinde bile değiller! Aynı argümanla, operatörlerin dahil edilmesine karşı çıkılabilir çünkü “daha ​​az kullanılan operasyonlar için yeni gösterimi icat etmeniz gerekecek”.

@delnan: Bunu anlama biçimim, yeni bir dil tasarlama ve dizilerin yanı sıra veri yapılarının da (muhtemelen) yeni sözdizimi ile doğal olarak desteklenip desteklenmediğini veya bir kütüphane ekleyerek desteklenip desteklenmediğini merak etme perspektifindendi .
SinirliFormsDesigner ile

Ben OP olduğunu varsayalım böylece Peki, ilk cümle açıkça, "ortak veri yapıları" bahsediyor değil şimdiye kadar icat her karanlık veri yapısı için özel bir sözdizimi eklemek denemek için deli yeter.

@delnan: ... ve sonra OP, LISP listelerini ve dizileri (genel olarak) hariç tutmaya devam ediyor "... LISP'nin bütünleşik liste sözdizimini bir kenara koydu, hangi türden bir dil sağlayan, başka bir dil bilmiyorum. dizinin yukarısındaki veri yapısı , sözdizimlerinin bütünleşmiş bir parçası olarak "... bu yüzden veri yapılarını dizilerden / listelerden daha egzotik düşündüklerini sanıyordum ...
FrustratedWithFormsDesigner

Evet ("dizilerin üzerinde" "diğer ortak veri yapıları" olarak yorumladım), ancak sorudaki hiçbir şey "sahip olduğumuz her veri yapısı için hazır bilgi yapalım" anlamına gelmiyor. Bunun makul olanla sınırlı olması gerektiğini söylemek doğru, ancak bu varsayımdan dolayı "kötü fikir" diyebileceğimizi sanmıyorum .

5

Buradaki en sevdiğim örnek Lua . Lua'nın tek bir dahili veri türü olan " tablo " vardır, ancak esnekliği ve hızı, onları düzenli diziler, bağlantılı listeler, sıralar, haritalar yerine kullandığınız anlamına gelir ve hatta Lua'nın nesne yönelimli özelliklerinin temelini oluşturur. (yani sınıflar).

Lua inanılmaz derecede basit bir dil, ancak tablo veri yapısının esnekliği de onu oldukça güçlü kılıyor.


2
JavaScript nesneleri gerçekten aynıdır - Diziler sadece sayısal özellikleri ve uzunluğu olan nesnelerdir.
Tikhon Jelvis

1
Lua tabloları JavaScript Nesneleri'nden farklıdır: JavaScript'te {}değil [], Lua'da {}her ikisine de sahipsiniz . Lua tabloları Lisp'daki listelerle karşılaştırılsa daha iyi olur.
Jakob

Sanırım JavaScript'te, "her şey bir nesnedir" - diziler dahil - ama her şey bir dizi değildir. Lua'da her şey bir masadır.
Dean Harding

3

Her üst düzey veri türü için özel bir sözdizimine sahip olmanız gerekmez . Örneğin, set([1, 2, 3])yerine (Python 2.x yaptığı gibi) tolere edilebilir {1, 2, 3}.

Önemli olan sahip olmaktır bazı üst düzey bir veri yapısını oluşturmak için uygun bir yol. Kaçınılması gereken şey şuna benzer bir koddur:

s = set()
s.add(1)
s.add(2)
s.add(3)

ki ben kullandığınızda beni çok rahatsız ediyor std::vector, std::setve std::mapC ++. Neyse ki, yeni standart olacak std::initializer_list.


3

Benim düşünceme göre, şaşırtıcı bir şekilde, en azından dikkatle yapılırsa şaşırtıcı bir şekilde kullanışlı olabilen inanılmaz derecede basit bir eklenti - yani en çok konuşulanlar, listeler, haritalar ve setler için iyi bilinenler.

  • Bir dile eklemek ucuz. Bu kıymetli karmaşıklık bütçesinin size çok maliyeti yok:
    • Dilbilgisi temel olarak someBracket {expr ','} someBracketveya someBracket {expr ':' expr ','} someBracketisteğe bağlı izleyen virgüller gibi şeyler istiyorsanız, bazı ölü basit ekstralar ile. Şamandıra değişmezleri kolaylıkla gramer içinde daha uzun olabilir.
    • Pek çok dilde, popüler hazır kelimelerin hiçbiri varolan sözdizimiyle çakışmaz (düşünebildiğim bir istisna, ifadeler, virgül operatörü ve olduğu gibi noktalı virgül içermeyen bir ayraç benzeri bloklar içeren bir dildir {1, 2})
    • Anlamsallık beş cümleden daha kısa bir sürede tanımlanabilir, enformel versiyon "yeni bir $ koleksiyonunu başlat, ardından ifadelerin argümanları olarak verilen ifadeler için .add/ .append/ bir .setItemkez çağır " şeklindedir.
  • Önceki üçüncü noktadan dolayı uygulanması da çok kolaydır.
  • İhtiyacınız olduğunda inanılmaz derecede kullanışlı bir hale gelir ve diğer öğelerin sözdizimini etkilemesi gerekmez (yani kullanmanız gerekmez), yani kullanmadığınızda “ödemezsiniz”.

3

Clojure bir lisp ama destekler

Lists: (x1 x2)
Vectors: [x1 x2]
Maps: {k1 v1 k2 v2}
Sets: #{x1 x2}

2

Dilin kendisinde ne kadar veri yapısı varsa, dili öğrenmek o kadar zor olacaktır. Kişisel bir tercih olabilir, ancak daha basit bir dili tercih etme eğilimindeyim ve daha sonra kütüphanelerden herhangi bir ekstra bulunabilir.

Belirli alanlar için tasarlanan diller bazen Matlab gibi dile yerleşik bazı veri yapılarına sahip olmaktan da faydalanabilir. Fakat çok fazla kişi sizi bunaltabilir.


2

Bir dilin gerçekten yararlı olması için, kutunun dışında belirli bir düzeyde görev yapması gerekir. Çünkü günlük pratik programlama, problemlerini belirli bir seviyede çözen araçlar gerektirir. Minimalizm kompakt ve havalı görünür, ancak büyük ama tekrarlanan problemleri çözmek için kullanmaya başlamak istediğinizde, üzerine inşa edebileceğiniz bir soyutlama seviyesine ihtiyacınız vardır.

Bu nedenle, programlama dillerinin, dilin tasarlandığı görevler için sözdiziminde en sık kullanılan veri yapılarını desteklemesi gerektiğini düşünüyorum.


2

Genel olarak listeler, kümeler vb. İçin hazır bilgi öğelerine sahip olmak uygun olur. Ama bazen, Python listesi veya Javascript dizisinin asıl uygulaması hakkında hiçbir şey bilmediğim için beni rahatsız ediyor. Emin olabileceğim tek şey belirli bir arayüzü ortaya çıkarmalarıdır.

Kendi dil yapılarını kütüphaneler olarak ne kadar iyi yazabileceğini ve bunları kullanmanın ne kadar kullanışlı olduğunu bir dil ifadesinin bir ölçütü olarak alıyorum.

Örneğin, Scala, farklı uygulama ve performans garantileriyle çeşitli koleksiyonlar sunar. Hepsi Scala'da uygulanmaktadır ve bunları kullanmak için kullanılan sözdizimi, yerleşik olmalarına ve çalışma zamanı desteğine sahip olmalarına kıyasla sadece biraz daha karmaşıktır.

Çalışma zamanının kendisinden, en azından yönetilen bir dilde gerçekten desteğe ihtiyaç duyan tek temel yapı dizidir: belleği yönetmezseniz, bir sürü bitişik bayt almak için zor zamanlar geçirirsiniz. Diğer her yapı dizilerden ve işaretçilerden (veya referanslardan) oluşabilir.


1

APL (ve ilgili modern değişkenler, A +, J ve K) birinci sınıf veri yapıları olarak skaler, vektör ve matrislere sahiptir.

Evet, dizide yalnızca değişkenler olarak kullanımdan kaldırılabilirler. Fakat aynı zamanda karmaşık bildirimlerden bağımsızlar ve ayrı bir kütüphaneden gelmiyorlar, dilin birinci sınıf bir parçası olan karmaşık veri yapıları gibi hissediyorlar.


APL ayrıca iç içe geçmiş dizilere sahiptir ve dizilerin hepsi çok güçlü veri yapıları yapan homojen veri türüne sahip olmak zorunda değildir.
RFlack

1

Dil tasarımı açısından bakıldığında, çekirdek dilde veri yapıları için belirli bir sözdizimine sahip olma hakkındaki görüşleriniz nelerdir? Bu iyi bir fikir midir ve dilin (vb.) Amacı bunun bir seçimde ne kadar iyi olabileceğini değiştirir mi?

Liste hazırlayıcıları ve harita hazırlayıcıları ve uygun bir kapama sözdizimi, üst düzey dillerin temel özellikleridir.

Bu Java kodu arasındaki fark:

Thing t = new Thing();
t.setFoo(3);
t.setBar(6.3);
t.setBaz(true);

ve bu Groovy kodu:

t = new Thing(foo: 3, bar: 6.3, baz: true)

muazzam. 40.000 satırlık bir program ve 10.000 satırlık bir program arasındaki fark. Sözdizimi önemlidir.


C # 'da yapabilecekleriniz: var t = new Thing(foo: 3, bar: 6.3, baz: true);- sadece 4 karakter daha.
İş

aslında aynı sayı; Groovy kodu 'def t = ...' okumalı
kevin cline

1

Elbette programlama dilinin uygulamasına bağlı, ancak daha yüksek seviyeli diller için ortak veri yapılarıyla çalışmak mümkün olduğu kadar uygun olmalıdır. Örnekler için Wikipedia'daki soyut veri türlerinin listesine bir göz atın . En yaygın olarak aşağıdaki temel prensipleri buldum (ancak diğer fikirleri de duymak istiyorum):

  • sıralı diziler (1 boyutlu): dizi, sıra, yığın, listeler ...
  • sıralı çok boyutlu yapılar : tablo, vektör, matris ..
  • haritalar : hashmap, sözlük, set, çoklu harita ... (1 boyutlu)
  • çok boyutlu haritalar : fonksiyonlar, harita haritaları ...
  • grafik türleri : ağaçlar, yönlendirilmiş grafikler ...

Herhangi bir yapıyı başka bir yapıyla taklit edebilirsiniz - bu yalnızca programlama dilinin izin verdiği ölçüde kolay ve net olmasına bağlıdır. Örneğin:

  • sıra ve yığının dizilerle veya listelerle taklit edilmesi kolaydır, ikincisi push, pop, shift vb. gibi işlemler sağlar.
  • sıralı diziler, sayısal tuşları olan haritalarla öykünebilir
  • kümeler, değerleri bir boole ile eşleyen haritalar tarafından taklit edilebilir
  • Grafik türlerinin çoğu iç içe geçmiş diziler veya haritalar tarafından taklit edilebilir
  • tanımlarını kolayca değiştirebiliyorsanız, haritaları taklit etmek için işlevler kullanılabilir

Çoğu dil, sıralı diziler için en az bir tür, biri 1 boyutlu haritalar ve diğeri çok işlevli haritalar için işlevlerle sınırlıdır. Şahsen, sık sık setleri özlüyorum ve Perl, PHP, JavaScript, Lua ... gibi dillerde çok boyutlu yapıları ıskaladım çünkü bunları taklit etmek yeterince uygun değil.


1

Özel sözdizimi alan çok fazla ayrıcalıklı veri türüne sahip olmanın kötü bir fikir olduğunu düşünüyorum. Bu, dil sözdizimini gereksiz yere zorlaştırır, kod okumayı zorlaştırır, yeni başlayanların öğrenmesini zorlaştırır ve dil için araçlar geliştirmeyi zorlaştırır.

Az sayıda çok yaygın veri yapısı türü için bir istisna yapmak sorun değil. Muhtemelen en fazla izin veririm:

  • Sabit uzunlukta diziler
  • Setler
  • Hashmaps
  • Diziler / listeler
  • Kayıtlar / yapılar / sınıflar

Bundan daha sofistike olan herhangi bir şey, dilin özel veri türleri için normal sözdizimini kullanarak işlemek için kütüphanelere bırakılmalıdır.

Özellikle, Kırmızı / Siyah ağaçlar, Öncelik Kuyrukları vb. Gibi şeylerin pek çok olası uygulama seçeneği vardır; bu nedenle, belirli bir uygulamayı ana dile yerleştirmek akıllıca değildir. İnsanların durumları için en uygun uygulamayı seçmelerine izin vermek daha iyidir. Bir dil tasarımcısının seçimimi sınırlandırmasını istemeyebileceğim uygulama seçeneklerine örnekler:

  • Değişken mi, değişmez mi?
  • Boş değerlere izin verir veya vermez mi?
  • Senkronize mi değil mi?
  • Kalıcı depolama ile destekleniyor mu, desteklenmiyor mu?
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.