We can distinguish four levels of programme hierarchy:
The distinction between a procedure and a function is that a function returns a value while a procedure does not.
A procedure or function comprises a head and a body. In the head the name of the routine and its formal parameters are specified. The code is defined in the body. In addition, in the case of a function, the function declaration must include a definition for its return value.
The format for declaring a procedure is as follows:
procedure NAME `(' <ARGUMENTS> `)' is begin <BODY> end NAME `;'
While that for a function declaration is:
function NAME `(' <ARGUMENTS> `)' return T is begin <BODY> end NAME `;'
where T is the type of the data item to be returned. Note also that a procedure (function) does not have to have any arguments. Further discussion concerning formal parameters for procedures and functions will be presented later.
Functions and procedures are activated by a procedure or function call (routine invocation) which names the routine and supplies the actual parameters. Note that after invocation control is returned to the point immediately after the invocation as illustrated in the following diagram.
One of the most important issues that has to be addressed in the design of a programming language is the support it gives to the control of complexity. An important technique is the division of a program into "chunks" called routines (or sub-programs) that will allow the programmer to think at a more abstract level. At its simplest a routine may comprises a single procedure or function (i.e a routine can be equivalent to a block). More often it comprises a group of (in Ada nested) procedures and/or functions invoked through routine invocation.
By adopting a top-down hierarchical decomposition to problem analysis and design we can identify the routines we require.
A number of declarations of types, variables and sub-routines can be
grouped together into a module or package
(also sometimes referred to as a task). The concept of modules (and modular programming)
appeared in
1970's in response to the increasing size of programs. The use of modules provides convenient access
to existing resources, and consequently results in more time efficient programming. Modules comprise a
specification part and a body part. The specification part contains a
description of the interface and the body the code that implements the
interface. The specification part is accessible to the user, the implementation
part is "hidden" (information hiding).
The highest level of program hierarchy is the program.
Ada assumes that there exists a method outside the language which allows the programmer to specify the name of a procedure and which will then construct an executable binary program for that procedure containing all the necessary modules.
To write the word "Ada" vertically down the screen using giant letters made up of strings of * (asterisk) characters and blank spaces as follows:
Using a top-down hierarchical decomposition approach we can identify the following break-down of operations:
Note that the "Draw giant letter A" operation is repeated twice. Therefore we only need three procedures as follows:
The design detail required for each of these procedures is given by the Nassi-Shneiderman charts given below. Note how routine invocation is indicated in the top level chart using the routine name surrounded by an ellipse.
To implement a top down design comprising more than one level we commence by encoding the top level first, testing this, and then implementing the lower levels, level by level, testing each level of implementation as it is completed. Where necessary lower level procedures can be indicated using "stubs". Thus, in this case, implementation will commence by writing a top-level procedure as follows:
-- GIANT ADA -- 9 August 1997 -- Frans Coenen -- Dept Computer Science, University of Liverpool with CS_IO; use CS_IO; procedure GIANT_ADA is ------------------------------------------- -- GIANT LETTER A PROCEDURE procedure GIANT_A is begin PUT_LINE("GIANT_A"); end GIANT_A; ------------------------------------------- -- GIANT LETTER D PROCEDURE procedure GIANT_D is begin PUT_LINE("GIANT_D"); end GIANT_D; ------------------------------------------- -- TOP LEVEL PROCEDURE begin GIANT_A; GIANT_D; GIANT_A; end GIANT_ADA;
Inspection of the above code indicates the nesting illustrated to the right. Note the ordering of the procedure declarations - this governs the visibility of procedures (i.e. which procedure can be used by which other procedure). For example in the above case the GIANT_D procedure is not visible form the GIANT_A procedures although the GIANT_A procedure is visible from the GIANT_D procedure. This is a direct consequence of the ordering in which these procedures are declared. Note also that it is considered good programming practice to demarcate procedures using (say) a dashed line and to introduce each procedure with a short comment. This is intended to enhance clarity and hence readability. On completion of this first level in the top-down design the code written so far should be tested. In this case a single execution of the program so far will suffice. We would expect the output to be as follows:
GIANT_A GIANT_D GIANT_A
The second level in the top-down design can now be encoded as follows:
-- GIANT ADA -- 9 August 1997 -- Frans Coenen -- Dept Computer Science, University of Liverpool with CS_IO; use CS_IO; procedure GIANT_ADA is ----------------------------------------------------- -- GIANT LETTER A PROCEDURE procedure GIANT_A is begin PUT_LINE(" *"); PUT_LINE(" * *"); PUT_LINE(" * *"); PUT_LINE(" * *"); PUT_LINE(" *********"); PUT_LINE(" * *"); PUT_LINE("* *"); NEW_LINE; end GIANT_A; ----------------------------------------------------- -- GIANT LETTER D PROCEDURE procedure GIANT_D is begin PUT_LINE(" *******"); PUT_LINE(" * *"); PUT_LINE(" * *"); PUT_LINE(" * *"); PUT_LINE(" * *"); PUT_LINE(" * *"); PUT_LINE(" *******"); NEW_LINE; end GIANT_D; ----------------------------------------------------- -- TOP LEVEL PROCEDURE begin GIANT_A; GIANT_D; GIANT_A; end GIANT_ADA;
On completion of the implementation phase the entire program should be tested. In this case, given that there is no input and a straight forward sequence of commands, final testing can be carried out through a single execution of the program. The expected result of this final test would be as follows:
* * * * * * * ********* * * * * ******* * * * * * * * * * * ******* * * * * * * * ********* * * * *
Example Problem Giant Ada Report.
Created and maintained by Frans Coenen. Last updated 11 October 1999