Procedures and Functions

Declare and call procedures (actions) and functions (value-returning), understand subprogram specifications and bodies, return statements, expression functions, local subprograms, and why Ada separates the two kinds of subprograms.

Ada has two kinds of subprograms: procedures, which perform actions and are called as statements, and functions, which compute a value and are called inside expressions. The distinction is enforced — you cannot call a function as a statement and ignore its result, and a procedure cannot be used in an expression — which makes side effects and results explicit.

Procedures

A procedure has a specification 'procedure Print_Line (Width : Positive)' and a body 'is ... begin ... end Print_Line;'. It is called as a statement: Print_Line (20);. A procedure with no parameters is called by name alone: New_Line;. A procedure may use 'return;' to leave early. Subprograms can be declared inside other subprograms (local subprograms), where they can use the enclosing subprogram's variables.

• procedure P (Params) is ... begin ... end P; — called as a statement. • Parameterless call: P; (no empty parentheses). • return; exits early; subprograms can be nested.

Functions

A function specifies a result type: 'function Square (X : Integer) return Integer'. Every path through the body must end in 'return Expression;' — falling off the end raises Program_Error (and GNAT warns at compile time). Functions are called in expressions: Y := Square (12);. Discarding a function result is not allowed. Function parameters were traditionally 'in' only; since Ada 2012 functions may also have 'out' and 'in out' parameters, though pure functions without side effects remain best practice.

An expression function (Ada 2012) is a function whose body is a single parenthesized expression: 'function Is_Even (N : Integer) return Boolean is (N mod 2 = 0);'. Expression functions are concise, can appear in package specifications, and are often used for simple queries and in contracts.

• function F (Params) return T is ... begin ... return Value; end F; • Must return on every path; result cannot be ignored. • Expression function: function F (...) return T is (Expression); • Prefer side-effect-free functions.

Specifications, Bodies and Declarations Order

A subprogram must be declared before it is used. You can separate its declaration (the specification followed by ';') from its body, e.g. in a package spec, or as a forward declaration to allow mutual recursion. The body repeats the specification exactly and adds 'is ... begin ... end'. This separation is the foundation of Ada's packages: clients see only the specification.

• Declaration: procedure P (X : Integer); Body: procedure P (X : Integer) is ... end P; • Declare before use; forward declarations enable mutual recursion.

Code Examples

Print_Line builds a String with an array aggregate [1 .. Width => '-']. Square and Max_Of_Three are functions; Is_Even is an expression function. Output: -------------------- Square (12) = 144 Max (4, 19, 7) = 19 Is_Even (10) = TRUE Square (Square (3))= 81 --------------------

Square (5); -- calling a function as a statement Result:= Square (5);

A function call is an expression; its result must be used.

function Sign (X : Integer) return Integer is begin if X > 0 then return 1; end if; if X < 0 then return -1; end if; end Sign;

function Sign (X : Integer) return Integer is begin if X > 0 then return 1; elsif X < 0 then return -1; else return 0; end if; end Sign;

Falling off the end of a function raises Program_Error; ensure every path returns.

Print_Line ();

Print_Line; -- when it has no parameters Ada does not use empty parentheses for parameterless calls.

Which subprogram kind returns a value? A. Procedure B. Function C. Both D. Task

What happens if a function reaches its end without a return statement? A. Returns 0 B. Program_Error is raised C. Returns garbage D. Returns null

B. Program_Error (and GNAT warns at compile time).

Which is an expression function? A. function F return Integer; B. function F (X : Integer) return Integer is (X + 1); C. procedure F is null; D. F := X + 1;

B. A function whose body is a parenthesized expression.

How do you call a parameterless procedure Reset? A. Reset(); B. Reset; C. call Reset; D. Reset (null);

Write a function Is_Prime (N : Positive) return Boolean.

function Is_Prime (N : Positive) return Boolean is begin if N < 2 then return False; end if; for D in 2 .. N loop exit when D * D > N; if N mod D = 0 then return False; end if; end loop; return True; end Is_Prime;

Trial division up to the square root; the exit when avoids needing a square-root function. Every path ends in a return.

with Ada.Text_IO; use Ada.Text_IO;

procedure L14_Subprograms is

   --  A procedure performs an action; it does not return a value.
   procedure Print_Line (Width : Positive) is
   begin
      Put_Line ([1 .. Width => '-']);
   end Print_Line;

   --  A function computes and returns a value.
   function Square (X : Integer) return Integer is
   begin
      return X * X;
   end Square;

   function Max_Of_Three (A, B, C : Integer) return Integer is
      Result : Integer := A;
   begin
      if B > Result then
         Result := B;
      end if;
      if C > Result then
         Result := C;
      end if;
      return Result;
   end Max_Of_Three;

   function Is_Even (N : Integer) return Boolean is (N mod 2 = 0);   --  expression function
begin
   Print_Line (20);
   Put_Line ("Square (12)       =" & Integer'Image (Square (12)));
   Put_Line ("Max (4, 19, 7)    =" & Integer'Image (Max_Of_Three (4, 19, 7)));
   Put_Line ("Is_Even (10)      = " & Boolean'Image (Is_Even (10)));
   Put_Line ("Square (Square (3))=" & Integer'Image (Square (Square (3))));
   Print_Line (20);
end L14_Subprograms;