Чи слід інтегрувати структури даних у мову (як у Python) або надаватись у стандартній бібліотеці (як у Java)?


21

У Python та, швидше за все, у багатьох інших мовах програмування загальні структури даних можна знайти як інтегровану частину основної мови з власним виділеним синтаксисом. Якщо відкласти синтаксис інтегрованого списку LISP убік, я не можу уявити жодних інших мов, які я знаю, які забезпечують якусь структуру даних над масивом як інтегровану частину їх синтаксису, хоча всі вони (але C, я думаю) здається, надають їх у стандартній бібліотеці.

З точки зору дизайну мови, які ваші думки щодо того, щоб мати конкретний синтаксис для структур даних в основній мові? Це гарна ідея, і чи змінюється мета мови (тощо), наскільки хорошим це може бути вибір?

Редагувати: Вибачте, що (мабуть) спричинило певну плутанину щодо того, які структури даних я маю на увазі. Я говорю про основні та загальновживані, але все ж не найосновніші. Це виключає дерева (занадто складні, нечасті), стеки (занадто рідко використовуються), масиви (занадто прості), але включає, наприклад, набори, списки та хеш-карти.


1
Чи виключаємо ми об’єкт та хешмап?
Орлінг

3
@Anto: Добре багато мов мають хешмапи у вигляді асоціативних масивів, Perl, PHP, JS (тут технічно об'єкт) тощо.
Orbling

1
Можливо, ви могли б бути більш конкретними щодо того, про які структури даних ви думаєте, окрім масивів, списків, хешмапів / асоціативних масивів?
FrustratedWithFormsDesigner

1
Додайте хеш-карти, списки та щось більш розширене як "складні структури даних" та викидайте масиви як занадто прості.
Анто

1
Думаю, більш розумною назвою було б щось на кшталт: "Які структури даних повинні бути включені в мову, а які в бібліотеку?" Змістовна відповідь значною мірою залежить від мови: чим більш чітко інтегрована бібліотека в мову, тим більш розумним є переміщення структур у бібліотеку.
Джері Коффін

Відповіді:


13

Це залежить, для чого мова.

Деякі приклади (дещо вкрадені з інших відповідей):

  • Perl має спеціальний синтаксис для хештелів, масивів, рядків. Perl часто використовується для сценаріїв, вони корисні для сценаріїв.
  • Matlab має спеціальний синтаксис для списків, матриць, структур. Matlab призначений для виконання матричної та векторіальної математики для інженерії.
  • Підтримка Java / .NET підтримує рядок і масиви. Це мови загального призначення, де часто використовуються масиви та рядки (все менше і менше з використанням нових класів колекції)
  • C / C ++ масиви підтримки. Це мови, які не приховують від вас обладнання. Рядки підтримуються частково (без конкатенації, використання strcpy тощо)

Я думаю, це залежить від того, яка мета / дух / аудиторія вашої мови; наскільки абстрактно і наскільки далеко ви хочете, щоб це було. Як правило, мови, які підтримують списки як примітиви, дозволяють створювати нескінченно довгі списки. Хоча на низькому рівні, таких як C / C ++, їх ніколи не було, оскільки це не мета, дух цих мов.

Для мене збирання сміття дотримується тієї самої логіки: чи цікавить аудиторія вашої мови про те, коли точно знати, коли і чи виділяється чи звільняється пам'ять? Якщо так, malloc / безкоштовно; якщо ні, то збирання сміття.


6
Це погане місце для використання терміна "C / C ++", оскільки наявність типів шаблонів високого рівня в C ++ є головною різницею між двома мовами.
dan04

Збір сміття може здійснюватися детерміновано, просто потрібні лінійні типи (або заміна їх бідної людини: RAII).
піон

@ EduardoLeón, хоча ви можете назвати збирання сміття в детермінованій точці, я не думаю, як довго він буде працювати детерміновано (з тієї ж причини, що mallocі newне детерміновані в C / C ++).
EarlNameless

@earlNameless: Це детерміновано відносно використання ресурсу: лінійні типи (або унікальні типи, подібні) роблять його помилкою типу (і, таким чином, помилкою компіляції), щоб не звільняти ресурси (модуль можливості, не захоплений типом системи, будь-якого ненормального припинення програми) або використовувати їх після їх утилізації.
піон

5

У Perl є хешмапи та PL / SQL підтримує записи, і у мене дуже туманні спогади про matlab, який має синтаксис для підтримки векторів і матриць усіх різних вимірів (хоча я можу помилитися з цим, і можна стверджувати, що це типи даних, а не дані споруди ) ... Я б сказав, що приємно мати певну підтримку дуже поширених структур. Зазвичай здається, що масиви та хешмапи / асоціативні масиви - це найпоширеніші споконвічно підтримувані структури, і вони, мабуть, також найбільш часто використовуються.

Не забувайте, що якщо ви додаєте підтримку нативного синтаксису для інших структур, таких як бінарні дерева, ці структури також будуть реалізовані за допомогою допоміжних інструментів мови (компілятор / час виконання / тощо). На скільки структур ви хочете створити підтримку?

Вам доведеться придумувати нове позначення для менш поширених споконвічно підтримуваних структур ... Тримайте це просто !.


Немає необхідності вигадувати буквальний синтаксис, наприклад, дерева - вони рідше, їх навіть немає в багатьох мовах! З цього ж аргументу можна протидіяти включенню операторів, оскільки "вам доведеться вигадувати нове позначення для менш поширених операцій".

@delnan: Я зрозумів, що це було з точки зору проектування нової мови і цікавився, чи слід структуру даних, крім масивів, підтримувати (можливо) новим синтаксисом, або якщо їх слід підтримувати, включаючи бібліотеку.
FrustratedWithFormsDesigner

Ну, перше речення прямо говорить про "загальні структури даних", тому я припускаю, що ОП недостатньо божевільне, щоб спробувати додати спеціальний синтаксис для кожної незрозумілої структури даних, коли-небудь винайденої.

@delnan: ... а потім ОП продовжує виключати списки та масиви LISP (загалом) "... відклади в сторону синтаксис інтегрованого списку LISP, я не можу придумати жодних інших мов, які я знаю, які забезпечують певний тип структура даних над масивом як складова частина їхнього синтаксису "... тому я думав, що вони обдумують структури даних більш екзотичні, ніж масиви / списки ...
FrustratedWithFormsDesigner

Так (я інтерпретував "над масивами" як "інші загальні структури даних"), але нічого в цьому питанні не натякає на "давайте зробимо літерали для кожної окремої структури даних". Чудово констатувати, що це повинно обмежуватися лише розумним, але я не думаю, що ми можемо сказати «погану ідею» саме через це припущення .

5

Мій улюблений приклад тут - Луа . Lua має лише один вбудований тип даних, " таблицю ", але її гнучкість та швидкість означають, що ви фактично використовуєте їх замість регулярних масивів, зв'язаних списків, черг, карт і вони навіть є основою для об'єктно-орієнтованих функцій Lua (тобто заняття).

Lua - така дивовижно проста мова, але гнучкість структури даних таблиці також робить її досить потужною.


2
Об'єкти JavaScript справді однакові - Масиви - це просто дійсні об'єкти, що мають чисельні властивості та довжину, наприклад.
Тихон Єлвіс

1
Таблиці Lua відрізняються від JavaScript Об'єкти: У JavaScript {}немає [], у Lua у вас є {}обидва. Таблиці Lua краще порівняти зі списками в Lisp.
Якоб

Я думаю, що в JavaScript "все є об'єктом", включаючи масиви - але не все це масив. У Луа все - це стіл.
Дін Хардінг

3

Не потрібно мати спеціальний синтаксис для кожного типу даних високого рівня. Наприклад, допустимо мати set([1, 2, 3])(як Python 2.x) замість {1, 2, 3}.

Важливо, щоб мати певний зручний спосіб побудови структури даних високого рівня. Чого ви хочете уникати, це такий код:

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

яка дратує мене сильно , коли я використовую std::vector, std::setі std::mapв C ++. На щастя, новий стандарт буде std::initializer_list.


3

На мою думку, це надзвичайно просте доповнення, яке може стати в нагоді напрочуд часто, принаймні, якщо робити це обережно - тобто щонайбільше для кортежів, списків, карт та наборів, оскільки вони мають добре визнані літерали.

  • Додавати мову дешево. Це не коштує вам дорогого з дорогоцінного бюджету складності:
    • граматика - це, в основному, someBracket {expr ','} someBracketабо someBracket {expr ':' expr ','} someBracketз деякими мертвими простими додатками, якщо ви хочете такі речі, як необов'язкові кінцеві коми. У поплавок літерали можуть легко бути більше в граматиці.
    • У багатьох мовах жодна з популярних літералів не стикається з існуючим синтаксисом (виняток, який я можу придумати, - це мова з блоками, схожими на дужки, як вирази, оператор з комами та без крапки з комою, як у {1, 2})
    • Семантику можна визначити менш ніж за п’ять речень, неформальна версія якої - "Миттєво запрограмуйте нову колекцію $, а потім зателефонуйте .add/ .append/ .setItemодин раз за заданими виразами з тим (тими) виразами, як аргументи".
  • Завдяки попередньому третьому моменту це також дуже просто здійснити.
  • Це надзвичайно зручно, коли вам це потрібно, і не впливає на синтаксис інших елементів, тобто ви не «платите» за нього, коли не використовуєте його.

3

Clojure - це супіна, але підтримує

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

2

Чим більше структур даних у вас у самій мові, тим складніше мову буде вивчити. Це може бути особистим уподобанням, але я, як правило, віддаю перевагу більш простій мові, і тоді будь-які додаткові послуги можуть надаватися бібліотеками.

Мови, розроблені для конкретних полів, іноді можуть мати користь від того, щоб вбудовані певні структури даних до мови, наприклад Matlab. Але занадто багато може вас переповнити.


2

Щоб мова була справді корисною, вона повинна виконувати певний ступінь завдань поза рамками. Тому що для практичного щоденного програмування потрібні інструменти, які вирішують їх проблеми на якомусь загальному рівні. Мінімалізм виглядає компактно і круто, але коли ви хочете почати використовувати для вирішення великих, але повторних проблем, вам потрібен рівень абстракції, над яким ви можете будувати.

Тому я думаю, що мови програмування повинні підтримувати найбільш часто використовувані структури даних у синтаксисі для завдань, для яких призначена мова.


2

Взагалі мені здається, що для літератури зручно мати літерали для списків, наборів тощо. Але іноді мене клопочуть, що я нічого не знаю про фактичну реалізацію - скажімо, списку Python або масиву Javascript. Єдине, в чому я можу бути впевнений, це те, що вони відкривають даний інтерфейс.

Я вважаю орієнтиром мовної виразності те, наскільки добре вона може записувати власні структури даних як бібліотеки, і як зручно користуватися ними.

Наприклад, Scala пропонує різні колекції з різними гарантіями реалізації та виконання. Усі вони реалізовані в самому Scala, і синтаксис їх використання є лише дещо складнішим, ніж якби вони були вбудовані та мали підтримку виконання.

Єдина основна структура, яка дійсно потребує підтримки з боку самого виконання, хоча б керованою мовою, - це масив: якщо ви не керуєте пам'яттю, вам буде важко отримати купу суміжних байтів. Кожна інша структура може бути побудована з масивів і покажчиків (або посилань).


1

APL (і супутні сучасні варіанти, A +, J і K) мають скалярні, векторні та матричні як першокласні структури даних.

Так, вони можуть бути застаріли як просто варіанти у масиві. Але вони також не містять складних декларацій і не походять з окремої бібліотеки, вони відчувають себе складними структурами даних, які є першокласною частиною мови.


APL також має вкладені масиви, і масиви не повинні мати однорідний тип даних, що все робить для дуже потужних структур даних.
RFlack

1

З точки зору дизайну мови, які ваші думки щодо того, щоб мати конкретний синтаксис для структур даних в основній мові? Це гарна ідея, і чи змінюється мета мови (тощо), наскільки хорошим це може бути вибір?

Літеральні переліки та карти та зручний синтаксис закриття - важливі особливості мов високого рівня.

Різниця між цим кодом Java:

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

і цей код Groovy:

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

величезна. Різниця між програмою 40 000 ліній та 10 000 лінійною програмою. Синтаксис має значення.


У C # можна зробити: var t = new Thing(foo: 3, bar: 6.3, baz: true);- лише 4 символи більше.
Робота

це насправді однакове число; код Groovy повинен читати 'def t = ...'
kevin cline

1

Звичайно, це залежить від застосування мови програмування, але для мов вищого рівня слід якомога зручніше працювати з будь-якою загальною структурою даних. Перегляньте список абстрактних типів даних у Вікіпедії для прикладів. Я знайшов такі основні принципи, які є найпоширенішими (але я хотів би почути й інші думки):

  • упорядковані послідовності (1-мірна): масив, черга, стек, списки ...
  • упорядковані багатовимірні структури : таблиця, вектор, матриця ..
  • карти : хешмап, словник, набір, мультимапа ... (1-мірна)
  • багатовимірні карти : функції, карти карт ...
  • типи графіків : дерева, спрямовані графіки ...

Можна емулювати будь-яку структуру будь-якою іншою структурою - це залежить лише від того, наскільки це легко та зрозуміло мови програмування. Наприклад:

  • черга та стек легко емулюються масивами чи списками, останні забезпечують такі операції, як push, pop, shift тощо.
  • упорядковані послідовності можуть бути імітовані картами, що мають числові клавіші
  • набори можуть бути імітовані картами, які відображають значення в бульне значення
  • більшість типів графіків можна імітувати за допомогою послідовностей вкладки чи карт
  • Функції можна використовувати для емуляції карт, якщо ви можете легко змінити їх визначення

Більшість мов надають принаймні один тип для впорядкованих послідовностей, один для одновимірних карт і один для багатовимірних карт, обмежених функціями. Особисто мені часто не вистачає наборів і упорядкованих багатовимірних структур на таких мовах, як Perl, PHP, JavaScript, Lua ... тому що емуляція їх недостатньо зручна.


1

Я думаю, що погана ідея мати занадто багато привілейованих типів даних, які отримують спеціальний синтаксис. Це непотрібно ускладнює синтаксис мови, ускладнює читання коду, ускладнює навчання початківцям і ускладнює розробку інструментів для мови.

Добре робити виняток для невеликої кількості дуже поширених типів даних даних. Я, мабуть, дозволяю максимум:

  • Масиви фіксованої довжини
  • Набори
  • Хешмапи
  • Послідовності / списки
  • Записи / структури / заняття

Що-небудь більш складне, ніж це, мабуть, слід залишити бібліотекам для обробки, використовуючи звичайний синтаксис мови для спеціальних типів даних.

Зокрема, такі речі, як Червоні / Чорні дерева, Пріоритетні черги тощо, мають досить багато можливих варіантів реалізації, тому не розумно переносити певну реалізацію на основну мову. Краще дозволити людям вибрати найбільш відповідну реалізацію для своєї ситуації. Приклади варіантів реалізації, які, можливо, не хочу, щоб мовний дизайнер обмежував свій вибір на:

  • Змінні чи незмінні?
  • Дозволяє нулі чи ні?
  • Синхронізовано чи ні?
  • Підтримується стійким зберіганням чи ні?
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.