Haruskah struktur data diintegrasikan ke dalam bahasa (seperti dalam Python) atau disediakan di perpustakaan standar (seperti di Jawa)?


21

Dalam Python, dan kemungkinan besar banyak bahasa pemrograman lain, struktur data umum dapat ditemukan sebagai bagian terintegrasi dari bahasa inti dengan sintaksis khusus mereka sendiri. Jika kita mengesampingkan sintaks daftar terintegrasi LISP, saya tidak bisa memikirkan bahasa lain yang saya tahu yang menyediakan semacam struktur data di atas array sebagai bagian terintegrasi dari sintaks mereka, meskipun semuanya (tapi C, saya kira) tampaknya menyediakannya di perpustakaan standar.

Dari perspektif desain bahasa, apa pendapat Anda tentang memiliki sintaksis khusus untuk struktur data dalam bahasa inti? Apakah ini ide yang bagus, dan apakah tujuan bahasa (dll.) Mengubah seberapa bagus pilihan ini?

Sunting: Saya minta maaf atas (tampaknya) menyebabkan beberapa kebingungan tentang struktur data yang saya maksud. Saya berbicara tentang yang dasar dan yang umum digunakan, tetapi masih bukan yang paling dasar. Ini tidak termasuk pohon (terlalu kompleks, tidak umum), tumpukan (terlalu jarang digunakan), array (terlalu sederhana) tetapi termasuk misalnya set, daftar, dan hashmaps.


1
Apakah kita mengecualikan objek dan hashmap?
Orbling

3
@Anto: Banyak bahasa memiliki hashmaps dalam bentuk array asosiatif, Perl, PHP, JS (secara teknis objek di sini), dll.
Orbling

1
Mungkin Anda bisa lebih spesifik tentang struktur data yang Anda pikirkan, selain dari array, daftar, hashmaps / array asosiatif?
FrustratedWithFormsDesigner

1
Sertakan peta hash, daftar, dan apa pun yang lebih canggih sebagai "struktur data kompleks" dan buang array sebagai terlalu sederhana.
Anto

1
Saya pikir judul yang lebih masuk akal akan seperti: "Struktur data apa yang harus dimasukkan dalam bahasa, dan apa yang ada di perpustakaan?" Namun, jawaban yang bermakna sangat tergantung pada bahasa: semakin bersih perpustakaan diintegrasikan ke dalam bahasa, semakin masuk akal untuk memindahkan struktur ke perpustakaan.
Jerry Coffin

Jawaban:


13

Itu tergantung untuk apa bahasa itu.

Beberapa contoh (agak dicuri dari jawaban lain):

  • Perl memiliki sintaks khusus untuk hashtable, array, string. Perl sering digunakan untuk skrip, ini berguna untuk skrip.
  • Matlab memiliki sintaks khusus untuk daftar, matriks, struktur. Matlab adalah untuk melakukan matrik dan matematika vektorial untuk teknik.
  • String dan array dukungan Java / .NET. Ini adalah bahasa tujuan umum di mana array dan string sering digunakan (semakin sedikit dengan menggunakan kelas koleksi baru)
  • C / C ++ mendukung array. Ini adalah bahasa yang tidak menyembunyikan perangkat keras dari Anda. String didukung sebagian (tidak ada rangkaian, gunakan strcpy, dll.)

Saya pikir itu tergantung apa tujuan / semangat / audiens bahasa Anda; seberapa abstrak dan seberapa jauh dari perangkat keras yang Anda inginkan. Secara umum bahasa yang mendukung daftar sebagai primitif memungkinkan Anda untuk membuat daftar yang sangat panjang. Sementara level rendah seperti C / C ++ tidak akan pernah memiliki ini, karena itu bukan tujuan, semangat bahasa-bahasa tersebut.

Bagi saya, pengumpulan sampah mengikuti logika yang sama: apakah audiens bahasa Anda peduli untuk mengetahui kapan dan apakah memori dialokasikan atau dibebaskan? Jika ya, malloc / gratis; jika tidak, maka pengumpulan sampah.


6
Ini adalah tempat yang buruk untuk menggunakan istilah "C / C ++", karena keberadaan tipe templat tingkat tinggi dalam C ++ adalah perbedaan utama antara kedua bahasa.
dan04

Pengumpulan sampah dapat dilakukan dengan cara deterministik, Anda hanya perlu jenis linier (atau pengganti orang miskin mereka: RAII).
pyon

@ EduardoLeón, meskipun Anda dapat memanggil pengumpulan sampah pada titik deterministik, saya tidak berpikir berapa lama itu akan berjalan adalah deterministik (untuk alasan yang sama mallocdan newnon-deterministik dalam C / C ++).
earlNameless

