Typsysteme: nominal vs. strukturell, explizit vs. implizit


24

Ich bin etwas verwirrt über den Unterschied zwischen nominalen und strukturellen Systemen. Kann jemand bitte erklären, wie sie sich unterscheiden?

Von dem, was ich verstehe:

  • Nominal: Die Typkompatibilität basiert auf dem Typnamen.
  • Strukturell: Die Typkompatibilität basiert auf der Typstruktur. Wenn z. B. in C zwei Variablen Strukturtypen mit unterschiedlichen Namen, aber derselben Struktur sind, sind ihre Typen kompatibel.

Nun zu explizit und implizit: Warum unterscheidet es sich von statischer und dynamischer Typisierung? Bei der statischen Typisierung sind Typen explizit, während bei der dynamischen Typisierung Typen implizit sind. Habe ich recht?

Antworten:


29

In einem dynamisch typisierten System haben Werte zur Laufzeit Typen, Variablen und Funktionen jedoch nicht. In einem statisch typisierten System sind die Typen von Variablen und Funktionen bekannt und werden beim Kompilieren überprüft. ZB in Python xkann alles sein ; Wenn es zur Laufzeit 1eine Zahl ist "foo", ist es eine Zeichenfolge. Sie wissen nur, welcher Typ xzur Laufzeit vorhanden ist, und er kann bei jedem Ausführen des Programms anders sein. In einer Sprache wie Java würden Sie schreiben, int xwenn xes sich um eine Zahl handeln würde, und Sie würden beim Kompilieren wissen, dass es sich ximmer um eine Zahl handeln muss int.

"Explizite" und "implizite" Typen beziehen sich beide auf statische Typsysteme. Das bestimmende Merkmal eines statischen System ist , dass die Typen sind bekannt bei der Kompilierung, aber nicht unbedingt , dass sie aus geschrieben werden müssen. In Java sind Typen explizit - Sie müssen sie ausschreiben. In Java könnte eine Methode folgendermaßen aussehen:

public int foo(String bar, Object baz) { ... }

Die Typen sind sowohl zur Kompilierungszeit bekannt (statisch) als auch ausgeschrieben (explizit). Es gibt jedoch auch Sprachen, die Sie nicht zwingen, den Typ auszuschreiben. Sie können den Typ einer Funktion aus ihrem Körper und ihrer Verwendung ableiten . Ein Beispiel wäre OCaml, wo Sie so etwas schreiben können:

let foo x = x + 1

Da Sie verwendet haben +, kann OCaml herausfinden, dass xdies intalles für sich sein muss. Der Typ von foo( foo : int -> int) ist also zur Kompilierungszeit bekannt, genau wie im Java-Beispiel. Es ist völlig statisch. Da der Compiler jedoch selbst herausfinden kann, was die Typen sein müssen, müssen Sie sie nicht selbst aufschreiben: Sie sind implizit.

Kurz: Ob ein Typsystem explizit oder implizit ist, ist eine Eigenschaft statischer Systeme. Es ist eine ganz andere Frage, ob ein Typensystem dynamisch oder statisch ist.

Oft haben Sie Typsysteme, die manchmal explizit und manchmal implizit sind.

Ich glaube beispielsweise, dass Sie mit C # mithilfe des varSchlüsselworts auf Typen schließen können . Anstatt also zu schreiben int x = 10, können Sie schreiben, var x = 10und der Compiler stellt fest, dass xdies eine sein muss int. C ++ macht etwas Ähnliches mit auto. Diese Systeme sind in der Regel explizit, lassen jedoch Rückschlüsse zu.

Auf der anderen Seite gibt es Systeme, die normalerweise implizit sind, Sie jedoch manchmal zum Schreiben einer Typensignatur zwingen. Haskell ist ein gutes Beispiel. Meistens kann Haskell die Typen für Sie ableiten. Manchmal können Sie jedoch mehrdeutigen Code schreiben show . read, bei dem Haskell die Typen nicht selbst herausfinden kann. In diesem Fall müssten Sie entweder showoder explizit angeben read. Darüber hinaus machen einige fortgeschrittenere Merkmale des Typsystems (wie der Rang-n-Polymorphismus) die Inferenz unentscheidbar - das heißt, es ist nicht garantiert, dass sie anhält. Dies bedeutet, dass Code, der diese Funktion verwendet, häufig explizite Typensignaturen benötigt.


