If, Case, Conditional and Case Expressions

Write if / elsif / else statements, exhaustive case statements with ranges, choice lists and others, and the Ada 2012 conditional (if) and case expressions that select values inside expressions.

Decisions in Ada use two statements — if and case — and two matching expression forms. The case statement is especially powerful because the compiler checks that every possible value of the selector is handled exactly once, turning a forgotten case into a compile-time error rather than a production bug.

if / elsif / else

The form is 'if Condition then ... elsif Condition then ... else ... end if;'. Conditions must be Boolean. There is no dangling-else problem because every if ends with 'end if'. Use elsif (one word) for chains; nest ifs only when the logic is genuinely nested.

• if ... then ... elsif ... then ... else ... end if; • Conditions must be Boolean — no integer truthiness. • 'elsif' is one word; every if closes with 'end if'.

case Statements

'case Selector is when Choice => statements; ... end case;' requires a discrete selector (integer, enumeration, character). Choices may be single values, ranges (Mon .. Fri), lists (Sat | Sun) or 'others'. The rules are strict: every value of the selector's subtype must be covered exactly once, choices must be static, and there is no fall-through between alternatives. If the selector is a variable of a large type like Integer, you usually need 'when others'.

Because coverage is checked, avoid 'when others' for enumerations when you can list every value: then adding a new enumeration literal makes every incomplete case statement fail to compile, pointing you to each place that must handle it.

• Selector must be discrete; choices must be static. • Choices: value, range, list (A | B), others. • Full coverage required, no overlaps, no fall-through. • Prefer explicit enumeration coverage over 'others' for maintainability.

Conditional and Case Expressions

Ada 2012 added expression forms that yield a value: '(if Temperature > 30 then "hot" else "mild")' and '(case D is when Sat | Sun => "free", when others => "busy")'. They must be enclosed in parentheses (unless they are the sole argument of a call). Every branch yields a value of the same type; for Boolean if-expressions the else part may be omitted (it defaults to True), which is useful in contracts.

• (if C then A elsif D then B else E) — value-producing conditional. • (case X is when ... => V1, when others => V2) — alternatives separated by commas. • Parentheses required; all branches same type.

Code Examples

Grade uses an if/elsif chain; Describe uses a case over an enumeration with a range and a choice list (no 'others' needed — all seven days are covered). The final loop shows a case over Integer that needs 'when others'. Output: Grade (95) = A, Grade (72) = C WED: work day SUN: weekend Weather: hot Wed is busy 1: start 2: running 3: running 4: stop case Code is when 1 =>... when 2 =>... end case; -- Code: Integer case Code is when 1 =>... when 2 =>... when others => null; end case;

All Integer values must be covered; add 'when others' (with null if nothing should happen).

else if X > 0 then elsif X > 0 then 'else if' opens a new nested if requiring its own 'end if'; use elsif for chains.

Label := if Ok then "yes" else "no";

Label := (if Ok then "yes" else "no");

Conditional expressions must be parenthesized.

What happens if a case statement over an enumeration omits one value and has no 'others'? A. Runtime error B. The missing value is ignored C. Compile error D. Falls through to the next case

C. Compile error — case statements must cover every value.

Does Ada's case statement fall through to the next alternative? A. Yes, like C B. No, never C. Only without break D. Only for ranges

B. No — each alternative is independent; there is no break keyword.

Which is a legal conditional expression? A. X := if A then 1 else 2; B. X := (if A then 1 else 2); C. X := A ? 1 : 2; D. X := iif (A, 1, 2);

B. Parentheses are required.

Which type cannot be a case selector? A. Integer B. Character C. Float D. An enumeration

C. Float — case selectors must be discrete.

Write a function Days_In_Month (Month : Positive; Leap : Boolean) return Positive using a case statement.

function Days_In_Month (Month : Positive; Leap : Boolean) return Positive is begin case Month is when 2 => return (if Leap then 29 else 28); when 4 | 6 | 9 | 11 => return 30; when others => return 31; end case; end Days_In_Month;

A choice list groups the 30-day months, a conditional expression handles February, and 'others' covers the 31-day months (a Month outside 1 .. 12 would need a subtype such as Month_Number to reject it).

with Ada.Text_IO; use Ada.Text_IO;

procedure L11_If_Case is
   type Day is (Mon, Tue, Wed, Thu, Fri, Sat, Sun);

   function Grade (Score : Natural) return Character is
   begin
      if Score >= 90 then
         return 'A';
      elsif Score >= 80 then
         return 'B';
      elsif Score >= 70 then
         return 'C';
      else
         return 'F';
      end if;
   end Grade;

   procedure Describe (D : Day) is
   begin
      case D is
         when Mon .. Fri => Put_Line (Day'Image (D) & ": work day");
         when Sat | Sun  => Put_Line (Day'Image (D) & ": weekend");
      end case;
   end Describe;

   Temperature : constant Integer := 31;
begin
   Put_Line ("Grade (95) = " & Grade (95) & ",  Grade (72) = " & Grade (72));
   Describe (Wed);
   Describe (Sun);
   --  Conditional expression (like a ternary operator):
   Put_Line ("Weather: " & (if Temperature > 30 then "hot" else "mild"));
   --  Case expression:
   Put_Line ("Wed is " & (case Wed is when Sat | Sun => "free", when others => "busy"));
   for Code in 1 .. 4 loop
      case Code is
         when 1      => Put_Line ("1: start");
         when 2 | 3  => Put_Line (Integer'Image (Code) & ": running");
         wh
…