Typing (computer science)

from Wikipedia, the free encyclopedia

A typing is used in computer science to the fact that the objects (abstract mathematical objects here understood in the sense) of the programming languages such. B. Variables , functions or objects (in the sense of object-oriented programming ) are used correctly. One goal of typing is to avoid runtime errors .

Type system

In computer science , the term type system describes a component that can be used in programming languages to limit the range of values ​​of variables. Programming languages ​​that have a type system are called typed . Depending on the characteristics of the type system, one also speaks of strongly typed or weakly typed languages. The typing is intended to ensure that no operations are performed on the content of variables that are syntactically or semantically incorrect. A type system is formed by the following components:

  • The types themselves, which are either created using type definitions or are firmly integrated in the respective language (as primitive data types ).
  • The ability to declare program elements (such as variables, method parameters , etc.) with a specific type using type annotation .
  • Rules according to which the values ​​of expressions are assigned a certain type.
  • Rules for checking the assignment compatibility of types.
  • Optionally, further language components such as type-related operators (e.g. "instanceof" in various languages) or a reflection API for determining and checking type information at runtime.

Classification of type systems

Type systems can be classified along three dimensions:

  • strong typing ( strong typing ) and weak typing ( weak typing )
    How strict language distinguishes the types? Which data types can be converted into one another? Does it allow implicit casts? Does it allow insecure cast conversions, e.g. B. Values ​​can be lost?
  • dynamic typing ( dynamic typing ) and static typing ( static typing )
    type tests may be made at compile time or at runtime. In the first case one speaks of static type testing , in the second of dynamic type testing . Static type tests allow assignment errors to be found before runtime, whereas with dynamic typing they are not noticed until runtime. In return, the latter allows more powerful behavior such as the correct processing of actually incompatible types and extensions at runtime.
  • explicit typing ( explicit typing ) and implicit typing ( implicit typing )
    If the data types mentioned explicitly or by type derivation ( type inference determined)?
  • optional typing ( optional typing )
    type annotations are used to support the programmer, but have no impact on the actual implementation by the compiler at run time.

The tasks of a type system include:

  • Detection of type violations during translation and execution. The type information can be understood as redundant information, which prevents variables from being assigned values ​​which the relevant variable should never assume (so-called type invariants ). It prevents the execution of operations on the contents of these variables, which are either impossible or not useful for reasons of program logic.
  • Typecasting (engl. Type conversion ), so conversion and transport and degradation of types (engl. Type promotion , type demotion ). In many object-oriented languages, the three options up cast , down cast and cross cast are available for this.

Examples

The following examples are intended to clarify the classification; however, the classification of languages ​​in these categories is subjective to a certain extent ( e.g. C ++ is typed more strongly than C, but weaker than OCAML ), and many type systems have several aspects depending on their use ( polymorphic values , type conversion, etc.) .


none: x86 assembler

 mov ah, 0x0e                      ; Weise dem oberen Byte des Registers a den Wert 14 zu.
 mov al, '!'                       ; Weise dem unteren Byte den Wert des Zeichens '!' zu.
 int 0x10                          ; Erzeuge Interrupt 0x10 um das Zeichen '!' auszugeben.


Static, explicit, weak: C

 int x;                            // Weise x explizit den Typ int (Ganzzahl) zu.
 char *str = x;                    // Weist str als Anfangsadresse den Wert von x zu.
                                   // Da x undefiniert ist, kann die Ausgabe von str zum Programmabsturz führen.
 x = &str;                         // Weist x die Speicheradresse von str zu.
 *(char **)x = "text";             // Schreibt die Anfangsadresse des Strings "text" in die Adresse von str.
 printf("%s", str);                // Ausgabe von "text"


Static and Dynamic, Explicit and Implicit, Strong: C #

 object addmax(object a, int b, short c)
 {
     int max = Math.Max(b, c);     // Aufruf von Max(int b, int c) der Klasse Math
     int sum = (int)a + max;       // InvalidCastException falls a nicht konvertierbar,
                                   // NullReferenceException falls a undefiniert
     return sum;                   // implizite Konvertierung (Boxing) von int zu object
 }


Static, explicit and implicit, strong: Java

 Integer addmax(Object a, int b, short c) {
    int max = Math.max(b, c);      // Aufruf von max(int b, int c) der Klasse Math
    int sum = (int)a + max;        // ClassCastException falls a nicht konvertierbar,
                                   // NullPointerException falls a undefiniert
    return sum;                    // implizite Konvertierung (boxing) zu Integer
 }