2
Tatsächlich gibt es einige Sprachen mit einer expliziten dynamischen Typisierung . In diesen Sprachen können Sie normalerweise Ausdrücke mit Typen versehen. Diese Typen werden dann zur Laufzeit mit dem Laufzeittyp des Ausdrucks abgeglichen.
Jörg W Mittag

nur eine präzision: typsysteme sind nicht implizit oder explizit. Hierbei handelt es sich lediglich um eine Typinferenz, bei der es sich im Wesentlichen um eine Möglichkeit handelt, gültige Terme in einem Typsystem aus einer anderen (manchmal nicht festgelegten) Syntax zu generieren.
Eduardo Pareja Tobes

Gute Antwort, aber hier geht es nicht um nominelle oder strukturelle Typisierung. Eine Bearbeitung wäre toll.
lunchmeat317

7
  • statisch vs dynamisch beschreibt, wann Typen überprüft werden (mehr oder weniger zur Kompilierungszeit oder zur Ausführungszeit)

  • nominal vs strukturell beschreibt, wenn zwei Typen als gleich angesehen werden.

(Und es gibt Variationen, die bekannteste ist die Variante der strukturellen Typisierung, die nur berücksichtigt, was anstelle der gesamten als Ententypisierung bekannten Typisierung verwendet wird.)

Die vier Kombinationen (statisch nominal, statisch strukturell, dynamisch nominal, dynamisch strukturell) sind möglich, und Sprachen gehören oft nicht nur zu einer Klasse, sondern zu anderen.

Beispielsweise sind die Typsysteme von C ++ statisch, meist nominell, aber strukturell, wenn Sie Vorlagen berücksichtigen (und Sie können einen Teil der Probleme im Zusammenhang mit Konzepten in C ++ als Konflikt zwischen denjenigen betrachten, die vom Duck-Typing zu einer vollständigen Form des strukturellen Typings übergehen möchten diejenigen, die zur nominalen Eingabe gehen wollen). Die Verwendung von Klassen und Vererbung ermöglicht in einigen Fällen die Verwendung einer dynamischen und nominalen Typisierung.

Sprache, die in dynamischen Typsystemen häufig strukturelle Typisierung verwendet, aber CLOS als nominelle Aspekte.


1

Strukturell: Die Typkompatibilität basiert auf der Typstruktur. Wenn z. B. in C zwei Variablen Strukturtypen mit unterschiedlichen Namen, aber derselben Struktur sind, sind ihre Typen kompatibel.

Dies ist normalerweise nicht der Fall. Strukturelles Typisieren bedeutet, dass Bes sich um einen Subtyp handelt, der der Schnittstelle von " ABefriedigen A" entspricht. Dies bedeutet normalerweise, Mitglieder mit demselben Namen zu haben. nicht nur die gleiche Struktur im Speicher.

Dies unterscheidet sich von der nominativen Typisierung, bei der bei der Deklaration Supertypen angegeben werden müssen.


1

Die beste Erklärung, die ich für die Unterscheidung zwischen (tatsächlich unterstellten) dynamischen und statischen Typsystemen gesehen habe, ist in diesem Blog-Beitrag von Bob Harper:

Sein Hauptpunkt kann wie folgt zusammengefasst werden:

  • Dynamische Sprachen sind die statischen Sprachen mit nur einem Typ

1
Links können kaputt gehen; Sie sollten die relevantesten Teile des Artikels zitieren, damit sie für die Nachwelt erhalten bleiben, auch wenn der Blog kaputt geht.
Doval

2
Sicher. Ich denke, dass in diesem Fall der Satz, den ich hinzugefügt habe, ausreicht :)
Eduardo Pareja Tobes
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.