Ada: Records
A record groups named fields of different types under one name — the "struct" of the C family, but with variants, discriminants, and default values. Records are the foundation of all data modeling in Ada, and every later lesson (OOP especially) builds on them.
Basic Records
with Ada.Text_IO; use Ada.Text_IO;
procedure Record_Demo is
type Point is record
X, Y : Float := 0.0; -- a default applies to every new object
end record;
type Player is record
Name : String (1 .. 20);
Score : Natural;
Pos : Point; -- nested record — records compose freely
end record;
P : Player := (Name => "alice ", Score => 10, Pos => (others => <>));
begin
P.Score := P.Score + 5; -- dot notation, nested naturally
P.Pos.X := 1.5;
Put_Line (Natural'Image (P.Score)); -- 15
end Record_Demo;
Records assign as whole values: Q := P; copies every field. Equality (=, /=) compares every field. Records are never compared through their bytes, so padding garbage cannot create false inequality.
Variant Records and Discriminants
Ada's variant record is a checked union: a discriminant records which variant is active, and the compiler rejects access to fields of the wrong variant. The diagram shows how one type holds several layouts safely:
procedure Variant_Demo is
type Shape_Kind is (Circle, Rectangle);
type Shape (Kind : Shape_Kind := Circle) is record
X, Y : Float;
case Kind is
when Circle =>
Radius : Float;
when Rectangle =>
Width, Height : Float;
end case;
end record;
C : Shape; -- Kind defaults to Circle
R : Shape (Kind => Rectangle); -- fixed variant, Rectangle fields legal
begin
C.Radius := 2.0; -- OK: C's variant is Circle
-- R.Radius := 2.0; -- compile error: R is a Rectangle
null;
end Variant_Demo;
The variant record replaces a C union + tag enum pair with one construct where the pairing of tag and data is enforced by the type system — the "tagged union" done right.
Defaults and Initialization
Field defaults apply to every declaration; aggregates override selectively. Use others => <> to say "leave the rest at their defaults":
procedure Defaults_Demo is
type Config is record
Retries : Natural := 3;
Timeout : Float := 1.5;
Verbose : Boolean := False;
end record;
Fast : Config := (Timeout => 0.2, others => <>); -- override one, keep rest
begin
null; -- Fast.Retries = 3, Fast.Timeout = 0.2, Fast.Verbose = False
end Defaults_Demo;
Representation Clauses
For device drivers and binary formats, specify the exact layout with representation clauses — the record becomes a typed window onto hardware:
procedure Hardware_Demo is
type Register is record
Enable : Boolean;
Mode : Natural range 0 .. 3;
Unused : Natural range 0 .. 2 ** 6 - 1;
end record;
for Register use record -- byte layout, bit by bit
Enable at 0 range 0 .. 0;
Mode at 0 range 1 .. 2;
Unused at 0 range 3 .. 8;
end record;
begin
null; -- reading/writing a Register object now maps the hardware byte
end Hardware_Demo;
Next: Access Types — how Ada handles references safely.