DDP-Projekt / Kompilierer

Der Kompilierer der Deutschen Programmiersprache
https://ddp.le0n.dev/Spielplatz
MIT License
138 stars 4 forks source link

Typ Aliase (typedefs) #45

Closed bafto closed 2 months ago

bafto commented 9 months ago

Typdefs sind ein nettes Feature, welches von vielen Sprachen (C, C++, Go, Scala, ...) unterstützt wird. In DDP ist es zwar nicht zwingend notwendig, aber doch sehr nützlich und spätestens mit der Einführung von Generics essenziell.

Die Syntax könnte so aussehen:

Wir nennen ein(e/en) <Typname> ein(e/en) <Typalias>.

[Beispiele]
Wir nennen eine Zahl eine Postleitzahl.
Wir nennen einen Wahrheitswert einen Boolean.

[Beispiel für einen Vektor mit Typparameter T]
Wir nennen einen Vektor mit T gleich Zahl einen ZahlenVektor.
Wir nennen einen Vektor mit T gleich Kommazahl einen KommazahlenVektor.
bafto commented 2 months ago

Ich würde auch vorschlagen, dass solche Typ-Aliase als eigene Typen gelten, und nicht implizit umgewandelt werden. Also in nicht-ddp pseudo-code:

typedef my_int = int;

foo( int ) {
  ....
}

my_int i = 2.
foo( i ); // Fehler -> foo erwartet int, aber hat my_int bekommen
foo( int( i ) ); // funktioniert

Das bringt Vorteile beim API Design, und kann dazu führen, dass Fehler bereits beim Kompilieren gefunden werden. Betrachten wir als Beispiel DDP-Bindings für sqlite3:

Wir nennen die Kombination aus
    der Zahl p mit Standardwert 0,
einen Zeiger,
und erstellen sie so:
    "null"

Die Funktion Oeffne_DB mit dem Parameter db vom Typ Zeiger Referenz, gibt einen Wahrheitswert zurück,
ist in "sqlite.ddp.c" definiert
und kann so benutzt werden:
    "Oeffne <db>" oder
    "<db> erfolgreich geoeffnet wurde"

Die Funktion Statement_Vorbereiten mit den Parametern db, stmt und sql vom Typ Zeiger, Zeiger Referenz und Text, gibt einen Wahrheitswert zurück,
ist in "sqlite.ddp.c" definiert
und kann so benutzt werden:
    "Bereite <stmt> in <db> mit dem SQL <sql> vor" oder
    "<stmt> erfolgreich in <db> mit dem SQL <sql> vorbereitet wurde"

In diesem Beispiel ist es sehr einfach Fehler zu machen, wenn man einen beliebigen Zeiger als db oder stmt übergibt. Es wird auch nicht zwischen den Typen Datenbank oder Statement unterschieden.

Mit neuer Syntax könnte das so aussehen:

Wir nennen eine Zahl einen Zeiger.
Wir nennen einen Zeiger eine Datenbank.
WIr nennen einen Zeiger einen SQLAusdruck.

Die Funktion Oeffne_DB mit dem Parameter db vom Typ Datenbank Referenz, gibt einen Wahrheitswert zurück,
ist in "sqlite.ddp.c" definiert
und kann so benutzt werden:
    "Oeffne <db>" oder
    "<db> erfolgreich geoeffnet wurde"

Die Funktion Statement_Vorbereiten mit den Parametern db, stmt und sql vom Typ Datenbank, SQLAusdruck Referenz und Text, gibt einen Wahrheitswert zurück,
ist in "sqlite.ddp.c" definiert
und kann so benutzt werden:
    "Bereite <stmt> in <db> mit dem SQL <sql> vor" oder
    "<stmt> erfolgreich in <db> mit dem SQL <sql> vorbereitet wurde"

Es ist klar zu sehen, was die Parameter jeder Funktion sein müssen, und es steht nicht mehr bloß überall Zeiger.

Alternative

Man könnte beides einführen: Typdefs, die implizit umgewandelt werden, und solche die es nicht werden. Mögliche Syntax:

Wir nennen eine Zahl auch eine Hausnummer. [Hausnummer ist bloß ein neuer Name für Zahl und kann überall austauschbar benutzt werden]

Wir definieren einen Zeiger als eine Zahl. [Zeiger ist ein eigener Type, der immer in eine Zahl umgewandelt werden muss und nicht dieselben Operatoren besitzt]

Die Zahl zahl ist 1.
Die Hausnummer h ist zahl. [geht]
Speichere h plus 1 in h. [geht]

Der Zeiger zeiger ist z. [Fehler: falscher Typ]
Der Zeiger zeiger ist z als Zeiger [geht]
Speichere z plus 1 in z. [Fehler: der plus Operator geht nicht für Zeiger]