Illustrations of Ada Goodies:

Recommendation:

A simple device interface program, involving memory-mapped I/O
to registers, using representation clauses. Make it a generic, and
have a number of these instantiated with different represented
enumerated types running as concurrent tasks. Have them all
wirting to a common database, using a protected object.

Example of a represented enumerated type.
:
type traffic_light_T is ( Red, Red_and_Amber, Green, Amber);
for traffic_light_T use
(
   Red => 2#000_0100#,
   Red_and_Amber => 2#0000_0110#,
   Green => 2#0000_0001#,
   Amber => 2#000_0010#,

);

for traffic_light_T'SIZE use 8;

You can then loop through traffic_light_T without bothering about
magic numbers, or even how big the loop is.

Ada-95 has lots of good OO features, but we often forget just exactly
how easy it is to program at a high level in Ada without being bothered
by such weird incantations as
"public static void main(String[] args){print"Hello World\n");}"

Note that - C isn't typesafe, Java can't handle real as opposed to
virtual machine I/O, C++ templates are poorly implemented compared
with Ada generics, and so on.

Careful though with Java: more and more Ada features are being
added to each iteration of thye language. Today it's generics, tomorrow
maybe enumerations, then who knows?