2.4 Procedures

[ Table of Contents ] Prev ] Chapter Overview ] Next ] [ Glossary/Index ]

The following table depicts the general form of a procedure. Note that four reserved words (procedure, is, begin, end) are always included. Every procedure has a name and a sequence of executable statements, known as its executable part. There may also be an exception handling part preceded by the reserved word exception.

General form
of a procedure body

procedure Procedure_Name(formal parameters)is
  -- declarative part (optional)
  -- executable part (normal action)
exception  -- (optional)
  -- exception handling actions  -- (optional)
end Procedure_Name;

Example Program with Two Procedures

Im2-4.gif (2647 bytes)

This diagram depicts the architecture of the program listed below. The main (test) procedure depends on the Show_Birthday_Song procedure, which depends on a package from the predefined environment. All three modules are library units.

The dashed green arrows represent the with clauses, as in the previous examples, and you can click any green element in the diagram to jump to the corresponding line of code.

The upper part of the next table contains the example procedure named Show_Birthday_Song. It has two formal parameters, First_Name and Last_Name. The Show_Birthday_Song procedure can be compiled as it stands, but it can be run only if it is called with appropriate actual parameters. So a second example procedure called Test_Show_Birthday_Song is provided. Test_Show_Birthday_Song declares two strings representing first (given) and last (sur) names, and calls Show_Birthday_Song with the two strings as actual parameters.

Example procedure body preceded by two context clauses

with Ada.Text_IO;
use  Ada.Text_IO;
procedure Show_Birthday_Song(First_Name : in String;
                             Last_Name  : in String) is

  Str1 : constant String := "Happy birthday ";
  Str2 : constant String := "to you.";


  Put_Line(Str1 & Str2);
  Put_Line(Str1 & Str2); 
  Put_Line(Str1 & First_Name & " " & Last_Name & ".");
  Put_Line(Str1 & Str2);

end Show_Birthday_Song;

which calls the first example

with Show_Birthday_Song;
procedure Test_Show_Birthday_Song is

  Given_Name : constant String := "Ada";
  Sur_Name   : constant String := "Lovelace";


  Show_Birthday_Song(Given_Name, Sur_Name);

end Test_Show_Birthday_Song;

If you compile, link and run the above two procedures, using Test_Show_Birthday_Song as the main procedure, the program should display the following lines of text:

     Happy birthday to you.
     Happy birthday to you.
     Happy birthday Ada Lovelace.
     Happy birthday to you.

This would be appropriate on December 10th, since Augusta Ada Byron was born on the 10th of December in 1815, the daughter of Lord Byron, the poet. (See A Brief History of Ada, in Chapter 1.) You can, of course, change the two string declarations in the second example procedure to whatever first and last names you like.

Notes about the general  form and the examples:

As indicated above, there are two optional parts of a procedure body: the declarative part and the exception handling part. Both of the examples include a declarative part, while neither includes an exception handler. (Examples of exception handling code appear in the next chapter.)

It is mandatory that every procedure body start with the reserved word procedure followed by the name of the procedure. It is also mandatory that every procedure body include an executable part starting with the word begin, ending with end; (or "end Procedure_Name;") and containing at least one executable statement between them. The second procedure has only one such statement: a call to the first procedure.

Parameters are not mandatory. The first example has two formal parameters; the second example (which becomes the main procedure) has none. The two formal parameters are both of mode in. Thus, they are treated as constants that cannot be changed during the execution of the procedure.

Parameter Profiles and Default Values

The parenthesized list (First_Name : in String; Last_Name : in String) defines the parameter profile of the procedure Show_Birthday_Song. Note that each formal parameter has a name, a mode, and a type. The three possible modes are: in, in out, and out.

A formal parameter of mode in may be declared with a  default value that will be applied whenever no actual parameter value is given in a procedure call. For example, if the string "Lovelace" were to be used as the default value for the second parameter in the above example, the proper syntax of the parameter profile would be: (First_Name : in String; Last_Name : in String := "Lovelace").

Possible Confusion: procedure body vs procedure

You may be confused by the fact that we have sometimes, in the above material, referred to a procedure and other times referred to a procedure body, without distinguishing between the two terms. Here is an explanation.

There are two ways to create a subprogram (procedure or function), which we will refer to as the "one-step way" and the "two-step way." So far, you have seen only the one-step way, where the entire procedure (called the procedure body) is created in a single sequence of statements, as illustrated in both examples above. The two-step way involves, first, creation of a procedure declaration in a single statement appearing as part of a package declaration, and second, creation of the entire procedure body as part of the package body. ( The last type of nesting, illustrated graphically in the previous section, depicted this kind of two-step creation of a procedure. Coded examples appear later in this chapter.)

The other kinds of modules (packages, tasking units, protected units, and protected entries) are always created in two steps, with separate declarations and bodies, and the bodies are clearly labeled as such in the code -- using the reserved word body.

Recursive Subprograms

Ada supports recursion. That is, a subprogram (procedure or function) can call a replica of itself.

Related Topics

2.2 Program Units 3.2 Procedure Calls

[ Back to top of pagePrev ] Next ]