\chapter{Basic Ada}
\section{``Hello, world!'' programs}
\subsection{``Hello, world!''}
A common example of a language's syntax is the Hello world program.
Here a straight-forward Ada Implementation:
\mylstinputlisting{code/hello_world_1.adb}
The with statement adds the package Ada.Text\_IO to the program. This
package comes with every Ada compiler and contains all functionality
needed for textual Input/Output. The with statement makes the
declarations (i.e. all types and the operations on them) within
Ada.Text\_IO visible by selection. In Ada, packages can be used as
toolboxes, providing a collection of tools and types in one
easy-to-access module. Here is a partial glimpse at package
Ada.Text\_IO:
\begin{mylstlisting}
package Ada.Text_IO is
type File_Type is limited private;
-- more stuff
procedure Open(File : in out File_Type;
Mode : File_Mode;
Name : String;
Form : String := "");
-- more stuff
procedure Put_Line (Item : String);
-- more stuff
end Ada.Text_IO;
\end{mylstlisting}
\subsection{``Hello, world!'' with renames}
By renaming a package it is possible to give a shorter alias to any
package name. This reduces the typing involved while still keeping
some of the readability.
\mylstinputlisting{code/hello_world_2.adb}
Renames can also be used for procedures, functions, variables, array
elements. It can not be used for types - a type rename can be
accomplished with subtype.
\subsection{``Hello, world!'' with use}
The use clause makes all the content of a package directly visible. It
allows even less typing but removes some of the readability. One
suggested "rule of thumb": use for the most used package and renames
for all other packages. You might have another rule (for example,
always use Ada.Text\_IO, never use anything else).
\mylstinputlisting{code/hello_world_3.adb}
use can be used for packages and in the form of use type for types.
use type makes only the operators of the given type directly visible
but not any other operations on the type.
\subsection{FAQ: Why is ``Hello, world!'' sooo big?}
Ada beginners frequently ask how it can be that such a simple program
as ``Hello, world!'' results in such a large executable. The reason
has nothing to do with Ada but can usually be found in the compiler
and linker options used or not used.
Standard behavior for Ada compilers --- or good compilers in general
--- is not to create the best code possible but to be optimized for
ease of use. This is done to not frighten away potential new users by
providing a system which does not work ``out of the box''.
The GNAT project files, which you can download alongside the example
programs, use better tuned compiler, binder and linker options. If you
use those options, your ``Hello, world!'' will be a lot smaller:
\begin{verbatim}
32K ./Linux-i686-Debug/hello_world_1
8,0K ./Linux-i686-Release/hello_world_1
36K ./Linux-x86_64-Debug/hello_world_1
12K ./Linux-x86_64-Release/hello_world_1
1,1M ./Windows_NT-i686-Debug/hello_world_1.exe
16K ./Windows_NT-i686-Release/hello_world_1.exe
32K ./VMS-AXP-Debug/hello_world_1.exe
12K ./VMS-AXP-Release/hello_world_1.exe
\end{verbatim}
For comparison the sizes for a plain gnat make compile:
\begin{verbatim}
497K hello_world_1 (Linux i686)
500K hello_world_1 (Linux x86_64)
1,5M hello_world_1.exe (Windows_NT i686)
589K hello_world_1.exe (VMS AXP)
\end{verbatim}
One tidbit worth mentioning is that hello\_world (Ada,C,C++) compiled
with GNAT/MSVC 7.1/GCC(C) all produces executables with approximately
the same size given comparable optimisation and linker methods.
\section{Things to look out for}
It will help to be prepared to spot a number of significant features
of Ada that are important for learning its syntax and semantics.
\subsection{Comb Format}
There is a comb format in all the control structures and module
structures. See the following examples for the comb format. You don't
have to understand what the examples do yet --- just look for the
similarities in layout.
\begin{mylstlisting}
if Boolean expression then
statements
elsif Boolean expression then
statements
else
statements
end if;
\end{mylstlisting}
\begin{mylstlisting}
declare
declarations
begin
statements
exception
handlers
end;
\end{mylstlisting}
\begin{mylstlisting}
procedure P (parameters : in out type) is
declarations
begin
statements
exception
handlers
end P;
\end{mylstlisting}
\begin{mylstlisting}
function F (parameters : in type) return type is
declarations
begin
statements
exception
handlers
end F;
\end{mylstlisting}
\begin{mylstlisting}
type R (discriminant : type) is
record
declarations
end record;
\end{mylstlisting}
\begin{mylstlisting}
type R (discriminant : type) is
record
declarations
end record;
\end{mylstlisting}
\begin{mylstlisting}
type C (discriminant : type) is new parent class declaration
and interface declarations -- (Ada 2005)
with
record
declarations
end record;
\end{mylstlisting}
\begin{mylstlisting}
package P is
declarations
private
declarations
end P;
\end{mylstlisting}
\begin{mylstlisting}
generic
declarations
package P is
declarations
private
declarations
end P;
\end{mylstlisting}
\begin{mylstlisting}
generic
declarations
procedure P (parameters : in out type);
\end{mylstlisting}
Note that semicolons consistently terminate statements and
declarations; and that the empty string is not a valid statement: the
null statement is null.
\subsection{Type and subtype}
There is an important distinction between type and subtype: a type is
given by a set of values and their operations. A subtype is given by a
type, and a constraint that limits the set of values. Values are
always of a type. Objects (constants and variables) are of a subtype.
This generalizes, clarifies and systematizes a relationship, e.g.
between Integer and $1\ldots 100$, that is handled ad hoc in the
semantics of Pascal.
\subsection{Constrained types and unconstrained types}
There is an important distinction between constrained types and
unconstrained types. An unconstrained type has one or more free
parameters that affect its size or shape. A constrained type fixes the
values of these parameters and so determines its size and shape.
Loosely speaking, objects must be of a constrained type, but formal
parameters may be of an unconstrained type (they adopt the constraint
of any corresponding actual parameter). This solves the problem of
array parameters in Pascal (among other things).
\subsection{Dynamic types}
Where values in Pascal or C must be static (e.g. the subscript bounds
of an array) they may be dynamic in Ada. However, static expressions
are required in certain cases where dynamic evaluation would not
permit a reasonable implementation (e.g. in setting the number of
digits of precision of a floating point type).
\subsection{Separation of interface}
Ada consistently supports a separation of interface and mechanism. You
can see this in the format of a package, which separates its
declaration from its body; and in the concept of a private type, whose
representation in terms of Ada data structures is inaccessible outside
the scope containing its definition.