Kopplung über die Form und Kopplung über die Fallliste. Woher sie kommen, was sie kosten, was sie mildert. Lernseite, keine Empfehlung.
Stand 09.11.2026. Jede Aussage trägt ihre Marke. Ein Tipp zeigt die Quelle.
In drei Sätzen
Die beiden Konzepte sind keine Gegensätze. Ein strukturelles Interface koppelt über die Form, ein Summentyp über die Liste der Fälle. Jede Sprache mit beidem zeigt, dass sie nebeneinander gehen.
Der Grundkonflikt offen gegen geschlossen ist seit bekannt. Bis heute gibt es keine billige Lösung. Was sich leicht mildern lässt, ist fast nur Sichtbarkeit: Go kann seine Kanten sichtbarer machen, Rust seine Wildcards verbieten.
Empirisch ist die Lage dünn. Direkt gemessen ist nur der mögliche Nutzen struktureller Typen in Java. Einen Vergleich von Summentypen mit Interfaces fand die Recherche nicht.
Was die Marken sagen
gemessen Zahl oder Beobachtung aus der Quelle.
gelesen Steht so in der Quelle, ohne Messung.
Meinung Urteil aus der Quelle, ohne Messung.
zweite Hand Nur über eine Sekundärquelle belegt.
Einschätzung Unser Urteil, keine Quelle.
Allgemeinwissen Jahreszahl ohne eigene Quelle.
Quelle Die Recherche nennt nur die Quelle, ohne Marke.
Mit unseren Proben ist eine Haushalts-App gemeint, einmal in Go und einmal in Rust gebaut. Die Grenzen der Proben stehen unter Unsere Proben.
Die zwei Arten
Ein Interface koppelt über die Form. Ein Summentyp koppelt über die Fälle.
Kopplung über die Form
Der Anbieter kennt den Verbraucher nicht. Wer ihn nutzt, sieht man nur zur Laufzeit oder per Suche.
Kopplung über die Fallliste
Jeder Verbraucher hängt an der ganzen Liste. Kommt ein Fall dazu, meldet der Compiler jede Stelle.
Die Karte
Die beiden Konzepte stehen nicht auf einer Achse. Alle vier Felder sind besetzt. Ein Tipp auf eine Sprache zeigt mehr.
Fälle offenjeder darf ergänzen
Fälle geschlossenCompiler kennt alle
Passt über die Form
Passt über den Namen
Go-Interface
Ein Interface ist eine Menge von Methoden, ohne implements.
Niemand erklärt die Passung. Sie gilt von selbst. Keine Kante, keine Spur im Build.
TypeScript-Interface
Strukturell, weil JavaScript so geschrieben wird.
Niemand erklärt die Passung. Sie gilt von selbst.
OCaml-Objekte
Passen über die Form, und die Fälle sind offen.
OCaml hat Objekte, polymorphe Varianten und datatype. Die drei sind vollständig getrennt.
TypeScript Discriminated Union
Tagged Unions über eine gemeinsame Eigenschaft.
Beide Formen sind strukturell. Erschöpfung gibt es nur über never als Idiom.
OCaml polymorphe Varianten
In der geschlossenen Form. Garrigue nannte das „Structural polymorphism“ für Varianten.
Sie sind sicher, aber „a weaker type discipline“, also eine schwächere Typdisziplin.
Java-Interface
Nur der Typ selbst darf die Passung erklären. Der Typ muss den Vertrag kennen. Das Handbuch von TypeScript nennt das als Gegenbild.
Rust-Trait
Ein Trait ist der Vertrag in Rust. Nur der Typ oder der Vertrag dürfen die Passung erklären. Das ist die Orphan-Regel.
Die Kante ist sichtbar. Sonst braucht es einen Adapter.
Ein Trait darf auch beim Vertrag stehen, nicht nur beim Typ. Das Erbe sind Typklassen.
Haskell-Typklasse
Jeder darf die Passung erklären. Ein Orphan, also eine Instanz weder beim Typ noch bei der Klasse, gibt nur eine Warnung (-Worphans).
Eine Spur ist da, aber zwei Antworten sind möglich.
Rust-enum
Algebraische Datentypen und Pattern Matching aus SML und OCaml.
Das Buch nennt die Regel: enum für eine feste Menge, Trait-Objekt für eine offene.
ML-datatype
Standard ML übernimmt Datatypes und Pattern Matching aus Hope.
Der Typ und alle Konstruktoren stehen an einem Ort.
Java sealed
sealed ist die Grundlage für erschöpfende Muster, seit Java 17.
Ein sealed interface ist ein Interface, dessen Implementierungen feststehen. Dort fallen beide Konzepte in einem Konstrukt zusammen.
Kotlin sealed
Wie Java: ein sealed interface, dessen Implementierungen feststehen.
C# 15union
union und closed. .NET 11 ist noch Vorabversion.
closed gilt für Klassen. Geschlossene Interfaces sind noch nicht drin.
Die dritte Achse: Wer erklärt die Passung, und wo steht das?
Unsere Beobachtung war: Go koppelt leicht und unsichtbar, Rust mit Aufwand und sichtbar. Das liegt auf keiner der beiden Achsen. Es liegt auf einer dritten.
Niemand, sie gilt von selbst
Go TypeScript Python Protocol
Keine Kante. Keine Spur im Build.
Nur Typ oder Vertrag dürfen sie erklären
Rust, Orphan-Regel
Kante sichtbar. Sonst ein Adapter.
Nur der Typ selbst
Java, C#
Der Typ muss den Vertrag kennen.
Jeder darf, mit Warnung
Haskell, Orphan-Instanzen Swift, @retroactive
Spur vorhanden, aber zwei Antworten möglich.
Zwei Linien
Links die Summentypen, rechts die strukturelle Passung. Die Reihe folgt der Zeit, die Abstände nicht. CLU steht in beiden.
SummentypenStrukturelle Passung
McCarthy Abstrakte Syntax mit Fällen. Vermutete Quelle für Landin.
Landin, ISWIM Daten „ist entweder … oder …“. Nur eine Konvention, nicht geprüft.
Algol 68union mit Etikett, Auswahl über case.
Pascal Varianten-Records. Das Etikett pflegt der Programmierer selbst.
Smalltalk Duck Typing, dynamisch. Wer die Nachricht versteht, passt.
CLU steht in beiden Linien
oneof und variant als eingebaute Tagged Unions.
where t has …. Der Compiler prüft die Operationen eines Typ-Parameters nach Name und Signatur.
Getrennte Mittel für getrennte Aufgaben.
Burstall, NPL Typen mit Konstruktoren und Pattern Matching.
Hope Der Typ und alle Konstruktoren stehen an einem Ort. Geburt des geschlossenen datatype.
Standard ML Übernimmt Datatypes und Pattern Matching aus Hope.
Maranget Algorithmus für nicht erschöpfende und nutzlose Fälle, in OCaml eingebaut.
Rust Algebraische Datentypen und Pattern Matching aus SML und OCaml.
TypeScript Tagged Unions über eine gemeinsame Eigenschaft.
Java 17sealed als Grundlage für erschöpfende Muster.
C# 15union und closed. .NET 11 ist noch Vorabversion.
Cardelli Strukturelle Subtypen, formal.
Modula-3 Strukturelle Gleichheit als Regel, BRANDED als Ausnahme.
Garrigue, OCaml „Structural polymorphism“ für Varianten.
Go Interface ist eine Menge von Methoden, ohne implements.
TypeScript Strukturell, weil JavaScript so geschrieben wird.
Python, PEP 544 „Static duck typing“ neben dem nominalen Weg.
Hope: geschlossen wegen schnellem Code
NPLKonstruktoren einzelnHopealle an einem Ort
Vor Hope war der Fall offen. NPL erlaubte, Konstruktoren einzeln zu deklarieren. Hope schloss die Liste nicht aus Gründen der Sicherheit, sondern für schnellen Code beim Pattern Matching.
Die Vollständigkeitsprüfung kam als Nutzen hinzu.
Modula-3: BRANDED trennt gleiche Formen
gleiche Form = gleicher TypBRANDED trennt sie
Die Sprache prüfte strukturell. Sie gab ein Wort, um zwei gleich geformte Typen zu trennen.
„Brands distinguish types that would otherwise be the same“
Marken unterscheiden Typen, die sonst gleich wären. TypeScript-Nutzer fordern dasselbe in Issue 202, mit , offen.
Rust begann strukturell. Frühe Fassungen hatten strukturelle Records. Sie wurden entfernt.
Was passiert, wenn …
Nur Fälle, die die Recherche belegt. Fehlt ein Beleg, steht das dort. Ein Tipp auf einen Fall zeigt beide Seiten.
Ein neuer Fall kommt dazu
Bei Kopplung über die Form
Reynolds, laut Cook: Objekte erleichtern neue Darstellungen.
Bei der Probe „Neuer Zustand“ gab es in Go kein Werkzeug, das die Stelle meldet.
exhaustive fängt fehlende Fälle. Es braucht aber einen switch an der Stelle.
Bei Kopplung über die Fallliste
Der neue Fall bricht jeden Verbraucher. Für Cargo ist das ein „Major“-Bruch ohne #[non_exhaustive].
Der Compiler kennt alle Fälle. Das treibt den Umbau: Bei der Probe „Neuer Zustand“ meldete er die Stelle.
Eine neue Methode kommt in den Vertrag
Bei Kopplung über die Form
Eine neue Methode bricht alle Implementierungen. Das gilt für Go und für Rust genauso .
Pike sagt: „A change to an interface affects only the immediate clients.“ Eine Änderung trifft also nur die direkten Nutzer.
Bei Kopplung über die Fallliste
Reynolds, laut Cook: Abstrakte Datentypen erleichtern neue Operationen.
Wadler zeichnet es als Tabelle. Funktionale Sprachen legen die Zeilen fest, also die Fälle.
Zwei Methoden haben zufällig dieselbe Signatur
Bei Kopplung über die Form
Dieselbe Signatur heißt nicht dasselbe. Malayeri und Aldrich prüften das von Hand. In Apache Collections gab es kein einziges Paar mit verschiedener Operation. In Lucene hatten von den gemeinsamen () nicht dieselbe Bedeutung. davon taten etwas anderes.
Das sind . Eine Messung an Go-Code fehlt.
Cook: „the type system does not prohibit bad implementations.“ Das Typsystem verbietet schlechte Implementierungen nicht.
Bei Kopplung über die Fallliste
Dazu hat die Recherche keinen Beleg.
_ steht in einem Match
_ heißt: alle übrigen Fälle.
Bei Kopplung über die Form
go-check-sumtype prüft fehlende Fälle bei einem Interface mit Marker. Ein default zählt dort als erledigt.
Bei Kopplung über die Fallliste
_ weist neuen Fällen stumm altes Verhalten zu. Lubin und Chasins beobachteten das in . Ein Teilnehmer sagt: In seiner Hauptcodebasis sind Wildcards deshalb verboten. Das ist qualitativ, ohne Zahl.
OCaml warnt davor als „fragile pattern matches“.
Das Wildcard-Verbot ist bei uns schon an.
Die Kante soll sichtbar werden
Bei Kopplung über die Form
Keine Kante im Build. Bei uns: , .
Den Laufzeit-Zyklus aus der Probe „Beide Module brauchen einander“ fand in Go nur der Review, keine automatische Prüfung.
var _ I = (*T)(nil) schreibt die Passung in den Code. Das kostet eine Zeile je Paar.
Bei Kopplung über die Fallliste
Die Kante hängt nicht an der Fallliste. Bei Rust kommt sie von Cargo und der Orphan-Regel.
Die Proben „Aufruf zwischen Modulen“ und „Beide Module brauchen einander“ (Go billiger, Rust sichtbarer) passen zur dritten Achse.
Was sie kosten
Vor- und Nachteile, einzeln mit Marke.
Strukturelle Interfaces
Was dafür spricht
Interfaces können definiert werden, ohne bestehenden Code zu ändern.
Keine Typ-Hierarchie, also auch keine Abhängigkeits-Hierarchie.
Der Verbraucher beschreibt nur, was er braucht. der Methodenparameter in Java ließen sich strukturell typisieren. Davon waren zu spezifisch deklariert. Bei gab es keinen passenden nominalen Typ. Die gefundenen Typen hatten im Mittel , die deklarierten .
Was dagegen spricht
Keine Kante im Build: , .
Die Form sagt nichts über die Bedeutung. Cook: „Pure object interfaces allow any structurally compatible implementation, thus the type system does not prohibit bad implementations.“
Zufällige Treffer: Mehr dazu beim Fall Gleiche Signatur oben.
Eine neue Methode bricht alle Implementierungen. In Go und in Rust .
Summentypen
Was dafür spricht
Der Compiler kennt alle Fälle. Bei der Probe „Neuer Zustand“ meldete er die Stelle, in Go gab es kein Werkzeug dafür.
Unmögliche Zustände lassen sich gar nicht erst bauen.
Der Fall trägt seine Daten mit, statt sie an einen String zu hängen.
Was dagegen spricht
Ein neuer Fall bricht jeden Verbraucher.
Geschlossen heißt: Fremde können nicht ergänzen. Eine feste Menge ist gut, solange man sie kennt. Für Erweiterung durch andere ist sie falsch.
Der Wildcard hebt alles wieder auf: Mehr dazu beim Fall _ im Match oben.
Die Prüfer haben selbst Fehler. Neuere Tests fanden Fehler in scalac, javac und ghc, vor allem bei rekursiven Typen.
Beides in einer Sprache
Viele Sprachen haben offene und geschlossene Mittel. Was geschieht, wenn beides sich trifft?
CLU (1977)
where-Klausel, oneof
Getrennte Mittel für getrennte Aufgaben.
OCaml
Objekte, polymorphe Varianten, datatype
Vollständig getrennt. Polymorphe Varianten sind sicher, aber „a weaker type discipline“.
TypeScript
Interface, Union
Beide strukturell. Erschöpfung nur über never als Idiom.
Scala 3
Traits, enum, Selectable
Strukturell nur per Reflexion, „much slower“.
Java 17, Kotlin
sealed interface
Ein Interface, dessen Implementierungen feststehen. Hier fallen beide Konzepte in einem Konstrukt zusammen.
Rust
trait, enum, „sealed trait“-Muster
Das Buch nennt die Regel: enum für eine feste Menge, Trait-Objekt für eine offene. Sealed Trait: Cargo nennt es als Technik.
C# 15
union, closed, Interface
closed gilt für Klassen. Geschlossene Interfaces sind noch nicht drin.
Wo beides da ist, entsteht kein Durcheinander. Die Sprachen trennen die Aufgaben. Der eine echte Konflikt ist bei Go der Nullwert.
Go hat beides nicht direkt
Die FAQ sagt: Varianten „overlap in confusing ways with interfaces“. Sie überlappen auf verwirrende Weise mit Interfaces.
Issue 19412, Summentypen. läuft
Issue 57644: Unions in Interfaces erlauben. Der Vorschlag sagt selbst: in naher Zukunft nicht zu erwarten.
neild, 76920: Unions in Interfaces sind der falsche Weg. Der Nullwert von Interfaces wäre nil, und der Vorschlag zwinge zwei verschiedene Konzepte zusammen. Auch dieser Vorschlag sagt selbst: in naher Zukunft nicht zu erwarten.
Vorschlag 80607 vom Go-Team abgelehnt. Ian Lance Taylor nannte den Nutzen zu klein für die Kosten. abgelehnt
offen
PR 80467 von RestartFU baut enum in einem eigenen Fork. Angenommen ist er nicht. offen
Mit Summentypen in Go ist in absehbarer Zeit nicht zu rechnen.
Was die Nachteile mildert
Jedes Mittel mit seinen Kosten. Filter nach Art oder Nachteil engen die Liste ein.
Kosten: nur auf Anfrage, außerhalb des Pakets nur exportierte
exhaustive
Werkzeug, Go
Wirkt auf: fehlende Fälle, auch bei Type Switches
Kosten: braucht einen switch an der Stelle
go-check-sumtype
Werkzeug, Go
Wirkt auf: fehlende Fälle bei Interface mit Marker
Kosten://sumtype:decl, ein default zählt als erledigt
Marke (BRANDED, Brand-Idiom)
Sprache oder Bauweise
Wirkt auf: zufällige Treffer
Kosten: mehr Text je Typ
#[non_exhaustive]
Sprache, Rust
Wirkt auf: Bruch durch neuen Fall
Kosten: zwingt zum Wildcard, verliert Erschöpfung außerhalb der Crate
@unknown default
Sprache, Swift
Wirkt auf: beides zugleich
Kosten: Warnung bei bekannten Fällen, trotzdem kompatibel
Wildcard-Verbot
Werkzeug
Wirkt auf: stumme Wildcards
Kosten: etwas mehr Text.
Bei uns schon an.
Sealed Trait
Bauweise, Rust
Wirkt auf: fremde Implementierungen
Kosten: Muster, kein Sprachmittel
Eigenes Vertrags-Crate oder Adapter
Bauweise, Rust
Wirkt auf: Orphan-Regel
Kosten: zusätzliche Fläche
Nichts passt zu beiden Filtern.
Die Orphan-Regel ist selbst ein Gegenmittel
Die Orphan-Regel verhindert, dass zwei Crates (Rust-Pakete) dieselbe Passung verschieden erklären. Matsakis nennt die Alternative: Man müsste festlegen, welche Implementierung gerade gilt.
Haskell lässt Orphans zu, mit Warnung -Worphans. Swift warnt seit 6.0, und @retroactive schaltet die Warnung ab. Rust hat die Regel mit RFC 2451 gelockert.
Gegen das Expression Problem selbst
Wadler, : „add new cases to the datatype and new functions over the datatype, without recompiling existing code, and while retaining static type safety“. Also neue Fälle und neue Funktionen, ohne Neukompilieren, typsicher.
FunktionFunktionFallFall
Zeilen sind Fälle, Spalten Funktionen. Funktionale Sprachen legen die Zeilen fest. Objektorientierte Sprachen legen die Spalten fest.
Reynolds sah das schon , laut Cook. Das Expression Problem liegt auf der Achse offen/geschlossen. Mit der Form-Achse hat es nichts zu tun.
Visitor plus Erweiterung
OO-Muster mit Fällen und Operationen.
Kosten: viel Zeremonie, jede Klasse braucht accept.
Kosten: Typklassen mit Überlappung und Erweiterungen.
Object Algebras
Fabrik-Interface, einfache Generics, kein accept.
Kosten: etwas neue Denkweise, in Java machbar. Beleg:
Tagless Final
Die Sprache als Typklasse, keine Etiketten.
Kosten: abstrakt. Beleg:
Keine davon bringt beides umsonst. Für eine Anwendung mit einer Handvoll Zustände und wenigen Modulen ist jede dieser Lösungen überdimensioniert. Das ist Bibliotheks-Technik.
Was belegt ist
Von gemessen bis nur Meinung. Oben ist der Boden fest, unten fehlt er.
Gemessen, auf genau dieser Achse
Nützt strukturelle Typisierung in nominalem Code? Gemessen an Potenzial, kein Vergleich mit Menschen. .
Wie oft trifft eine Passung zufällig? Gemessen an : .
Gemessen, aber auf einer anderen Achse
Typen finden Fehler: öffentlicher JavaScript-Bugs.
Sprache und Fehlerquote: Sehr kleine Effekte, nur signifikant.
Statische Typen allgemein: Helfen bei undokumentiertem Code und Typfehlern, nicht bei Logikfehlern.
Beobachtet, ohne Zahl
Hilft Vollständigkeitsprüfung gegen Fehler? Beobachtung, keine Zahl. Lubin und Chasins, qualitativ.
KI-Agenten beim Programmieren, mit Summentypen oder Interfaces: Nur unsere Proben. .
Nur Begründung, keine Messung
Orphan-Regel, Go-FAQ, Pike: Begründung der Designer, keine Messung.
Nicht gefunden
Ist das in Go auch so? Nicht gefunden.
Summentyp gegen Interface im direkten Vergleich? Nicht gefunden.
offen Was fehlt
Keine direkte Vergleichsstudie von Summentypen und Interfaces.
Keine Studie zu Go-Interfaces im Großen.
Keine Studie zu KI-Agenten und einem der beiden.
Die Malayeri-Studie ist die einzige, die genau diese Achse misst. Sie selbst sagt: „one must study the way structural subtyping is eventually used by mainstream programmers“. Man müsse also noch untersuchen, wie Programmierer strukturelle Typen tatsächlich nutzen.
Was das für unsere Proben heißt
Orientierung, keine Empfehlung. Kosten grob.
Was die Proben sind und was nicht
Unsere Proben stammen aus einer Haushalts-App. Wir haben sie einmal in Go und einmal in Rust gebaut.
Zwei Einschränkungen gelten für jeden Befund. Erstens: . Jede Probe lief je Fassung nur einmal. Zweitens: Es sind zugleich zwei Bauweisen. Ein Unterschied kann also an der Sprache liegen oder an der Bauweise.
In Go
var _ orders.Customers = (*customers.Module)(nil) (Beispiel) an der Stelle, die die Module zusammensteckt
Die drei Verträge
Die Passung steht im Code. Bricht früher.
Klein. Keine Kante im Build.
Richtungsliste als Test
Architektur-Test
Macht die Probe „Beide Module brauchen einander“ sichtbar.
Klein. Liste von Hand. Schon vorgeschlagen
exhaustive einschalten
Linter-Konfiguration, heute nicht aktiv
Fängt fehlende Fälle, wo ein switch steht.
Klein. Findet nichts ohne switch.
Eine Funktion mit switch je Zustandstyp
Die Zustandstypen der App
Schafft die Stelle, die exhaustive braucht. Die Probe „Neuer Zustand“ hätte einen Treffer.
Klein. Disziplin, kein Zwang.
Interface mit Marker und go-check-sumtype oder exhaustive -check=typeswitch
Zustände mit Daten je Fall
Nähe zum Summentyp.
Mittel. Ein Typ je Fall, Umbau an DB und Draht. default hebt es auf.
Keine dieser Stellen ersetzt den Compiler. Sie hängen alle daran, dass jemand den switch schreibt.
In Rust
Wildcard-Verbot
Schon aktiv
Fängt stumme Wildcards. Deckt genau den Befund aus ab.
Keine.
Vertrags-Crate
Anbieter-Crate und Verbraucher
Kanten weg, ein Trait statt drei.
Neue Crate, ADR
Adapter in der App-Crate
—
wie in Go.
Die App-Crate übersetzt dann fachlich
#[non_exhaustive]
nirgends sinnvoll
—
Erzwingt außerhalb der Crate einen Wildcard. Bei uns sind Crate-Grenzen Modulgrenzen. Der Compiler-Bruch ist dort gerade der Nutzen.
Was die Literatur zu unseren Proben sagt
Die Proben „Neuer Zustand“, „Ein Pflichtfeld“, „Zustände im Typ“ (Rust besser, Sprache) passen zur Linie. Der Gewinn ist seit Hope bekannt, und das ist der geschlossene Fall.
Die Proben „Aufruf zwischen Modulen“, „Beide Module brauchen einander“ (Go billiger, Rust sichtbarer) passen zur dritten Achse. Sie gehören nicht zum Expression Problem.
Nirgends bei uns wird das Expression Problem zum Hindernis. Module erweitert nur unser eigener Code.
Die Literatur stößt unsere Proben nicht um. Sie stützt die zwei Seiten, die wir schon gemessen haben.
Typische Irrtümer
„Interfaces und Summentypen schließen sich aus.“
Falsch. Java 17 hat sealed interface. TypeScript hat beides. Rust hat beides. Der Satz der Go-FAQ gilt für Go, nicht allgemein.
„Strukturell heißt unsicher.“
Falsch. Go prüft die Passung beim Kompilieren. TypeScript ist an anderen Stellen unsound, nicht wegen der Struktur.
„Nominal heißt: Kante sichtbar.“
Nur teilweise. Bei Rust kommt die Kante von Cargo und der Orphan-Regel. In Haskell sind Orphans unsichtbar erlaubt.
„Ein Trait ist ein Java-Interface.“
Nein. Ein Trait darf auch beim Vertrag stehen, nicht nur beim Typ. Das Erbe sind Typklassen.
„Summentypen sind etwas Modernes.“
Nein. Hope hatte das Konzept fertig.
„Der Compiler findet die Fehler.“
Er findet die Stelle. Was dort richtig ist, entscheidet jemand anderer. Ein _ schaltet ihn ab.
3Reynolds: User-defined types and procedural data structures as complementary approaches to data abstraction, 1975. Nur über [2]. Nur über Quelle 2, kein eigener Abruf.
8Cardelli: Publikationsliste, darin A Semantics of Multiple Inheritance (1984/1988), Structural Subtyping and the Notion of Power Type (POPL 1988) http://lucacardelli.name/indexPapers.html
17Go Issue 80607: define sum types as an extension of interfaces. Taylor 12.08.2026: „likely decline“, letzter Kommentar 09.09.2026, geschlossen https://github.com/golang/go/issues/80607
50Hanenberg u. a.: An empirical study on the impact of static typing on software maintainability, Empirical Software Engineering 19(5), 2014, S. 1335–1382. Nur Zusammenfassung aus dem Suchergebnis, ohne eigenen Abruf. Nur Zusammenfassung aus dem Suchergebnis, ohne eigenen Abruf.