In Python und höchstwahrscheinlich in vielen anderen Programmiersprachen finden sich häufig verwendete Datenstrukturen als integraler Bestandteil der Kernsprache mit einer eigenen dedizierten Syntax. Wenn wir die integrierte Listensyntax von LISP beiseite lassen, kann ich mir keine andere Sprache vorstellen, die eine Art Datenstruktur über dem Array als integrierten Teil ihrer Syntax liefert, obwohl alle von ihnen (aber C, denke ich) scheinen sie in der Standardbibliothek bereitzustellen.
Was halten Sie aus Sicht des Sprachdesigns von einer bestimmten Syntax für Datenstrukturen in der Kernsprache? Ist es eine gute Idee und ändert der Zweck der Sprache (etc.), wie gut dies von einer Wahl sein könnte?
Edit: Es tut mir leid, dass ich (anscheinend) einige Unklarheiten darüber habe, welche Datenstrukturen ich meine. Ich spreche über die grundlegenden und häufig verwendeten, aber immer noch nicht die grundlegendsten. Dies schließt Bäume (zu komplex, ungewöhnlich), Stapel (zu selten verwendet) und Arrays (zu einfach) aus, umfasst jedoch z. B. Mengen, Listen und Hashmaps.
Antworten:
Es kommt darauf an, wofür die Sprache ist.
Einige Beispiele (etwas von anderen Antworten gestohlen):
Ich denke, es kommt darauf an, was der Zweck / Geist / das Publikum Ihrer Sprache ist. Wie abstrakt und wie weit von der Hardware entfernt soll sie sein? Im Allgemeinen können Sie mit den Sprachen, die Listen als Grundelemente unterstützen, unendlich lange Listen erstellen. Während Low-Level-Versionen wie C / C ++ diese niemals haben würden, ist dies nicht das Ziel, sondern der Geist dieser Sprachen.
Garbage Collection folgt für mich der gleichen Logik: Interessiert es die Zielgruppe Ihrer Sprache, genau zu wissen, wann und ob Speicher zugewiesen oder freigegeben wird? Wenn ja, malloc / free; Wenn nein, dann Müllabfuhr.
quelle
malloc
undnew
nicht deterministisch ist).Perl hat Hashmaps und PL / SQL unterstützt Datensätze, und ich habe sehr trübe Erinnerungen an Matlab mit Syntax zur Unterstützung von Vektoren und Matrizen in allen verschiedenen Dimensionen (obwohl ich mich in dieser Hinsicht irren und argumentieren könnte, dass dies Datentypen und keine Daten sind Strukturen ) ... Ich würde sagen, dass es nett ist, eine native Unterstützung für sehr häufige Strukturen zu haben. Normalerweise scheinen Arrays und Hashmaps / assoziative Arrays die gebräuchlichsten nativ unterstützten Strukturen zu sein, und sie werden wahrscheinlich auch am häufigsten verwendet.
Vergessen Sie nicht, dass, wenn Sie native Syntaxunterstützung für andere Strukturen wie Binärbäume hinzufügen, diese Strukturen auch von den unterstützenden Tools der Sprache (Compiler / Runtime / etc) implementiert wurden. Für wie viele Strukturen möchten Sie Unterstützung aufbauen?
Sie müssen eine neue Notation für die weniger gebräuchlich unterstützten Strukturen erfinden ... Keep It Simple !.
quelle
Mein Lieblingsbeispiel hier ist Lua . Lua hat nur einen integrierten Datentyp, die " Tabelle ". Aufgrund ihrer Flexibilität und Geschwindigkeit können Sie sie jedoch anstelle von regulären Arrays, verknüpften Listen, Warteschlangen und Karten verwenden. Sie sind sogar die Grundlage für die objektorientierten Funktionen von Lua (dh Klassen).
Lua ist eine unglaublich einfache Sprache, aber die Flexibilität der Tabellendatenstruktur macht sie auch sehr mächtig.
quelle
{}
ist dies nicht der[]
Fall, in Lua haben Sie{}
für beide. Lua-Tabellen lassen sich besser mit Listen in Lisp vergleichen.Sie müssen nicht für jeden Datentyp auf hoher Ebene eine dedizierte Syntax haben . Zum Beispiel ist es tolerierbar
set([1, 2, 3])
(wie es Python 2.x getan hat) statt{1, 2, 3}
.Das Wichtigste ist , hat einige bequeme Möglichkeit , eine High-Level - Datenstruktur zu konstruieren. Was Sie vermeiden möchten, ist Code wie:
das ärgert mich sehr , wenn ich verwende
std::vector
,std::set
undstd::map
in C ++. Zum Glück wird der neue Standard habenstd::initializer_list
.quelle
Meiner Meinung nach ist es eine erstaunlich einfache Ergänzung, die überraschend oft nützlich sein kann, zumindest wenn man vorsichtig vorgeht - dh höchstens für Tupel, Listen, Karten und Mengen, die anerkannte Literale haben.
someBracket {expr ','} someBracket
odersomeBracket {expr ':' expr ','} someBracket
mit ein paar toten einfachen Extras, wenn Sie Dinge wie optionale Kommas wollen. Die Float-Literale können in der Grammatik leicht länger sein.{1, 2}
)..add
/.append
/.setItem
einmal pro angegebenen Ausdrücke mit diesem (diesen) Ausdruck (s) als Argumente“.quelle
Clojure ist ein lisp aber unterstützt
quelle
Je mehr Datenstrukturen Sie in der Sprache selbst haben, desto schwieriger ist es, die Sprache zu lernen. Es mag eine persönliche Präferenz sein, aber ich bevorzuge eher eine einfachere Sprache, und dann können alle Extras von Bibliotheken bereitgestellt werden.
Sprachen, die für bestimmte Bereiche entwickelt wurden, können manchmal davon profitieren, dass bestimmte Datenstrukturen in die Sprache integriert sind, z. B. Matlab. Aber zu viele können dich überwältigen.
quelle
Damit eine Sprache wirklich nützlich ist, muss sie ein gewisses Maß an Aufgaben von der Stange übernehmen. Weil die praktische tägliche Programmierung Tools erfordert, die ihre Probleme auf einer allgemeinen Ebene lösen. Minimalismus sieht kompakt und cool aus, aber wenn Sie anfangen möchten, große, aber sich wiederholende Probleme zu lösen, benötigen Sie eine Abstraktionsebene, auf der Sie aufbauen können.
Daher denke ich, dass Programmiersprachen Unterstützung für die am häufigsten verwendeten Datenstrukturen in der Syntax für die Aufgaben liefern sollten, für die die Sprache entwickelt wurde.
quelle
Im Allgemeinen finde ich es praktisch, Literale für Listen, Mengen usw. zu haben. Aber manchmal nervt es mich, dass ich nichts über die tatsächliche Implementierung der Python-Liste oder des Javascript-Arrays weiß. Das Einzige, dessen ich mir sicher sein kann, ist, dass sie eine bestimmte Schnittstelle offen legen.
Ich nehme als Maßstab für die Ausdruckskraft einer Sprache, wie gut sie ihre eigenen Datenstrukturen als Bibliotheken schreiben kann und wie bequem sie zu verwenden ist.
Zum Beispiel bietet Scala verschiedene Kollektionen mit unterschiedlichen Implementierungs- und Leistungsgarantien an. Alle von ihnen sind in Scala selbst implementiert, und die Syntax für ihre Verwendung ist nur geringfügig komplexer als wenn sie eingebaut wären und Laufzeitunterstützung hätten.
Die einzige grundlegende Struktur, die wirklich Unterstützung von der Laufzeit selbst benötigt, zumindest in einer verwalteten Sprache, ist das Array: Wenn Sie den Speicher nicht verwalten, werden Sie Schwierigkeiten haben, eine Reihe benachbarter Bytes zu erhalten. Jede andere Struktur kann aus Arrays und Zeigern (oder Referenzen) aufgebaut werden.
quelle
APL (und verwandte moderne Varianten, A +, J und K) haben Skalar, Vektor und Matrix als erstklassige Datenstrukturen.
Ja, sie können als reine Array-Varianten verworfen werden. Sie sind aber auch frei von komplexen Deklarationen und stammen nicht aus einer separaten Bibliothek, sondern fühlen sich wie komplexe Datenstrukturen an, die ein erstklassiger Teil der Sprache sind.
quelle
Listen- und Map-Literale sowie eine komfortable Abschlusssyntax sind wesentliche Merkmale von Hochsprachen.
Der Unterschied zwischen diesem Java-Code:
und dieser Groovy Code:
ist enorm. Es ist der Unterschied zwischen einem 40.000-Zeilen-Programm und einem 10.000-Zeilen-Programm. Syntax ist wichtig.
quelle
var t = new Thing(foo: 3, bar: 6.3, baz: true);
- nur noch 4 Zeichen.Sicher, es hängt von der Anwendung der Programmiersprache ab, aber für höhere Sprachen sollte es so bequem wie möglich sein, mit jeder gängigen Datenstruktur zu arbeiten. Schauen Sie sich beispielsweise die Liste der abstrakten Datentypen in Wikipedia an. Ich fand die folgenden Grundprinzipien am gebräuchlichsten (aber ich möchte auch andere Meinungen hören):
Sie können jede Struktur mit jeder anderen Struktur emulieren - es kommt nur darauf an, wie einfach und übersichtlich die Programmiersprache dies zulässt. Zum Beispiel:
Die meisten Sprachen bieten mindestens einen Typ für geordnete Sequenzen, einen für eindimensionale Karten und einen für mehrdimensionale Karten, der auf Funktionen beschränkt ist. Ich persönlich vermisse oft Mengen und geordnete mehrdimensionale Strukturen in Sprachen wie Perl, PHP, JavaScript, Lua ..., weil es nicht bequem genug ist, sie zu emulieren.
quelle
Ich halte es für eine schlechte Idee, zu viele privilegierte Datentypen mit einer speziellen Syntax zu haben. Dies verkompliziert die Sprachsyntax unnötig, was das Lesen von Code erschwert, Anfängern das Lernen erschwert und die Entwicklung von Tools für die Sprache erschwert.
Es ist in Ordnung, eine Ausnahme für eine kleine Anzahl sehr gebräuchlicher Datenstrukturtypen zu machen. Ich würde wahrscheinlich maximal zulassen:
Alles, was raffinierter ist, sollte wahrscheinlich den Bibliotheken überlassen bleiben und die normale Syntax der Sprache für benutzerdefinierte Datentypen verwenden.
Insbesondere haben Dinge wie Rot / Schwarz-Bäume, Prioritätswarteschlangen usw. eine ganze Reihe möglicher Implementierungsoptionen, so dass es nicht ratsam ist, eine bestimmte Implementierung in die Kernsprache zu backen. Es ist besser, die Menschen die für ihre Situation am besten geeignete Implementierung auswählen zu lassen. Beispiele für Implementierungsoptionen, bei denen ich möglicherweise nicht möchte, dass ein Sprachdesigner meine Auswahl einschränkt:
quelle