Coding Ada: Using multiple packages
So Ada uses packages to implement a form of encapsulation, which actually existed before the whole hoopla with C++ evolved. Packages have a specification, and an implementation. In the example below, we will create three packages to generate an image comprised of random values, i.e. a noise image. Here is an example (it can be saved as a text image).

The first package only has a specification, and is called datas
. It includes the data structures needed by the other packages (i) image, and (ii) print (and also the main program). Here is what the specification looks like (datas.ads
):
package datas is type randRange is new Integer range 0..255; type randImg is array(1..500,1..500) of randRange; end datas;
It includes a type randRange
, which specifies integers in the range 0..255, and a type randImg
, which is a 2D array of type randRange
. Next is the package image
β its task is to generate an image of random numbers in the range 0..255. Here is the specification (image.ad
s):
with ada.numerics.discrete_random; with datas; use datas; package image is package Rand_Int is new ada.numerics.discrete_random(randRange); use Rand_Int; procedure makeImage(img : out randImg); end image;
It creates a new instance of the package discrete_random
, to deal with generating numbers in the range 0..255. It also contains a function makeImage()
, which uses the types in package datas
to generate an image. Here is the package implementation (image.ad
b):
package body image is procedure makeImage(img : out randImg) is gen : Generator; begin reset(gen); for i in 1..img'last(1) loop for j in 1..img'last(2) loop img(i,j) := random(gen); end loop; end loop; end; end image;
The last package, print
just prints out the image as a series of rows (to standard output, but it can be redirected to a file, e.g. a.out >randim.txt
). Here is the specification (print.ads
):
with ada.Text_IO; use Ada.Text_IO; with ada.Integer_Text_IO; use Ada.Integer_Text_IO; with datas; use datas; package print is procedure printImage(img : in randImg); end print;
And the associated implementation (print.adb
):
package body print is procedure printImage(img : in randImg) is begin for i in 1..img'last(1) loop for j in 1..img'last(2) loop put(randRange'Image(img(i,j))); end loop; new_line; end loop; end; end print;
Finally the main program that calls them all (test.adb
)
with image; use image; with print; use print; with datas; use datas; procedure test is im : randImg; begin makeImage(im); printImage(im); end test;
This program can be compiled simply using the main file:
% gnatmake -Wall test.adb
Obviously packages can be compiled,bu they canβt be linked or executed. Each of the packages can also be compiled separately:
% gnatmake -Wall image.ads image.adb % gnatmake -Wall print.ads print.adb % gnatmake -Wall datas.ads % gnatmake -Wall test.adb