Introduction to Programming Languages/Primitive Types

Primitive Types


Every programming language that has types builds these types around a finite set of primitive types. Primitive types are atomic. In other words, they cannot be de-constructed into simpler types. As an example, the SML programming language has five primitive types:

  • bool: these are the true or false.
  • int: these are the integer numbers, which can be positive or negative.
  • real: these are the real numbers. SML might represent them with up to 12 meaningful decimal digits after the point, e.g., 2.7 / 3.33 = 0.810810810811.
  • char: these are the characters. They have a rather cumbersome syntax, when compared to other types. E.g.: #"a".
  • string: these are the chains of characters. However, contrary to most of the programming languages, strings in SML cannot be de-constructed as lists of characters.

Different languages might provide different primitive types. Java, for instance, has the following primitive types:

  • bool (1-bit)
  • byte (1-byte signed)
  • char (2-byte unsigned)
  • short (2-byte signed)
  • int (4-byte signed)
  • long (8-byte signed)
  • float (4-byte floating point)
  • double (8-byte floating point)

Some authors will say that strings are primitive types in Java. Others will say that strings are composite: they are chains of characters. Nevertheless, independent on how strings are classified, we all agree that strings are built-in types. A built-in type is a data type that is not user-defined. Because the built-in type is part of the core language, its elements can be treated specially by the compiler. Java's strings, for instance, have the special syntax of literals between quotes. Furthermore, in Java strings are implemented as read-only constants. If we try, say, to insert a character in the middle of a string, then what we can do is to build a new string composing the original value with the character we want to insert.

In some languages the primitive types are part of the language specification. Thus, these types have the same semantics in any system where the language is supported. This is the case of the primitive types in Java and in SML, for instance. For example, the type integer, in Java, contains 232 elements in any setup that runs the Java Virtual Machine. However, there exist systems in which the semantics of a primitive type depends on the implementation of the programming language. C is a typical example. The size of integers in this programming language might vary from one architecture to the others. We can use the following function to find out the largest integer in C:

int main(int argc, char** argv) {
  unsigned int i = ~0U;
  printf("%d\n", i);
  i = i >> 1;
  printf("%d\n", i);

This function is executed in constant time, because of the operations that manipulate bits. In languages that do not support this type of operations, in general we cannot find the largest integer so quickly. For instance, the function below, in SML, finds the largest integer in  , where   is the number of bits in the integer type:

fun maxInt current inc = maxInt (current + inc) (inc * 2)
    handle Overflow => if inc = 1 then current else maxInt current 1

Type Definition · Constructed Types