# Defining new types and subtypes

You can define a new type with the following syntax:

`type T is...`

followed by the description of the type, as explained in detail in each category of type.

Formally, the above declaration creates a type and its first subtype named T. The type itself, correctly called the “type of T”, is anonymous; the RM refers to it as T (in italics), but often speaks sloppily about the type T. But this is an academic consideration; for most purposes, it is sufficient to think of T as a type. For scalar types, there is also a base type called T’Base, which encompasses all values of T.

For signed integer types, the type of T comprises the (complete) set of mathematical integers. The base type is a certain hardware type, symmetric around zero (except for possibly one extra negative value), encompassing all values of T.

As explained above, all types are incompatible; thus:

```
type Integer_1 is range 1 .. 10;
type Integer_2 is range 1 .. 10;
A : Integer_1 := 8;
B : Integer_2 := A; -- illegal!
```

is illegal, because `Integer_1`

and `Integer_2`

are different and incompatible types. It is this feature which allows the compiler to detect logic errors at compile time, such as adding a file descriptor to a number of bytes, or a length to a weight. The fact that the two types have the same range does not make them compatible: this is name equivalence in action, as opposed to structural equivalence. (Below, we will see how you can convert between incompatible types; there are strict rules for this.)