@earlNameless: Ini adalah deterministik relatif terhadap penggunaan sumber daya: tipe linier (atau tipe keunikan, yang serupa) menjadikannya tipe kesalahan (dan, dengan demikian, kesalahan kompilasi) untuk tidak membebaskan sumber daya (modulo kemungkinan, tidak ditangkap oleh tipe tersebut sistem, dari penghentian program yang tidak normal), atau untuk menggunakannya setelah dibuang.
pyon

5

Perl memiliki hashmaps dan PL / SQL mendukung catatan, dan saya memiliki memori yang sangat berkabut dari matlab memiliki sintaks untuk mendukung vektor dan matriks dari semua dimensi yang berbeda (meskipun saya bisa salah tentang yang ini dan itu bisa menjadi argumen bahwa ini adalah tipe data bukan data struktur ) ... Saya akan mengatakan bahwa memiliki beberapa dukungan asli untuk struktur yang sangat umum baik untuk dimiliki. Biasanya tampaknya bahwa array dan hashmaps / array asosiatif adalah struktur yang didukung secara umum paling umum, dan mereka mungkin yang paling umum digunakan juga.

Jangan lupa bahwa jika Anda menambahkan dukungan sintaksis asli untuk struktur lain seperti pohon-biner, struktur itu juga telah diimplementasikan oleh alat pendukung bahasa (compiler / runtime / etc). Berapa banyak strucutres yang Anda inginkan untuk membangun dukungan?

Anda harus membuat notasi baru untuk struktur yang secara umum kurang didukung ... Keep It Simple !.


Tidak perlu menciptakan sintaksis harfiah untuk misal pohon - pohon lebih jarang, bahkan tidak ada di stdlib dari banyak bahasa! Dengan argumen yang sama, orang dapat menentang dimasukkannya operator karena "Anda harus menemukan notasi baru untuk operasi yang jarang digunakan".

@delnan: Cara saya memahaminya adalah dari perspektif merancang bahasa baru dan bertanya-tanya apakah struktur data selain array harus didukung secara native oleh (mungkin) sintaks baru, atau jika mereka harus didukung dengan menyertakan perpustakaan.
FrustratedWithFormsDesigner

Nah, kalimat pertama secara eksplisit berbicara tentang "struktur data umum", jadi saya berasumsi OP tidak cukup gila untuk mencoba menambahkan sintaks khusus untuk setiap struktur data yang tidak jelas yang pernah ditemukan.

@delnan: ... dan kemudian OP melanjutkan untuk mengecualikan daftar dan array LISP (secara umum) "... mengesampingkan sintaksis daftar terintegrasi LISP, saya tidak bisa memikirkan bahasa lain yang saya tahu yang menyediakan semacam struktur data di atas array sebagai bagian terintegrasi dari sintaks mereka "... jadi saya pikir mereka merenungkan struktur data lebih eksotis daripada array / daftar ...
FrustratedWithFormsDesigner

Ya (saya menafsirkan "di atas array" sebagai "struktur data umum lainnya"), tetapi tidak ada dalam pertanyaan yang mengisyaratkan "mari kita membuat literal untuk setiap struktur data tunggal yang kita miliki". Tidak apa-apa untuk menyatakan bahwa ini harus dibatasi pada apa yang masuk akal, tetapi saya tidak berpikir kita dapat mengatakan "ide buruk" hanya karena asumsi ini .

5

Contoh favorit saya di sini adalah Lua . Lua hanya memiliki satu tipe data built-in, " tabel ", tetapi fleksibilitas dan kecepatannya berarti Anda benar-benar menggunakannya di tempat array reguler, daftar tertaut, antrian, peta dan mereka bahkan menjadi dasar untuk fitur berorientasi objek Lua (kelas yaitu).

Lua adalah bahasa yang sangat sederhana, tetapi fleksibilitas struktur data tabel membuatnya cukup kuat juga.


2
Objek JavaScript benar-benar dengan cara yang sama - Array hanya benar-benar objek dengan sifat numerik dan panjang, misalnya.
Tikhon Jelvis

1
Tabel Lua berbeda dengan Objek JavaScript: Di JavaScript {}tidak [], di Lua Anda memiliki {}keduanya. Tabel Lua lebih baik dibandingkan dengan daftar di Lisp.
Jakob

Saya kira dalam JavaScript, "semuanya adalah objek" - termasuk array - tetapi tidak semuanya array. Di Lua, semuanya adalah sebuah meja.
Dean Harding

3

Anda tidak harus memiliki sintaks khusus untuk setiap tipe data tingkat tinggi. Sebagai contoh, itu lumayan untuk memiliki set([1, 2, 3])(sebagai Python 2.x lakukan) alih-alih {1, 2, 3}.

