Two Ada constructs are needed for defining an ADT: the data type and its methods are placed in an Ada package. For safety and information hiding, the data type is made private. Although a package's "client" can see the structure of the data type, the compiler prevents access to individual attributes of the type: thus effectively implementing the information hiding principle. The client can see the information, but can't do anything with it! (I believe that the reason for exposing the structure of the private type is purely pragmatic: compilers and linkers know how much space an ADT in a separately compiled package - for which only the specification might be available - requires.)
An Ada package for complex numbers would be implemented:
PACKAGE complex_numbers IS TYPE complex IS PRIVATE; I : CONSTANT complex; -- 'i' FUNCTION "-"( complex a ) RETURNS complex; -- Unary minus FUNCTION "+"( complex a; complex b ) RETURNS complex; FUNCTION "-"( complex a; complex b ) RETURNS complex; FUNCTION "*"( complex a; complex b ) RETURNS complex; FUNCTION "="( complex a; complex b ) RETURNS boolean; PRIVATE TYPE complex IS RECORD real, imag : FLOAT; END RECORD; I : CONSTANT complex := (0.0, 1.0); END complex_numbers;The body or implementation would usually be placed in a separate file and compiled separately:
PACKAGE BODY complex_numbers IS FUNCTION "-"( complex a ) RETURNS complex IS -- Unary minus RETURN complex'(-a.real,-a.imag); END "-"; FUNCTION "+"( complex a; complex b ) RETURNS complex IS RETURN complex'(a.real+b.real,a.imag+c.imag); END "+"; FUNCTION "-"( complex a; complex b ) RETURNS complex IS RETURN complex'(a.real-b.real,a.imag-c.imag); END "-"; FUNCTION "*"( complex a; complex b ) RETURNS complex IS RETURN complex'(a.real*b.real - a.imag*b.imag, a.real*b.imag + a.imag*b.real ); END "*"; FUNCTION "="( complex a; complex b ) RETURNS boolean IS RETURN (a.real = b.real) AND (a.imag = b.imag); END "="; END complex_numbers;
Note that Ada provides excellent operator overloading capabilities, which enable us to write mathematically "natural" code: e.g.
complex a, b, c, z; IF a = b THEN c := z - a; z := -z; END IF;
You can also observe that Ada is an extreme case of the
principle that programs are read many times
more often than they are read (for modern languages
at least - nothing is ever likely to match the verbosity of COBOL!).
Keywords appear everywhere:
IS, RETURNS, etc..