Ada: Conditionals

Ada offers two selection constructs: if/elsif/else for arbitrary conditions, and case for selecting on the value of an expression. Both are closed by a keyword (end if, end case), so nesting is unambiguous, and both have checks no C-family compiler performs.

The if Statement

The condition must be a genuine Boolean — integers are not accepted, so the "truthiness" bug class does not exist:

with Ada.Text_IO; use Ada.Text_IO;

procedure If_Demo is
   Speed : constant Integer := 95;
begin
   if Speed > 120 then              -- condition is always Boolean
      Put_Line ("overspeeding");
   elsif Speed > 90 then            -- note: elsif, one word
      Put_Line ("approaching the limit");
   else
      Put_Line ("cruising");
   end if;                          -- closed — no dangling else
end If_Demo;

Because Speed > 120 is a Boolean expression, if Speed then — the C idiom for "if nonzero" — is a compile error. Write what you mean: if Speed /= 0 then.

The case Statement

case selects by value. Its distinguishing rule: every possible value of the selector must be covered, either by explicit alternatives or by when others =>. The compiler rejects an incomplete case — adding a new literal to an enumeration later forces you to revisit every case that uses it:

with Ada.Text_IO; use Ada.Text_IO;

procedure Case_Demo is
   type Mode is (Off, Standby, Active, Fault);

   M : constant Mode := Standby;
begin
   case M is
      when Off =>               Put_Line ("system down");
      when Standby =>           Put_Line ("warm, waiting");
      when Active =>            Put_Line ("fully operational");
      when Fault =>             Put_Line ("diagnostics required");
      --  no "when others" needed: all four literals are covered
   end case;
end Case_Demo;

Alternatives may list several values (when 1 | 2 =>) or a range (when 3 .. 5 =>). case works on any discrete type — integers, enumerations, characters:

   --  grouping and ranges in one statement:
   --  case Digit is
   --     when 0 | Odd_Digit_Range ...   -- see lab demo for a full example
   --  end case;

Expressions vs Statements

Ada keeps conditional expressions (usable inside a declaration or initialization) separate from conditional statements. The expression form, added in Ada 2012, reads like the statement but omits the keywords:

procedure Expression_Demo is
   Temp : constant Integer := 35;
   Level : constant String :=
     (if Temp > 30 then "high" else "normal");   -- conditional expression
begin
   null;
end Expression_Demo;

A conditional expression must produce a value on every branch — Ada will not invent a default. That same totality rule is why there is no ternary operator ambiguity: (if C then A else B) is parenthesized and typed.

Truth and Logic

Booleans are a plain enumeration type ((False, True)), so everything from the Expressions lesson applies: and, or, not are per-type operators; and then / or else short-circuit; precedence binds not, then and, then or. Prefer the short-circuit forms by default:

   --  safe: if List is empty, List (I) is never evaluated
   --  if I <= List'Last and then List (I) /= Expected then

   --  UNSAFE in Ada too: "and" evaluates BOTH sides, so a bad index
   --  would still raise Constraint_Error when List is empty

Next: Loops.