Idioms, Style & Common Compiler Errors

Write idiomatic Ada (distinct types, enumerations with exhaustive case, unconstrained results, named parameters, declare-block constants, 'Image trimming), follow style conventions (Mixed_Case identifiers, GNAT -gnaty checks), and decode the most common GNAT errors: missing semicolons, = vs :=, mismatched end names, mixed types, missing case values, undefined names and visibility.

Ada rewards a particular style: model the problem with types, let the compiler check coverage, and prefer expressions and constants over mutable buffers. Newcomers from C-family languages often trip on the same handful of compiler messages; learning to read them quickly makes Ada feel far less strict.

Idiomatic Ada

Create a distinct type for each concept (type Meters is new Float) and subtypes for constraints (Percent). Model states with enumerations and handle them with case statements without 'others', so new literals are found by the compiler. Return String results instead of filling caller buffers. Use named parameters for Booleans and defaults for rarely changed settings. Compute text in declare blocks as constants. Keep helper functions such as Img that trim 'Image. Prefer 'for X of Container' loops, 'Range, and expression functions. Style: Mixed_Case_With_Underscores identifiers, lower-case reserved words, 3-space indentation; GNAT checks these with -gnaty (e.g. -gnaty3abcefhiklmnprst) and GNATformat/gnatpp reformat code.

Several idioms in one program. Output: RED GREEN AMBER RED Img (42) = [42], Repeat = ababab [50%] started [90%] almost done Distance * 2.0 = 2.50000E+01 Report for 2024 (15 chars)

• Types per concept; subtypes for ranges; enumerations + full case. • Return unconstrained results; constants from expressions. • Named parameters; 'for ... of'; expression functions. • Style: Mixed_Case, -gnaty checks, gnatformat.

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Strings.Fixed;

procedure L66_Idioms is
   --  Idiom 1: a distinct type per concept, subtypes for constraints
   type Meters is new Float;
   subtype Percent is Integer range 0 .. 100;

   --  Idiom 2: enumeration + exhaustive case instead of magic numbers
   type Light is (Red, Amber, Green);
   function Next (L : Light) return Light is
     (case L is when Red => Green, when Green => Amber, when Amber => Red);

   --  Idiom 3: 'Image cleanup helper (no leading space)
   function Img (N : Integer) return String is
     (Ada.Strings.Fixed.Trim (Integer'Image (N), Ada.Strings.Left));

   --  Idiom 4: return unconstrained results instead of fixed buffers
   function Repeat (S : String; N : Natural) return String is
     (if N = 0 then "" else S & Repeat (S, N - 1));

   --  Idiom 5: named parameters and defaults for readable calls
   procedure Log (Msg : String; Level : Percent := 50; Newline : Boolean := True) is
   begin
      Put ("[" & Img (Level) & "%] " & Msg);
      if Newline then
         New_Line;
      end if;
   end Log;

   L : Light := Red;
   Distance : constant Meters := 12.5;
begin
   for I in 1 .. 4 loop
      Put (Light'I
…

Syntax Errors

The most frequent beginner errors: a missing semicolon after a declaration, '=' where assignment ':=' was meant, and an 'end' name that does not match the unit. GNAT's messages are precise and often suggest the fix.

Three typos. Real GNAT diagnostics: l66_err.adb:4:24: error: missing ";" l66_err.adb:8:13: error: "=" should be ":=" l66_err.adb:11:05: error: misspelling of "L66_Err" The compiler stops at syntax errors, so the type error in Put_Line ("Total: " & Total) is only reported after they are fixed; you'd need Integer'Image (Total).

• missing ";" — end every declaration and statement with ; • "=" should be ":=" — = compares, := assigns. • misspelling of "Name" — end must repeat the unit name.

with Ada.Text_IO; use Ada.Text_IO;

procedure L66_Err is
   Count : Integer := 0
   Total : Integer := 10;
begin
   if Count = 0 then
      Count = 1;
   end if;
   Put_Line ("Total: " & Total);
end L66_Errr;

Semantic Errors

After parsing, GNAT checks types, coverage and names: mixing Integer and Float needs an explicit conversion (Float (X) * Y); case statements must cover every value; every name must be declared and visible (a missing 'with' or 'use' clause gives '"Put_Line" is undefined' plus a hint). Other common ones: 'expected type X, found type Y' (distinct types), 'actual for "T" must be a definite subtype' (generics), 'ambiguous operands' (qualify literals), 'is not visible — multiple use clauses cause hiding' (use expanded names), and 'cannot assign to in mode parameter'.

Type mixing, a missing case value and an undefined name. Real GNAT diagnostics: l66_err2.adb:7:11: error: invalid operand types for operator "*" l66_err2.adb:7:11: error: left operand has type "Standard.Integer" l66_err2.adb:7:11: error: right operand has type "Standard.Float" l66_err2.adb:8:04: error: missing case value: "Tue" l66_err2.adb:11:04: error: "Undefined_Proc" is undefined

• invalid operand types → convert explicitly: Float (X) * Y. • missing case value → add it (or others). • "X" is undefined → declare it or add with/use. • not visible / hiding → use an expanded name Pkg.X.

Put_Line ("Total: " & Total); -- Total: Integer Put_Line ("Total: " & Integer'Image (Total));

& concatenates strings; convert numbers to text explicitly.

if X = 1 then Count = Count + 1; end if;

if X = 1 then Count := Count + 1; end if;

Assignment is :=.

Y:= X * Y; -- X: Integer, Y: Float Y:= Float (X) * Y;

Ada has no implicit numeric conversions.

What does GNAT report for 'Count = 1;' as a statement? A. missing ; B. "=" should be ":=" C. type mismatch D. undefined Count

How do you multiply Integer X by Float Y? A. X * Y B. Float (X) * Y C. X *. Y D. (float) X * Y

Which switch enables GNAT style checks? A. -gnatwa B. -gnaty C. -gnata D. -gnatp

What does 'misspelling of "L66_Err"' at the last line mean? A. Spell-check of comments B. The end name doesn't match the unit name C. File name wrong D. Undefined procedure Fix all errors in this program.

Add ';' after 'Count : Integer := 0', change 'Count = 1;' to 'Count := 1;', end with 'end L66_Err;', and write Put_Line ("Total:" & Integer'Image (Total)). Real diagnostics before fixing: l66_err.adb:4:24: error: missing ";" l66_err.adb:8:13: error: "=" should be ":=" l66_err.adb:11:05: error: misspelling of "L66_Err"

procedure L66_Err2 is
   X : Integer := 5;
   Y : Float := 2.0;
   type Day is (Mon, Tue);
   D : Day := Mon;
begin
   Y := X * Y;                    --  mixing Integer and Float
   case D is
      when Mon => null;
   end case;                      --  Tue not covered
   Undefined_Proc;
end L66_Err2;
with Ada.Text_IO; use Ada.Text_IO;

procedure L66_Err is
   Count : Integer := 0
   Total : Integer := 10;
begin
   if Count = 0 then
      Count = 1;
   end if;
   Put_Line ("Total: " & Total);
end L66_Errr;