Blocks, declare, Quantified, Declare & Reduction Expressions

Introduce local declarations with declare blocks, understand scope, visibility and hiding, use the null statement, write quantified expressions (for all / for some), and use the Ada 2022 declare expressions and 'Reduce reduction expressions.

Ada separates declarations from statements, so how do you create a temporary variable in the middle of a sequence of statements? With a block statement: declare ... begin ... end. Blocks also give you a local exception handler and a clear lifetime for their variables. This lesson also covers the expression-level tools that express 'every element satisfies', 'some element satisfies', and 'combine all elements' concisely.

Block Statements and Scope

'declare <declarations> begin <statements> [exception <handlers>] end;' is a statement that can appear anywhere statements are allowed. Its declarations exist only while the block runs; memory for them is reclaimed when it ends. A declaration in an inner scope hides one with the same name in an outer scope; the outer one can still be reached with an expanded name such as Procedure_Name.X. Blocks can be named like loops. Blocks are also the standard way to handle an exception locally and continue.

• declare ... begin ... [exception ...] end; — local declarations mid-sequence. • Inner declarations hide outer ones; use Outer_Unit.Name to reach them. • Blocks limit lifetime and allow local exception handling. • null; is the do-nothing statement where a statement is required.

Quantified Expressions

'(for all V of Data => V > 0)' is True if the predicate holds for every element; '(for some V of Data => V > 40)' is True if at least one element satisfies it. They can iterate over index ranges too: (for all I in A'First .. A'Last - 1 => A (I) <= A (I + 1)) checks that an array is sorted. Quantified expressions are essential in contracts (Pre/Post and predicates) because they state properties declaratively.

• (for all X of C => P (X)) — universal; (for some X of C => P (X)) — existential. • Can range over indices: (for all I in R => ...). • Ideal for contracts and assertions.

Declare and Reduction Expressions (Ada 2022)

A declare expression '(declare Name : constant T := ...; begin Expression)' introduces constants that are only used inside one expression — perfect for readable postconditions and expression functions. A reduction expression 'A'Reduce ("+", 0)' combines all elements of an array or iterable with an operation and an initial value; value sequences such as [for I in 1 .. 10 => I * I]'Reduce ("+", 0) generate and reduce in one expression.

• (declare C : constant T := E; begin Expr) — local constants in expressions. • X'Reduce (Op, Initial) — fold elements into one value. • [for I in R => F (I)]'Reduce ("+", 0) — generate then reduce.

Code Examples

The block's X hides the outer X; L13_Blocks.X reaches the outer one. Quantified expressions test all/some elements and sortedness; a declare expression computes an average of the first three values (4 + 8 + 15 = 27, / 3 = 9); 'Reduce sums the whole array. Output: Sum = 108, inner X = 100 Outer X via expanded name = 1 All positive? TRUE Some > 40? TRUE Sorted? TRUE Average = 9 Sum via 'Reduce = 108 begin Put_Line ("start"); Temp: Integer:= 5; -- illegal here begin Put_Line ("start"); declare Temp: Integer:= 5; begin... end;

Declarations among statements require a declare block.

if Count > 0 then end if; -- empty branch if Count > 0 then null; end if;

A sequence of statements cannot be empty; write null; explicitly (and question why the branch exists).

Ok := for all V of Data => V > 0;

Ok := (for all V of Data => V > 0);

Quantified expressions must be parenthesized.

What does '(for some X of A => X = 0)' return? A. True if every element is 0 B. True if at least one element is 0 C. The index of 0 D. A count B. True if at least one element is 0.

How do you declare a temporary variable in the middle of a statement sequence? A. Just declare it B. With a declare block C. With var D. Impossible B. With a declare block.

What does Data'Reduce ("+", 0) compute? A. The number of elements B. The sum of the elements C. The maximum D. Nothing, it is illegal B. The sum, starting from 0.

How can you refer to an outer X hidden by an inner X in procedure P? A.::X B. outer.X C. P.X D. You cannot C. P.X — an expanded name.

Trace the block and quantified-expression example.

Real output: Sum = 108, inner X = 100 Outer X via expanded name = 1 All positive? TRUE Some > 40? TRUE Sorted? TRUE Average = 9 Sum via 'Reduce = 108

with Ada.Text_IO; use Ada.Text_IO;

procedure L13_Blocks is
   Data : constant array (1 .. 6) of Integer := [4, 8, 15, 16, 23, 42];
   X    : constant Integer := 1;
begin
   --  A declare block introduces declarations in the middle of statements.
   declare
      Sum : Integer := 0;
      X   : constant Integer := 100;   --  hides the outer X inside this block
   begin
      for V of Data loop
         Sum := Sum + V;
      end loop;
      Put_Line ("Sum =" & Integer'Image (Sum) & ", inner X =" & Integer'Image (X));
      Put_Line ("Outer X via expanded name =" & Integer'Image (L13_Blocks.X));
   end;

   --  Quantified expressions (Ada 2012)
   Put_Line ("All positive?  " & Boolean'Image (for all V of Data => V > 0));
   Put_Line ("Some > 40?     " & Boolean'Image (for some V of Data => V > 40));
   Put_Line ("Sorted?        " &
             Boolean'Image (for all I in Data'First .. Data'Last - 1 => Data (I) <= Data (I + 1)));

   --  Declare expression (Ada 2022)
   Put_Line ("Average =" & Integer'Image
     (declare
        Total : constant Integer := Data (1) + Data (2) + Data (3);
      begin
        Total / 3));

   --  Reduction expression (Ada 2022)
   Put_Line ("Sum via 'R
…