## 2.1 Record types

The `Record` construction is a macro allowing the definition of records as is done in many programming languages. Its syntax is described on figure 2.1. In fact, the `Record` macro is more general than the usual record types, since it allows also for ``manifest'' expressions. In this sense, the `Record` construction allows to define ``signatures''.

> sentence | ::= | record
> record | ::= | `Record` ident [`[` params `]`] `:` sort `:=` [ident] `{` [field `;` ... `;` field] `}` `.`
> field | ::= | ident `:` type
> | | | ident `:=` term
> | | | ident `:` type `:=` term

> Figure 2.1: Syntax for the definition of `Record`

In the expression
`Record` ident `[` params `]` `:` sort := ident0 `{` ident1 `:` term1; ...identn `:` termn `}`.
the identifier ident is the name of the defined record and sort is its type. The identifier ident0 is the name of its constructor. If ident0 is omitted, the default name `Build_`ident is used. The identifiers ident1, .., identn are the names of fields and term1, .., termn their respective types. Remark that the type of identi may depend on the previous identj (for j<i). Thus the order of the fields is important. Finally, params are the parameters of the record.
More generally, a record may have explicitly defined (a.k.a. manifest) fields. For instance, `Record` ident `[` params `]` `:` sort := `{` ident1 `:` type1 `;` ident2 `:=` term2 `;`. ident3 `:` type3 `}` in which case the correctness of type3 may rely on the instance term2 of ident2 and term2 in turn may depend on ident1.
Example: The set of rational numbers may be defined as:
`Coq` `<``Record Rat : Set := mkRat {`
`Coq` `<``sign : bool;`
`Coq` `<``top : nat;`
`Coq` `<``bottom : nat;`
`Coq` `<``Rat_bottom_cond : ~O=bottom;`
`Coq` `<``Rat_irred_cond:(x,y,z:nat)(mult x y)=top/\(mult x z)=bottom-``>``x=(S O)}.`
`Rat is defined`
`Rat_rect is defined`
`Rat_ind is defined`
`Rat_rec is defined`
Remark here that the field `Rat_cond` depends on the field `bottom`.
Let us now see the work done by the `Record` macro. First the macro generates a inductive definition with just one constructor:
`Inductive` ident`[` params`] :` sort`:=
` ident`0``: (`ident`1``:`term`1``) .. (`ident`n``:`term`n``)(`ident`` params`).`
To build an object of type ident, one should provide the constructor ident0 with n terms filling the fields of the record.
Let us define the rational 1/2.
`Coq` `<``Require Arith.`
`Coq` `<``Theorem one_two_irred: (x,y,z:nat)(mult x y)=(1)/\(mult x z)=(2)-``>``x=(1).`
...
`Coq` `<``Qed.`
`Coq` `<``Definition half := (mkRat true (1) (2) (O_S (1)) one_two_irred).`
`half is defined`
`Coq` `<``Check half.`
`half`
`: Rat`
The macro generates also, when it is possible, the projection functions for destructuring an object of type ident. These projection functions have the same name that the corresponding fields. If a field is named ```_`'' then no projection is built for this (anonymous) field. In our example:
`Coq` `<``Eval Compute in (top half).`
`= (1)`
`: nat`
`Coq` `<``Eval Compute in (bottom half).`
`= (2)`
`: nat`
`Coq` `<``Eval Compute in (Rat_bottom_cond half).`
`= (O_S (1))`
`: ~(0)=(bottom half)`
Warnings:

1. `Warning:` ident`i``cannot be defined.`
   It can happens that the definition of a projection is impossible. This message is followed by an explanation of this impossibility. There may be three reasons:
   1. The name identi already exists in the environment (see section 1.3.1).
   2. The body of identi uses a incorrect elimination for ident (see sections 1.3.4 and 4.5.4).
   3. `The projections [` idents`] were not defined.`
      The body of termi uses the projections idents which are not defined for one of these three reasons listed here.

Error messages:

1. `A record cannot be recursive`
   The record name ident appears in the type of its fields.
2. During the definition of the one-constructor inductive definition, all the errors of inductive definitions, as described in section 1.3.3, may also occur.

See also: Coercions and records in section 14.9 of the chapter devoted to coercions.