Terms and their data types

## 3.1 Terms and their data types

- Numbers
- Strings
- Atoms
- Lists
- Structures

Prolog data (terms) and programs are built from a small set of simple data-types. In this section, we introduce these data types together with their syntax (their textual representations). For the full syntax see the User Manual appendix on Syntax.

### 3.1.1 Numbers

Numbers come in several flavours. The ones that are familiar from other programming languages are integers and floating point numbers. Integers in ECLiPSe can be as large as fits into the machine's memory:

>     123  0   -27   3492374892749289174

Floating point numbers (represented as IEEE double floats) are written as

>     0.0 3.141592653589793 6.02e23 -35e-12 -1.0Inf

ECLiPSe provides two additional numeric types, rationals and bounded reals. ECLiPSe can do arithmetic with all these numeric types.
Note that performing arithmetic requires the use of the is/2 predicate:

>     ?- X is 3 + 4.
>     X = 7
>     Yes

If one just uses =/2, ECLiPSe will simply construct a term corresponding to the arithmetic expression, and will not evaluate it:

>     ?- X = 3 + 4.
>     X = 3 + 4
>     Yes

⊙
  For more details on numeric types and arithmetic in general see the User Manual chapter on Arithmetic.

⊙
  For more information on the bounded real numeric type, see Chapter 9.

### 3.1.2 Strings

Strings are a representation for arbitrary sequences of bytes and are written with double quotes:

>     "hello"
>     "I am a string!"
>     "string with a newline \n and a null \000 character"

Strings can be constructed and partitioned in various ways using ECLiPSe primitives.

### 3.1.3 Atoms

Atoms are simple symbolic constants, similar to enumeration type constants in other languages. No special meaning is attached to them by the language. Syntactically, all words starting with a lower case letter are atoms, sequences of symbols are atoms, and anything in single quotes is an atom:

>     atom  quark  i486  -*-  ???  'Atom'   'an atom'

### 3.1.4 Lists

A list is an ordered sequence of (any number of) elements, each of which is itself a term. Lists are delimited by square brackets (`[ ]`), and elements are separated by a comma. Thus, the following are lists:

>     [1,2,3]
>     [london, cardiff, edinburgh, belfast]
>     ["hello", 23, [1,2,3], london]

A special case is the empty list (sometimes called nil), which is written as

>     []

A list is actually composed of head-and-tail pairs, where the head contains one list element, and the tail is itself a list (possibly the empty list). Lists can be written as a `[Head|Tail]` pair, with the head separated from the tail by the vertical bar. Thus the list `[1,2,3]` can be written in any of the following equivalent ways:

>     [1,2,3]
>     [1|[2,3]]
>     [1|[2|[3]]]
>     [1|[2|[3|[]]]]

The last line shows that the list actually consists of 3 `[Head|Tail]` pairs, where the tail of the last pair is the empty list. The usefulness of this notation is that the tail can be a variable (introduced below): `[1|Tail]`, which leaves the tail unspecified for the moment.

### 3.1.5 Structures

Structures correspond to structs or records in other languages. A structure is an aggregate of a fixed number of components, called its arguments. Each argument is itself a term. Moreover, a structure always has a name (which looks like an atom). The canonical syntax for structures is

> <name>(<arg>1,...<arg>n)

Valid examples of structures are:

>     date(december, 25, "Christmas")
>     element(hydrogen, composition(1,0))
>     flight(london, new_york, 12.05, 17.55)

The number of arguments of a structure is called its arity. The name and arity of a structure are together called its functor and is often written as name/arity. The last example above therefore has the functor `flight/4`.

⊙
  See section 4.1 for information about defining structures with named fields.

#### Operator Syntax

As a syntactic convenience, unary (1-argument) structures can also be written in prefix or postfix notation, and binary (2-argument) structures can be written in prefix or infix notation, if the programmer has made an appropriate declaration (called an operator declaration) about its functor. For example if `plus/2` were declared to be an infix operator, we could write:

>     1 plus 100

instead of

>     plus(1,100)

It is worth keeping in mind that the data term represented by the two notations is the same, we have just two ways of writing the same thing. Various logical and arithmetic functors are automatically declared to allow operator syntax, for example `+/2, not/1` etc.

#### Parentheses

When prefix, infix and postfix notation is used, it is sometimes necessary to write extra parentheses to make clear what the structure of the written term is meant to be. For example to write the following nested structure

>     +(*(3,4), 5)

we can alternatively write

>     3 * 4 + 5

because the star binds stronger than the plus sign. But to write the following differently nested structure

>     *(3, +(4, 5))

in infix-notation, we need extra parentheses:

>     3 * (4 + 5)

A full table of the predefined prefix, infix and postfix operators with their relative precedences can be found in the appendix of the User Manual.

> Numbers ECLiPSehas integers, floats, rationals and bounded reals. Strings Character sequences in double quotes. Atoms Symbolic constants, usually lower case or in single quotes. Lists Lists are constructed from cells that have an arbitrary head and a tail which is again a list. Structures Structures have a name and a certain number (arity) of arbitrary arguments. This characteristic is called the functor, and written name/arity.

> Figure 3.1: Summary of Data Types