Kurz: Ein Typsystem legt fest, welche Arten von Werten (Zahlen, Texte, Listen, Objekte) es gibt und welche Operationen dafür erlaubt sind. Es entscheidet, wie früh Fehler auffallen: beim Übersetzen (statisch) oder erst beim Ausführen (dynamisch).
Genauer: Zwei Achsen werden oft verwechselt: statisch vs. dynamisch (wann wird geprüft?) und stark vs. schwach (wie streng sind die Regeln, wird still umgewandelt?). Python ist dynamisch und stark; C ist statisch und schwach; JavaScript ist dynamisch und schwach; Rust und Haskell sind statisch und stark.
Im Detail
Statisch oder dynamisch
- Statisch: Typen stehen vor dem Start fest und werden vom Compiler geprüft (Java, C#, Go, Rust, OCaml, Pascal, Ada). Falsche Aufrufe fallen früh auf, Editoren vervollständigen besser, der Compiler kann optimieren.
- Dynamisch: Werte tragen ihren Typ zur Laufzeit (Python, Ruby, Lua, Erlang, Prolog, Lisp). Weniger Schreibaufwand, schnelle Experimente – dafür fallen Typfehler erst im Betrieb auf.
- Graduell: Typen sind optional ergänzbar: TypeScript (zu JavaScript), Python mit Typannotationen, Racket mit Typed Racket, Groovy mit
@CompileStatic.
Stark oder schwach
Schwache Typisierung wandelt Werte implizit um und kann Fehler verstecken: In JavaScript ergibt "5" + 3 den Text "53", "5" - 3 aber die Zahl 2. In C lassen sich Zeiger und Zahlen beliebig vermischen. Starke Typisierung verlangt explizite Umwandlungen: In F# ist 1 + 2.0 ein Fehler, in OCaml braucht man +. für Fließkommazahlen.
Typinferenz
Der Compiler errät Typen aus dem Zusammenhang, ohne dass sie überall notiert werden: Haskell, OCaml, F#, Kotlin, Scala, Rust, Go (x := 5), Nim und Swift. So verbindet man die Sicherheit statischer Typen mit der Kürze dynamischer Sprachen.
Typsystem-Besonderheiten
| Merkmal | Beispiel |
|---|---|
| Algebraische Datentypen (Summentypen) | enum in Rust und Scala, Varianten in OCaml |
| Null-Sicherheit | Option/Maybe in Rust und Haskell, ? in Kotlin und Dart |
| Generics | Java, C#, Rust, C++-Templates |
| Typklassen / Traits | Haskell, Rust, Scala (given) |
| Wertebereichstypen | range 1 .. 100 in Ada, 0..9 in Pascal |
| Einheiten im Typ | <m> in F# |
| Ownership (Besitz) | Rust prüft Lebensdauer und Besitz im Typsystem |
Wann lohnt sich welches?
Kleine Skripte profitieren von dynamischen Sprachen; große, lange gepflegte Codebasen und sicherheitskritische Systeme von statischen. Deshalb bekamen JavaScript (TypeScript), Python (Typannotationen) und PHP (Typdeklarationen) nachträglich Typen.
Siehe auch: Programmierparadigmen, Kompiliert oder interpretiert?, Sprachen im Vergleich