Yang penting adalah memiliki beberapa cara mudah untuk membangun struktur data tingkat tinggi. Yang ingin Anda hindari adalah kode seperti:

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

yang mengganggu saya sangat ketika saya menggunakan std::vector, std::setdan std::mapdi C ++. Untungnya, standar baru akan ada std::initializer_list.


3

Menurut pendapat saya, ini adalah tambahan yang sangat sederhana yang bisa berguna secara mengejutkan sering, setidaknya jika dilakukan dengan hati-hati - yaitu paling banyak untuk tupel, daftar, peta dan set karena mereka memiliki literal yang dikenal dengan baik.

  • Lebih murah menambahkan ke bahasa. Anda tidak perlu mengeluarkan banyak biaya dari kompleksitas kompleksitas yang berharga:
    • tata bahasanya pada dasarnya adalah someBracket {expr ','} someBracketatau someBracket {expr ':' expr ','} someBracket, dengan beberapa tambahan sederhana mati jika Anda menginginkan hal-hal seperti koma tambahan opsional. The literal mengapung dengan mudah dapat lagi dalam tata bahasa.
    • Dalam banyak bahasa, tidak ada satu pun dari literal populer yang berbenturan dengan sintaksis yang ada (pengecualian yang dapat saya pikirkan adalah bahasa dengan blok seperti kurung sebagai ekspresi, operator koma dan tanpa titik koma, seperti pada {1, 2})
    • Semantik dapat didefinisikan dalam kurang dari lima kalimat, versi informal adalah "Instantiate $ collection baru, lalu panggil .add/ .append/ .setItemsatu kali per ekspresi yang diberikan dengan ekspresi (itu) sebagai argumen".
  • Karena poin ketiga sebelumnya, itu juga sangat mudah diimplementasikan.
  • Ini sangat berguna ketika Anda membutuhkannya, dan tidak (perlu) memengaruhi sintaksis elemen lain, yaitu Anda tidak "membayar" untuk itu ketika Anda tidak menggunakannya.

3

Clojure adalah orang yang lemah tetapi mendukung

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

2

Semakin banyak struktur data yang Anda miliki dalam bahasa itu sendiri semakin sulit bahasa yang akan dipelajari. Ini mungkin preferensi pribadi tetapi saya cenderung lebih suka bahasa yang lebih sederhana dan kemudian tambahan apa pun dapat disediakan oleh perpustakaan.

Bahasa yang dirancang untuk bidang tertentu terkadang dapat mengambil manfaat dari memiliki struktur data tertentu yang terintegrasi ke bahasa seperti Matlab. Tetapi terlalu banyak bisa membuat Anda kewalahan.


2

Agar suatu bahasa benar-benar bermanfaat, ia harus melakukan beberapa tugas di luar kotak. Karena pemrograman praktis sehari-hari membutuhkan alat yang menyelesaikan masalah mereka pada tingkat generik. Minimalisme terlihat kompak dan keren, tetapi ketika Anda ingin mulai menggunakan untuk menyelesaikan masalah besar tapi berulang, Anda membutuhkan tingkat abstraksi yang dapat Anda gunakan.

Jadi saya pikir bahasa pemrograman harus mengirimkan dukungan untuk struktur data yang paling umum digunakan dalam sintaks untuk tugas-tugas yang dirancang untuk bahasa tersebut.


2

Secara umum saya merasa nyaman memiliki literal untuk daftar, set dan sebagainya. Tapi kadang-kadang mengganggu saya bahwa saya tidak tahu apa-apa tentang implementasi aktual - katakanlah - daftar Python atau array Javascript. Satu-satunya hal yang saya bisa pastikan adalah bahwa mereka mengekspos antarmuka yang diberikan.

Saya menganggap sebagai tolok ukur dari ekspresi bahasa seberapa baik ia dapat menulis struktur datanya sendiri sebagai perpustakaan, dan seberapa nyaman menggunakannya.

Sebagai contoh, Scala menyediakan berbagai koleksi dengan implementasi yang berbeda dan jaminan kinerja. Semuanya diimplementasikan dalam Scala itu sendiri, dan sintaks untuk menggunakannya hanya sedikit lebih kompleks daripada jika mereka dibangun dan memiliki dukungan runtime.

Satu-satunya struktur dasar yang benar-benar membutuhkan dukungan dari runtime itu sendiri, setidaknya dalam bahasa yang dikelola, adalah array: jika Anda tidak mengelola memori, Anda akan kesulitan mendapatkan banyak byte yang berdekatan. Setiap struktur lain dapat dibangun dari array dan pointer (atau referensi).


1

APL (dan varian modern terkait, A +, J dan K) memiliki skalar, vektor, dan matriks sebagai struktur data kelas satu.

