# Ada Programming/Tips


## Full declaration of a type can be deferred to the unit\'s body

Often, you\'ll want to make changes to the internals of a private type.
This, in turn, will require the algorithms that act on it to be
modified. If the type is completed in the unit specification, it is a
pain to edit and recompile both files, even with an
IDE, but
it\'s something some programmers learn to live with.

It turns out you don\'t have to. Nonchalantly mentioned in the
ARM, and
generally skipped over in tutorials, is the fact that private types can
be completed in the unit\'s body itself, making them much closer to the
relevant code, and saving a recompile of the specification, as well as
every unit depending on it. This may seem like a small thing, and, for
small projects, it is. However, if you have one of those uncooperative
types that requires dozens of tweaks, or if your dependence graph has
much depth, the time and annoyance saved add up quickly.

Also, this construction is very useful when coding a shared library,
because it permits to change the implementation of the type while still
providing a compatible ABI.

Code sample:

` Private_And_Body `\
\
`  `` Private_Type `` `` ``;`\
\
`  `\
\
\
`  `` Body_Type;   `\
`  `` Private_Type `` `` Body_Type;`\
` Private_And_Body;`

The type in the public part is an
access to the hidden type.
This has the drawback that memory management has to be provided by the
package implementation. That is the reason why `Private_Type` is a
limited type, the client will not be allowed to copy the access values,
in order to prevent dangling references.

Normally, the full type definition has to be given in the specification
because the compiler has to know how much place to allocate to objects
in order to produce code using this type. And the astute reader will
note that also in this case the full type definition is given for
Private_Type: it is an access to some other (albeit incomplete) type,
and the size of an access value is known. This is why the full type
definition of Body_Type can be moved to the body.

The construction centering around `Private_Type` is sometimes called an
opaque pointer.

## Lambda calculus through generics

Suppose you\'ve decided to roll your own
set "wikilink") type. You can add
things to it, remove things from it, and you want to let a user apply
some arbitrary function to all of its members. But the scoping rules
seem to conspire against you, forcing nearly everything to be global.

The mental stumbling block is that most examples given of
generics are packages, and the Set package is
already generic. In this case, the solution is to make the Apply_To_All
procedure generic as well; that is, to nest the generics. Generic
procedures inside packages exist in a strange scoping limbo, where
anything in scope at the instantiation can be used by the instantiation,
and anything normally in scope at the formal can be accessed by the
formal. The end result is that the relevant scoping roadblocks no longer
apply. It isn\'t the full lambda calculus, just one of the most useful
parts.

\
`  `` Element `` ``;`\
` Sets `\
`  `` Set `` ``;`\
`   `*`[..]`*\
`  `\
`    `` `` Apply_To_One (The_Element : `` `` Element);`\
`  `` Apply_To_All (The_Set : `` `` Set);`\
` Sets;`

For a view of Functional Programming in Ada see.[^1]

## Compiler Messages

Different compilers can diagnose different things differently, or the
same thing using different messages, etc.. Having two compilers at hand
can be useful.

`selected component`: When a source program contains a construct such as `Foo.Bar`, you may see messages saying something like «selected component \"Bar\"» or maybe like «selected component \"Foo\"». The phrases may seem confusing, because one refers to `Foo`, while the other refers to `Bar`. But they are both right. The reason is that `selected_component` is an item from Ada\'s grammar (). It denotes all of: a prefix, a dot, and a selector_name. In the `Foo.Bar` example these correspond to `Foo`, \'`.`\', and `Bar`. Look for more grammar words in the compiler messages, e.g. «prefix», and associate them with identifiers quoted in the messages.

```{=html}
<!-- -->
```

:   For example, if you submit the following code to the compiler,

` `*`Pak`*\
` Foo `\
`   `` T `` `` `*`Pak`*`Bar``  `\
` Foo`

:   the compiler may print a diagnostic message about a prefixed
    component: `Foo`\'s author thought that `Pak` denotes a package, but
    actually it is the name of a *generic* package. (Which needs to be
    instantiated first; and then the *instance* name is a suitable
    prefix.)

## Universal integers

All integer literals and also some attributes like `'Length` are of the
anonymous type *universal_integer*, which comprises the infinite set of
mathematical integers. Named numbers are of this type and are evaluated
exactly (no overflow except for machine storage limitations), e.g.

` Very_Big: `` := 10**1_000_000 - 1;`