Static, implicit, strong: OCAML

 let myAdd a b =                (* Wir definieren eine Funktion, die zwei nicht näher bezeichnete Werte nimmt *)
   a +. b;;                     (* +. ist der Additionsoperator für Gleitkommazahlen *)
                                (* val myAdd : float -> float -> float = <fun> *)
                                (* Ocaml hat von selbst erkannt, dass diese Funktion zwei Gleitkommazahlen erwartet und eine zurückgibt *)
 myAdd 1 2.5;;                  (* Addiere zwei Zahlen, aber eine davon ist eine Ganzzahl *)
                                (* '''Compilerfehler:''' This expression has type int but is here used with type float *)
 myAdd (float_of_int 1) 2.5;;   (* Addiere zwei Zahlen, wandle Ganzzahl zuvor in Gleitkommazahl um, ergibt 3.5 *)

 let x = object method a = 10 end;;               (* definiere ein Objekt mit einer Methode a, die den Wert 10 zurückgibt *)
 let y = object method a = 10 method b = 11 end;; (* definiere ein Objekt mit zwei Methoden a und b, die jeweils unterschiedliche Ints zurückgeben. *)
 let l = [x;(y :> <a:int>)];;                     (* speichere x und y in einer Liste. y wird dabei in den Typ von x umgewandelt *)


Static and dynamic, explicit, strong: Pascal

 var a,b : integer;
       c : char;
 begin
   a := 33;                        { Weise a den ganzzahligen Wert 33 zu. }
   c := chr(a);                    { Weise c den Buchstaben zu, der dem ASCII-Wert von a entspricht. }
   b := ord(c);                    { Weise b den ASCII-Wert von c zu. }
   writeln(b, c);                  { Gibt "33 !" aus. }
   b := a / 2;                     { Laufzeitfehler, da die Division keinen ganzzahligen Wert ergibt. }
 end


Dynamic, implicit, weak: Perl

 $x = 1.5;                         # x ist nun die Zeichenkette "1.5"
 $x = $x + "4-2";                  # x ist nun "5.5" da nur 4 addiert wurde
 $x = $x + "text";                 # x ist unverändert, da "text" nicht mit einer Zahl beginnt


Dynamic, implicit, weak: PHP

 $x = 1;                           // Weise x explizit den Wert 1 zu.
 $x = 2 + "42";                    // Addiere eine Zahl und eine Zeichenkette,
                                   // wandle dazu die Zeichenkette in eine Zahl um
                                   // $x ist jetzt 44
 $x = 2 + "Ich bin keine Zahl";    // Wie oben, ungültige Zeichenkette wird zu 0 umgewandelt
                                   // $x ist jetzt 2


Dynamic, implicit, strong: Python

 x = 1                             # Weise x explizit den Wert 1 zu.
 x = 2 + "42"                      # Addiere eine Zahl und eine Zeichenkette, Laufzeitfehler ("TypeError")
 x = 2 + int("42")                 # Addiere eine Zahl und eine Zahl, die aus einer Zeichenkette erstellt wird
                                   # x ist jetzt 44
 x = 2 + int("Ich bin keine Zahl") # Laufzeitfehler ("ValueError")


Static and dynamic, explicit, strong: Pike

 int x = 1;                        // Definiere x als int und weise explizit den Wert 1 zu.
 x = 2 - "42";                     // Subtrahiere eine Zeichenkette von einer Zahl, Kompilier- oder Laufzeitfehler ("Bad argument 2 to `-.")
 x = "42";                         // Weise x den wert "42" zu. Kompilierfehler ("Bad type in assignment")
 x = 2 + (int)"42";                // Addiere eine Zahl und eine Zahl, die aus einer Zeichenkette erstellt wird
                                   // x ist jetzt 44
 x = 2 + (int)"Ich bin keine Zahl" // Ungültige Zeichenkette wird zu 0 umgewandelt
                                   // x ist jetzt 2

See also

literature

  • Luca Cardelli: Type Systems . In: Allen B. Tucker (Ed.): The Computer Science and Engineering Handbook . CRC Press, Boca Raton FL 1997, chapter 103, pp. 2208-2236.
  • Benjamin Pierce: Types and Programming Languages . MIT Press, 2002
  • Robert Harper: Practical Foundations for Programming Languages . Cambridge University Press, 2012 ( cs.cmu.edu (PDF; 1.7 MB)).

Web links