Ya, mereka dapat usang hanya sebagai varian pada array. Tetapi mereka juga bebas dari deklarasi kompleks dan tidak berasal dari perpustakaan yang terpisah, mereka merasa seperti struktur data kompleks yang merupakan bagian kelas bahasa.


APL juga memiliki array bersarang, dan array tidak harus memiliki tipe data yang homogen, yang semuanya membuat struktur data yang sangat kuat.
RFlack

1

Dari perspektif desain bahasa, apa pendapat Anda tentang memiliki sintaksis khusus untuk struktur data dalam bahasa inti? Apakah ini ide yang bagus, dan apakah tujuan bahasa (dll.) Mengubah seberapa bagus pilihan ini?

Daftar dan petakan peta dan sintaksis penutupan yang mudah digunakan adalah fitur penting dari bahasa tingkat tinggi.

Perbedaan antara kode Java ini:

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

dan kode Groovy ini:

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

sangat besar. Ini perbedaan antara program baris 40.000 dan program 10.000 baris. Masalah sintaksis.


Dalam C # satu dapat melakukan: var t = new Thing(foo: 3, bar: 6.3, baz: true);- hanya 4 karakter lagi.
Pekerjaan

sebenarnya nomor yang sama; kode Groovy harus dibaca 'def t = ...'
kevin cline

1

Tentu itu tergantung pada aplikasi bahasa pemrograman, tetapi untuk bahasa level yang lebih tinggi harus senyaman mungkin untuk bekerja dengan struktur data umum apa pun. Lihat daftar tipe data abstrak di Wikipedia untuk contohnya. Saya menemukan prinsip-prinsip dasar berikut yang paling umum (tetapi saya juga ingin mendengar pendapat lain):

  • urutan berurutan (1-dimensi): array, antrian, tumpukan, daftar ...
  • memesan struktur multi-dimensi : tabel, vektor, matrik ..
  • peta : hashmap, kamus, set, multimap ... (1-dimensi)
  • peta multi dimensi : fungsi, peta peta ...
  • jenis grafik : pohon, grafik terarah ...

Anda dapat meniru struktur apa pun dengan struktur lain - itu hanya tergantung pada seberapa mudah dan jelas bahasa pemrograman memungkinkannya. Contohnya:

  • antrian dan tumpukan mudah ditiru dengan array atau daftar, yang terakhir menyediakan operasi seperti push, pop, shift dll.
  • urutan yang dipesan dapat ditiru dengan peta yang memiliki tombol angka
  • set dapat ditiru oleh peta yang memetakan nilai ke boolean
  • kebanyakan tipe grafik dapat ditiru dengan urutan atau peta bersarang
  • fungsi dapat digunakan untuk meniru peta jika Anda dapat dengan mudah mengubah definisi mereka

Sebagian besar bahasa menyediakan setidaknya satu jenis untuk urutan yang diurutkan, satu untuk peta 1 dimensi, dan satu untuk peta multi dimensi, terbatas pada fungsi. Secara pribadi, saya sering melewatkan set dan memesan struktur multi-dimensi dalam bahasa seperti Perl, PHP, JavaScript, Lua ... karena meniru mereka tidak cukup nyaman.


1

Saya pikir itu ide buruk untuk memiliki terlalu banyak tipe data istimewa yang mendapatkan sintaks khusus. Ini mempersulit sintaksis bahasa yang tidak perlu, membuat kode lebih sulit untuk dibaca, mempersulit pemula untuk belajar dan membuatnya lebih sulit untuk mengembangkan alat untuk bahasa.

Tidak apa-apa untuk membuat pengecualian untuk sejumlah kecil tipe struktur data yang sangat umum. Saya mungkin akan mengizinkan maksimum:

  • Array panjang tetap
  • Set
  • Hashmaps
  • Urutan / daftar
  • Rekaman / struct / kelas

Apa pun yang lebih canggih dari itu mungkin harus diserahkan ke perpustakaan untuk ditangani, menggunakan sintaksis normal bahasa untuk tipe data khusus.

Secara khusus, hal-hal seperti pohon Merah / Hitam, Antrian Prioritas dll. Memiliki cukup banyak opsi implementasi yang mungkin, jadi tidak bijaksana untuk memanggang implementasi tertentu ke dalam bahasa inti. Lebih baik membiarkan orang memilih implementasi yang paling tepat untuk situasi mereka. Contoh pilihan implementasi yang saya mungkin tidak ingin seorang perancang bahasa membatasi pilihan saya pada:

  • Bisa berubah atau tidak berubah?
  • Mengizinkan nol atau tidak?
  • Disinkronkan atau tidak?
  • Didukung oleh penyimpanan yang gigih atau tidak?
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.