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;