Since *universal_integer* has no operators, its values are converted in
this example to *root_integer*, another anonymous type, the calcuation
is performed and the result again converted back in *universal_integer*.

Generally values of *universal_integer* are implicitly converted to the
appropriate type when used in some expression. So the expression
` A`
is fine; the value of
`A`
is interpreted as a modular integer since
 can only be applied to modular
integers (of course a context is needed to decide which modular integer
type is meant). This feature can lead to pitfalls. Consider

`   `` Ran_6 `` `` 1 `` 6`\
`   `` Mod_6 `` `` 6`

and then

`   `\
`   `` A`` `` Ran_6 ``  `\
`      …`\
\
`   `\
`   `` `` A`` `` Ran_6 ``  `\
`      …`\
`   `\
`   `` (`` A``) `` Ran_6 ``  `\
`      …`\
\
`   `\
`   `` A`` `` 1 `` 6 ``  `\
`      …`\
\
`   `\
`   `` `` A`` `` 1 `` 6 ``  `\
`      …`\
\
`   `\
`   `` A`` `` Mod_6 ``  `\
`      …`\
\
`   `\
`   `` `` A`` `` Mod_6 ``  `\
`      …`

:   The second conditional cannot be compiled because the expressions to
    the left of  is incompatible to the
    type at the right. Note that  has
    precedence over . It does not negate
    the entire membership test but only
    `A`.

```{=html}
<!-- -->
```

:   The fourth conditional fails in various ways.

```{=html}
<!-- -->
```

:   The sixth conditional might be fine because
     turns
    `A`
    into a modular value which is OK if the value is covered by modular
    type `Mod_6`.

```{=html}
<!-- -->
```

:   GNAT GPL 2009 gives these diagnoses respectively:

`error: incompatible types`\
`error: operand of not must be enclosed in parentheses`\
`warning: not expression should be parenthesized here`

:   A way to *avoid* these problems is to use
    ` `
    for the membership test (which, btw., is the language-intended
    form),

`   `` A`` `` `` Ran_6 ``  `\
`      …`

:   See
    -           ,

    -           ), and

    -           ,

    -           ,

    -   Membership
        Tests

## I/O

### Text_IO Issues

A canonical method of reading a sequence of lines from a text file uses
the standard procedure
.*Get_Line*. When the end of
input is reached, *Get_Line* will fail, and exception *End_Error* is
raised. Some programs will use another function from
 to prevent this and test for
*End_of_File*. However, this isn\'t always the best choice, as has been
explained for example in a Get_Line news group discussion on
comp.lang.ada.

A working solution uses an exception handler instead:

`  `\
`     The_Line`` String``1``100`\
`     Last`` Natural`\
`  `\
`     `\
`        Text_IO``Get_Line``The_Line`` Last`\
`        `\
`     `` `\
`  `\
`     `` Text_IO``End_Error `\
`        `\
`  `

The function End_of_File RM A.10.1(34) works fine as long as the file
follows the canonical form of text files presumed by Ada, which is
always the case when the file has been written by
. This canonical form requires
an End_of_Line marker followed by an End_of_Page marker at the very end
before the End_of_File.

If the file was produced by another any other means, it will generally
not have this canonical form, so a test for End_of_File will fail.
That\'s why the exception End_Error has to be used in those cases (which
always works).

## Quirks

Using GNAT on Windows, calls to subprograms from
 might need special
attention. (For example, the `Real_Time.Clock` function might seem to
return values indicating that no time has passed between two invocations
when certainly some time has passed.) The cause is reported to be a
missing initialization of the run-time support when no other real-time
features are present in the program.[^2] As a provisional fix, it is
suggested to insert

` 0``0`

before any use of `Real_Time` services.

### Stack Size

With some implementations, notably GNAT, knowledge of stack size
manipulation will be to your advantage. Executables produced with GNAT
tools and standard settings can hit the stack size limit. If so, the
operating system might allow setting higher limits. Using GNU/Linux and
the Bash command shell, try

`$ ulimit -s [some number]`

The current value is printed when only `-s` is given to *ulimit*.

## References

```{=html}
<references/>
```
## See also

### Wikibook

-   Ada Programming
-   Ada Programming/Errors

### Ada Reference Manual

-   

[^1]: Functional Programming
    in\...Ada?,
    by Chris Okasaki

[^2]:
        Usenet article forwards this information from AdaCore.
