home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #2 / Amiga Plus CD - 1995 - No. 2.iso / internet / faq / englisch / comp.lang.ada-programming < prev    next >
Encoding:
Text File  |  1995-04-11  |  111.2 KB  |  2,780 lines

  1. Archive-name: computer-lang/Ada/programming/part1
  2. Comp-lang-ada-archive-name: programming/part1
  3. Posting-Frequency: monthly
  4. Last-modified: 7 February 1995
  5. Last-posted: 19 January 1995
  6.  
  7.                                Ada Programmer's
  8.                        Frequently Asked Questions (FAQ)
  9.  
  10.    IMPORTANT NOTE: No FAQ can substitute for real teaching and
  11.    documentation. There is an annotated list of Ada books in the
  12.    companion comp.lang.ada FAQ.
  13.  
  14. This is part 1 of a 3-part posting.
  15. Part 2 begins with question 5.6.
  16. Part 3 begins with question 9.4.
  17. They should be the next postings in this thread.
  18.  
  19.  
  20. Introduction
  21.  
  22.    Ada is an advanced, modern programming language, designed and
  23.    standardized to support and strongly encourage widely recognized
  24.    software engineering principles: reliability, portability, modularity,
  25.    reusability, programming as a human activity, efficiency,
  26.    maintainability, information hiding, abstract data types, genericity,
  27.    concurrent programming, object-oriented programming, etc.
  28.  
  29.    All Ada compilers must pass a validation test. Ada is not a superset
  30.    or extension of any other language. Ada does not allow the dangerous
  31.    practices or effects of old languages, although it does provide
  32.    standardized mechanisms to interface with other languages such as
  33.    Fortran, Cobol, and C.
  34.  
  35.    Ada is recognized as an excellent vehicle for education in programming
  36.    and software engineering, including for a first programming course.
  37.  
  38.    Ada is defined by an international standard (the language reference
  39.    manual, or LRM), which has been revised in 1995. Ada is taught and
  40.    used all around the world (not just in the USA). Ada is used in a very
  41.    wide range of applications: banking, medical devices,
  42.    telecommunications, air traffic control, airplanes, railroad
  43.    signalling, satellites, rockets, etc.
  44.  
  45.    The latest version of this FAQ is always accessible through WWW as
  46.    http://lglwww.epfl.ch/Ada/FAQ/programming.html
  47.  
  48. Maintenance
  49.  
  50.    This FAQ is maintained on an individual volunteer basis, by Magnus
  51.    Kempe (Magnus.Kempe@di.epfl.ch). [Note: This is done as a hobby, not
  52.    in my capacity as an employee at the Swiss Federal Institute of
  53.    Technology. --MK]
  54.  
  55.    The coding style used in most of the example Ada code is my own, and
  56.    you'll have to live with it (you may want to adopt it :-).
  57.  
  58.  
  59.      _________________________________________________________________
  60.  
  61.    Opinions (if any) expressed are those of the submitters and/or
  62.    maintainer.
  63.      _________________________________________________________________
  64.  
  65.  
  66. Table of Contents:
  67.  
  68.  
  69.      * 1: Recent changes to the FAQ
  70.  
  71.      * 2: Information about this document
  72.  
  73.      * 3: Elementary Questions
  74.           + 3.1: How do I make operations directly visible without
  75.             "use"ing a package?
  76.           + 3.2: How do I assign to an array of length 1?
  77.           + 3.3: How do I create a C-style nul-terminated string?
  78.           + 3.4: How can I create an array of strings of various length?
  79.           + 3.5: I know an exception is raised, but my program quits with
  80.             no warning. Why?
  81.           + 3.6: I have only one task in my program, but it doesn't seem
  82.             to run. Why?
  83.           + 3.7: How do I increase the stack size for a task?
  84.           + 3.8: What's the difference between a type conversion and a
  85.             qualifier?
  86.           + 3.9: How do I avoid the potential space in front of
  87.             Integer'Image?
  88.           + 3.10: Why is an exception raised when giving a default
  89.             discriminant?
  90.           + 3.11: When I want an Integer type, what's wrong with just
  91.             using the predefined type Integer or Long_Integer? Why would
  92.             I ever want to declare new Integer types?
  93.           + 3.12: Since I can always declare my own portable integer
  94.             types, why would I ever want to use the predefined type
  95.             Integer?
  96.           + 3.13: I am learning Ada. Can I experiment with a game
  97.             program?
  98.  
  99.  
  100.      * 4: Advantages of Ada
  101.           + 4.1: Why use Ada?
  102.           + 4.2: Ada seems large and complex, why is it this way?
  103.  
  104.  
  105.      * 5: Object-Oriented Programming with Ada
  106.           + 5.1: Why does Ada have "tagged types" instead of classes?
  107.           + 5.2: Variant records seem like a dead feature now? When
  108.             should I use them instead of tagged types?
  109.           + 5.3: What is meant by "interface inheritance" and how does
  110.             Ada support it?
  111.           + 5.4: How do you do multiple inheritance in Ada 9X?
  112.           + 5.5: Why are Controlled types so, well, strange?
  113.           + 5.6: What do "covariance" and "contravariance" mean, and does
  114.             Ada support either or both?
  115.           + 5.7: What is meant by upcasting/expanding and
  116.             downcasting/narrowing?
  117.           + 5.8: How does Ada do "narrowing"?
  118.  
  119.  
  120.      * 6: Ada Numerics
  121.           + 6.1: Where can I find anonymous ftp sites for Ada math
  122.             packages? In particular where are the random number
  123.             generators?
  124.           + 6.2: How can I write portable code in Ada 83 using predefined
  125.             types like Float and Long_Float? Likewise, how can I write
  126.             portable code that uses Math functions like Sin and Log that
  127.             are defined for Float and Long_Float?
  128.           + 6.3: Where's a good place to start learning the Ada 95
  129.             numerics model?
  130.           + 6.4: How do I get Real valued and Complex valued math
  131.             functions in Ada 95?
  132.           + 6.5: What libraries or public algorithms exist for Ada?
  133.  
  134.  
  135.      * 7: Efficiency of Ada Constructs
  136.           + 7.1: How much extra overhead do generics have?
  137.  
  138.  
  139.      * 8: Advanced Programming Techniques with Ada
  140.           + 8.1: Does Ada have automatic constructors and destructors?
  141.           + 8.2: How can I redefine assignment operations?
  142.           + 8.3: Should I stick to a one package, one type approach while
  143.             writing Ada software?
  144.           + 8.4: What is the "Beaujolais Effect"?
  145.           + 8.5: What about the "Ripple Effect"?
  146.  
  147.  
  148.      * 9: Ada and Other Programming Languages
  149.           + 9.1: Where can I find programs that will translate from [some
  150.             language] to Ada?
  151.           + 9.2: How can I convert Ada 83 sources to Ada 9X?
  152.           + 9.3: I hear that Ada is slower than Fortran or C, is that
  153.             true?
  154.           + 9.4: Isn't Ada less "elegant" than Eiffel?
  155.           + 9.5: Are there any papers detailing the differences between
  156.             Ada and C++?
  157.           + 9.6: I keep hearing that Ada is a "strongly typed language",
  158.             but it seems different from what's meant in C++. Are they
  159.             different?
  160.           + 9.7: I'm told Ada does all sorts of static type checking, but
  161.             can't you get the same effect using a tool like "lint" with
  162.             C?
  163.           + 9.8: Does Ada have something like the Standard Template
  164.             Library (STL) in C++, or like the components one finds in
  165.             Smalltalk environments?
  166.           + 9.9: Where can I find the equivalent of "printf" in Ada?
  167.  
  168.  
  169.      * 10: Interfacing with Ada
  170.           + 10.1: I am writing software that used the Distributed
  171.             Interactive Simulation (DIS) interface, does an interface
  172.             exist in Ada?
  173.           + 10.2: Is there any support for Common Object Request Broker
  174.             Architecture (CORBA) for Ada 9X?
  175.  
  176.  
  177.      * 11: Finding Additional Information
  178.           + 11.1: Where can I find Ada books?
  179.           + 11.2: Are there other Ada-related FAQs?
  180.           + 11.3: What is the "Ada WWW Server"?
  181.  
  182.  
  183.      * 12: Pretty-printing Ada Source Code
  184.           + 12.1: Is there software that generates a pretty PostScript
  185.             file from Ada source code?
  186.           + 12.2: I use vgrind to do "pretty printing" of my source. Is
  187.             there a vgrind definition for Ada?
  188.           + 12.3: How about a source code reformatter?
  189.  
  190.  
  191.      * 13: Common Confusions 
  192.           + 13.1: Wasn't Ada designed by some committee? What kind of a
  193.             language could you possibly get from a committee?
  194.           + 13.2: I've heard the DoD is dropping all Military standards
  195.             to reduce costs, doesn't that mean the mandate to use Ada
  196.             goes away too?
  197.  
  198.  
  199.      * 14: Credits
  200.  
  201.      * 15: Copying this FAQ
  202.  
  203.  
  204.      _________________________________________________________________
  205.  
  206.  
  207. 1: Recent changes to the FAQ
  208.  
  209.  
  210.      * 950207: revised introduction.
  211.      * 950202: updated equivalents of C++ STL and Smalltalk library.
  212.      * 950126: advantages of code sharing for generics, Pascal to Ada
  213.        tool.
  214.      * 950125: why define new integer types, and why use the predefined
  215.        Integer type, submitted by Jonathan Parker.
  216.      * 950124: approved for posting in *.answers.
  217.      * 950116: converting Ada 83 code to Ada 9X.
  218.      * 950109: more on DIS.
  219.      * 950106: lengthy code sections extracted and put on FTP server.
  220.      * 950105: printf solution; update on exception traces and vgrind.
  221.      * 950104: links from TOC to all questions.
  222.      * 941222: pretty-printing solutions.
  223.      * 941220: numbered all questions; various updates.
  224.      * 941215: one-element aggregates.
  225.      * 941212: additional elementary questions, submitted by Paul Pukite.
  226.      * 941212: examining the so-called "elegance" of Eiffel (vs. Ada).
  227.      * 941212: integrated "Ada Numerics" section contributed by Jonathan
  228.        Parker.
  229.      * 941208: added "default discriminant" and "Beaujolais effect."
  230.      * December 1994: more re-organization, HTML'ized.
  231.      * October 1994: FAQ format by Magnus Kempe.
  232.      * September 1994: first draft by Dave Weller.
  233.  
  234.  
  235.    What's important and missing:
  236.      * everything, life, and 42
  237.  
  238.  
  239.      _________________________________________________________________
  240.  
  241.  
  242. 2: Information about this document
  243.  
  244.    This file is posted monthly to comp.lang.ada, comp.answers, and
  245.    news.answers.
  246.  
  247.    This document has a home on the Ada WWW Server, in hypertext format,
  248.    URL http://lglwww.epfl.ch/Ada/FAQ/programming.html
  249.    The text-only version is also available in directory
  250.    ftp://lglftp.epfl.ch/pub/Ada/FAQ
  251.  
  252.    It is available--as posted in *.answers--on rtfm.mit.edu, which
  253.    archives all FAQ files posted to *.answers; see
  254.    ftp://rtfm.mit.edu/pub/usenet-by-group/news.answers/computer-lang/Ada
  255.  
  256.    Magnus Kempe maintains this document; it's not a job, it's a hobby.
  257.    Feedback (corrections, suggestions, ideas) about it is to be sent via
  258.    e-mail to magnus.kempe@di.epfl.ch . Thanks.
  259.  
  260.    In all cases, the most up-to-date version of the FAQ is the version
  261.    maintained on the Ada WWW Server. Please excuse any formatting
  262.    inconsistencies in the posted version of this document, as it is
  263.    automatically generated from the on-line version.
  264.  
  265.      _________________________________________________________________
  266.  
  267.  
  268. 3: Elementary Questions
  269.  
  270.  
  271. 3.1: How do I make operations directly visible without "use"ing the package?
  272.  
  273.    In Ada 83, you can rename the operations in your scope.
  274.  
  275.      -- Say you have an integer type called Int in package Types
  276.      function "<" (Left, Right : Types.Int)
  277.        return Boolean
  278.        renames Types."<";
  279.      -- Make sure the profiles of the first and last "<" match!
  280.  
  281.  
  282.    For operators, Ada 95 introduces the "use type" clause:
  283.  
  284.      use type Types.Int; -- makes operators directly visible
  285.  
  286.  
  287. 3.2: How do I assign to an array of length 1?
  288.  
  289.    Because of ambiguity of parentheses, named notation must be used for
  290.    one-element aggregates (or, under a different angle: a positional
  291.    aggregate must have more than one component).
  292.  
  293.    See [RM9X 4.3.3(7)] as well as the syntax rule of
  294.    positional_array_aggregate in [RM9X 4.3.3]; historians see [RM83
  295.    4.3(4)].
  296.  
  297.      declare
  298.        Array_of_One : array (1..1) of Float;
  299.      begin
  300.        -- Array_of_One := (10.0);   -- Won't work, parsed as an expression
  301.                                     -- within parentheses
  302.  
  303.        Array_of_One := (1 => 10.0); -- No ambiguity here
  304.      end;
  305.  
  306.  
  307.    You can't write a one-element positional aggregate in Ada. Nor a
  308.    zero-element aggregate. The reason for this restriction is that it
  309.    would be difficult for compilers to determine whether:
  310.  
  311.      ( exp )
  312.  
  313.    is a parenthesized expression of some type, or an aggregate of an
  314.    array type. If Ada had used some other notation for aggregates (say,
  315.    "[...]"), then this problem would not exist.
  316.  
  317.    Apparently the original requirements for Ada forbade using certain
  318.    ASCII characters, like '[' and ']', because those characters were not
  319.    available on all hardware. Also, certain characters are used for
  320.    different purposes and glyphs in countries that need additional
  321.    letters not present in ASCII.
  322.  
  323.  
  324. 3.3: How do I create a C-style nul-terminated string?
  325.  
  326.    In a declaration block, append an ASCII.NUL to create a constant Ada
  327.    string.
  328.  
  329.      declare
  330.        Str_Nul : constant String := Str & ASCII.NUL;
  331.      begin
  332.        Call_Requiring_C_String (Str_Nul (Str_Nul'First)'Address);
  333.      end;
  334.  
  335. -- or --
  336.  
  337.      function Nul_Terminate (Str : String)
  338.        return String is
  339.        Str_Nul : constant String := Str & ASCII.NUL;
  340.      begin
  341.        return Str_Nul;
  342.      end Nul_Terminate;
  343.  
  344.  
  345. 3.4: How can I create an array of strings of various length?
  346.  
  347.    In Ada 83, you have to use string access types and "new" to get
  348.    "ragged" arrays:
  349.  
  350.      type String_Access is
  351.        access String;
  352.  
  353.      Strings : constant array (Positive range 1..3) of String_Access
  354.              := ( 1 => new String'("One"),
  355.                   2 => new String'("Two"),
  356.                   3 => new String'("Three")
  357.                 );
  358.  
  359.  
  360.    In Ada 95, the process is simplified by using aliased constants:
  361.  
  362.      type String_Access is
  363.        access constant String;
  364.  
  365.      One : aliased constant String := "One";
  366.      Two : aliased constant String := "Two";
  367.      Three : aliased constant String := "Three";
  368.  
  369.      Strings : constant array (Positive range <>) of String_Access
  370.              := ( 1 => One'Access,
  371.                   2 => Two'Access,
  372.                   3 => Three'Access
  373.                 );
  374.  
  375.  
  376. 3.5: I know an exception is raised, but my program quits with no warning. Why?
  377.  
  378.  
  379.    On some Ada compilers, you have to manually "with" Text_IO before
  380.    exception information is diplayed to the terminal.
  381.  
  382.    On other Ada compilers, you must set an environment variable flag in
  383.    order to cause the exception information trace to be displayed.
  384.  
  385.  
  386. 3.6: I have only one task in my program, but it doesn't seem to run. Why?
  387.  
  388.    In Ada, the main procedure is automatically designated as a task.
  389.    This task may be running forever, thus starving your other task(s),
  390.    because pre-emptive scheduling is not required.
  391.  
  392.    If your Ada run-time exhibits that --pretty rare-- behavior, one
  393.    solution is to explicitly put the main task to sleep within a loop
  394.    construct, as in:
  395.  
  396.      procedure Main is
  397.        task Test;
  398.        task body Test is
  399.        begin
  400.          loop
  401.            delay 1.0;
  402.            Text_IO.Put_Line ("Test");
  403.          end loop;
  404.        end Test;
  405.      begin
  406.        loop
  407.          delay 20.0;
  408.          Text_IO.Put_Line ("Sleeping then writing");
  409.        end loop;
  410.      end Main;
  411.  
  412.  
  413. 3.7: How do I increase the stack size for a task?
  414.  
  415.    Define the task as a "task type" and then use a pragma representation
  416.    clause.
  417.  
  418.      task type A_Task_Type;
  419.      for A_Task_Type'STORAGE_SIZE use 10_000;
  420.      -- 10K bytes allocated to instances of A_Task_Type
  421.      A_Task : A_Task_Type;
  422.  
  423.  
  424. 3.8: What's the difference between a type conversion and a qualifier?
  425.  
  426.    Use a qualifier (tick) to tell the compiler what type you want; this
  427.    incurs no run-time penalty. In other words, a qualifier "hints" the
  428.    type.
  429.  
  430.      A : Integer := Integer'(1);  -- same as := 1
  431.      B : Integer := Integer (1);  -- this is a conversion
  432.  
  433.  
  434. 3.9: How do I avoid the potential space in front of Integer'Image?
  435.  
  436.    Code a function that accepts a string and strips the leading blank.
  437.  
  438.      function Strip_Leading_Blank (Str : String)
  439.        return String is
  440.      begin -- Strip_Leading_Blank
  441.        if Str (Str'First) = ' ' then
  442.          return Str (1+Str'First .. Str'Last);
  443.        else
  444.          return Str;
  445.        end if;
  446.      end Strip_Leading_Blank;
  447.  
  448.      ...
  449.  
  450.      function My_Image (I : Integer)
  451.        return String is
  452.      begin -- My_Image
  453.        return Strip_Leading_Blank (Integer'Image (I));
  454.      end My_Image;
  455.  
  456.      ... My_Image (12) = "12" ...
  457.  
  458.  
  459. 3.10: Why is an exception raised when giving a default discriminant?
  460.  
  461.    Let's assume you would like to model varying-length strings:
  462.  
  463.      type V_String (Size : Natural := 0) is
  464.        record
  465.          S : String (1 .. Size);
  466.        end record;
  467.  
  468.  
  469.    (from Robert Dewar)
  470.  
  471.    When you give a default discriminant, then one method (I actually
  472.    think it is the preferred method) of implementation is to allocate the
  473.    maximum possible length. Since your discriminant is of type Natural,
  474.    this clearly won't work!
  475.  
  476.    GNAT may compile it, but it won't run it, and indeed I consider it a
  477.    GNAT bug (on the todo list) that no warning is issued at compile time
  478.    for this misuse.
  479.  
  480.    Some compilers, notably Alsys and RR, have at least partially "solved"
  481.    this problem by introducing hidden pointers, but this to me is an
  482.    undesirable implementation choice.
  483.  
  484.    First, it means there is hidden heap activity, which seems
  485.    undesirable. In a language where pointers are explicit, it is
  486.    generally a good idea if allocation is also explicit, and certainly
  487.    for real-time work, hidden anything is worrisome.
  488.  
  489.    Second, it is not easy to do uniformly. Alsys ends up introducing
  490.    arbitrary restrictions on the composition of such types (try making an
  491.    array of them), and RR introduces non-contiguous representations,
  492.    which are legal but troublesome.
  493.  
  494.    To "solve" the problem yourself, just declare a reasonable maximum
  495.    length, and use a subtype representing this length as the subtype of
  496.    the discriminant:
  497.  
  498.      Max_Length : constant := 200;
  499.  
  500.      subtype Index is
  501.        Natural range 0 .. Max_Length;
  502.  
  503.      type V_String (Size : Index := 0) is
  504.        record
  505.          S : String (1 .. Size);
  506.        end record;
  507.  
  508.  
  509. 3.11: When I want an Integer type, what's wrong with just using the predefined
  510. type Integer or Long_Integer? Why would I ever want to declare new Integer
  511. types?
  512.  
  513.    If you declare 2 distinct integer types, for example,
  514.  
  515.      type Data_Index        is range 1..100;
  516.      type Time_Series_Index is range 0..2**15-1;
  517.  
  518.  
  519.    then objects of type Data_Index can't be assigned (directly) to
  520.    variables of type Time_Series_Index, and vice-versa. Likewise,
  521.    variables of these 2 types can't be mixed in arithmetical expressions
  522.    (without explicit type conversions). This may seem like a source of
  523.    endless irritation, but on the contrary, good progammers use it to
  524.    improve the clarity of their code, to make it more robust, and more
  525.    portable. The first 2 examples discuss this. The third example
  526.    discusses the declaration of machine-portable 32-bit integers.
  527.    Declaring objects of type Integer can be highly non-portable, and of
  528.    course type Long_Integer may not exist on some compilers.
  529.  
  530.     Example 1.
  531.  
  532.    Suppose you declare arrays using the above indices:
  533.  
  534.      type Time_Series is array (Time_Series_Index) of Float;
  535.      type Y_Axis_Data is array (Data_Index)        of Float;
  536.  
  537.      Measurement : Time_Series;
  538.  
  539.  
  540.    Now if you mistakenly try to iterate over one array with the index of
  541.    the other, the compiler can catch the error at compile time:
  542.  
  543.      for I in Data_Index loop
  544.         Sum := Sum + Measurement(I);  -- compilation error
  545.      end loop;
  546.  
  547.  
  548.     Example 2.
  549.  
  550.    This is lifted from Tucker Taft's brief introduction to Ada 95 in the
  551.    contributed papers section of the Ada World Wide Web homepage. Here
  552.    Tucker uses the Ada 95 unsigned integers, called modular types, in the
  553.    implementation of a protected type, which defines a disk control unit.
  554.    Modular types are integer types with "and", "or" and "xor" defined, so
  555.    systems programmers are likely to use them as bit masks. Just as the
  556.    array indices of the 2 arrays defined above are never meant to be
  557.    mixed, the modular integer types used to implement the disk control
  558.    unit are never meant to be mixed. To make sure the compiler enforces
  559.    this, they are declared as distinct types:
  560.  
  561.      type Flags   is mod 2**4;  -- a 4-bit flags field
  562.      type Control is mod 2**4;  -- A 4-bit control field
  563.  
  564.      Status_Mask  : constant Flags := 2#1001#;   -- Set first and last bits.
  565.      Status_Ready : constant Flags := 2#1000#;   -- Status = Ready
  566.  
  567.      Start_Xfr    : constant Control := 2#0001#; -- Initiate xfr command
  568.  
  569.  
  570.    Now if someone attempts to apply a Flag variable where a Control
  571.    variable should be used (or vice-versa) the compiler will catch the
  572.    error. This is especially important when the code is maintained by
  573.    programmers who did not write it.
  574.  
  575.     Remarks on Examples 1 and 2.
  576.  
  577.    1. Notice that in both examples the programmer was able to state his
  578.    intentions rather forcefully in the code - intentions that otherwise
  579.    might have been expressed much less forcefully in comment statements.
  580.    Because of Ada's strong typing model, the compiler was able to catch
  581.    errors at compile-time when the programmer's intentions were violated.
  582.  
  583.  
  584.    2. Notice also that the Integer declarations in the 2 examples are
  585.    machine portable, unlike Integer and Long_Integer. A compiler will
  586.    typically map these integer types onto the most efficient base type
  587.    that is available on the target machine.
  588.  
  589.     Example 3.
  590.  
  591.    Although the examples given above are good ones, it is not necessarily
  592.    a common practice to define a large number of distinct integer types.
  593.    In many cases it is appropriate to use (say) a 32-bit integer (or a
  594.    small number of such types) and declare appropriate subtypes of it
  595.    (them). To declare a portable 32-bit integer (or more accurately, the
  596.    most efficient integer that is at least 32-bits):
  597.  
  598.    type Int_tmp is range -2**31+1 .. 2**31-1;
  599.    type Integer_32 is range Int_tmp'Base'First..Int_tmp'Base'Last;
  600.  
  601.  
  602.    A compiler may reject this declaration if no suitable base type is
  603.    available, but this is rare. What happens is this: in order to
  604.    implement Int_tmp, the compiler chooses as the base type of Int_tmp an
  605.    integer type that is available on the target machine. This base type
  606.    is usually the most efficient integer that accomodates the range of
  607.    Int_tmp, which in turn is usually the machine's 32-bit integer. (It
  608.    might even be a 64-bit integer on some machines, in which case
  609.    Integer_32'Size = 64, and Integer_32'Last = 2**63-1. Maybe we should
  610.    not call it Integer_32!)
  611.  
  612.  
  613. 3.12: Since I can always declare my own portable integer types, why would I
  614. ever want to use the predefined type Integer?
  615.  
  616.    The language itself provides some guidance here. The predefined type
  617.    Integer is used by Ada in the implementation of a number of convenient
  618.    services. The following examples describe some of these services.
  619.    Notice that in most of the following examples, it is unlikely that it
  620.    will ever matter whether or not the predefined type Integer is
  621.    16-bits, 32-bits, 48-bits, or 64-bits.
  622.  
  623.    a) The exponentiation of X (written X**N) is defined by the language
  624.    for any floating point or integer X, provided N is of type Integer. (N
  625.    should be non-negative for integer X though.)
  626.  
  627.    b) Ada's predefined String type (really just a packed unconstrained
  628.    array of characters) uses an index of subtype Positive (i.e. type
  629.    Integer).
  630.  
  631.    c) The array index in the following "short-hand" array declaration is
  632.    implicitly defined to be type Integer:
  633.  
  634.      A : array(10..40) of Float;
  635.  
  636.  
  637.    d) The loop parameter I in the following for loop is implicitly
  638.    declared type Integer:
  639.  
  640.      for I in 10..40 loop
  641.       ...
  642.      end loop;
  643.  
  644.  
  645.    This application of type Integer is the one most likely to get you
  646.    into portability trouble. If you write: "for I in 1..2**17 loop", then
  647.    you get a constraint error on compilers that make Integer 16-bits,
  648.    because 2**17 is out of range of any Ada 16-bit integer.
  649.  
  650.  
  651. 3.13: I am learning Ada. Can I experiment with a game program?
  652.  
  653.    Of course. The Public Ada library (FTP wuarchive.wustl.edu) has a
  654.    portable Ada Tetris program in the languages/ada/misc/games directory.
  655.    It uses tasking, keyboard input, and ANSI screen graphics. Have fun!
  656.  
  657.      _________________________________________________________________
  658.  
  659.  
  660. 4: Advantages of Ada
  661.  
  662.  
  663. 4.1: Why use Ada?
  664.  
  665.    Think of it like this: We're the kid on the street corner, licking
  666.    that tasty ice cream cone on a hot summer day; an impish grin
  667.    decorates our face as we consume our cool confection. Meanwhile, other
  668.    kids gather round, noticing our pleasure. It matters not a whit that
  669.    they've just had a drink, or had their fill with supper -- they now
  670.    want ice cream. We offer no lecture on how good the ice cream is, we
  671.    simply demonstrate that we are happy, and let their memories carry
  672.    them to the nearest ice cream truck.
  673.  
  674.    (Sorry, I got a little carried away --DW).
  675.  
  676.  
  677. 4.2: Ada seems large and complex, why is it this way?
  678.  
  679.    (Robert Dewar, lead designer of the GNU Ada compiler, responds):
  680.  
  681.    During the Ada 9X development process we have often had fierce
  682.    arguments over the need to simplify proposals, and I pointed out some
  683.    time ago that the idea of simplicity is heavily overloaded:
  684.      * simple to implement
  685.      * simple to describe informally
  686.      * simple to describe formally
  687.      * results in simple programs
  688.      * simple to understand and/or remember
  689.      * short to describe
  690.  
  691.  
  692.    None of these goals are quite the same, and often they severely
  693.    conflict.
  694.  
  695.    If you listen to programming language design types, especially from
  696.    universities, they often have very little experience in programming,
  697.    and especially little experience in writing large delivered,
  698.    maintained software. That doesn't mean they know nothing about
  699.    programming languages, but it does tend to mean that their view of
  700.    complexity is skewed, and in particularly concentrates on the
  701.    simplicity of the language itself, rather than on the simplicity of
  702.    resulting programs.
  703.  
  704.    A lot of the creative tension in the 9X design process arose from this
  705.    same fundamental dichotomy. The design team tended to have a high
  706.    tolerance for language complexity (partly because they were very good
  707.    at understanding language details), but had a lot of experience in
  708.    actual large scale programming, and so their idea of simplicity was
  709.    biased heavily to simplifying Ada programs. The opposite voice,
  710.    worried about the simplicity of the language itself, represented by a
  711.    section of the DR's and ISO group (who, being a larger more diverse
  712.    group tended to reflect a wider view), considered that the design team
  713.    had gone too far in this direction. If you want to get a feel for the
  714.    transitions, look at the early versions of the 9X ILS, particularly
  715.    version 1.0.
  716.  
  717.    In retrospect, I think we came up with what is at least very close the
  718.    optimal balance. Tuck can speak for himself here more clearly than I
  719.    can speak for him, but I would guess that he and the other members of
  720.    the team recognize that you have to be able to sell the resulting
  721.    design as an acceptably simple whole, and thus must step back from the
  722.    most extensive proposals, while on the other hand, the more
  723.    conservative KISS sentiments were convinced to accept more features
  724.    than they originally felt comfortable with because of convincing
  725.    programming examples and discussions of resulting programming
  726.    complexity. The third wing of opinion ("I don't care what you think,
  727.    but if we can't implement it, then it's not much use!") was also
  728.    effectively fed in from the user-implementor teams.
  729.  
  730.    Is the result too complex? Time will tell, but I think the balance is
  731.    a successful blend.
  732.  
  733.    I am a little more worried about C++ since there is an even greater
  734.    danger of kitchen sink mentality, fueled by lots of enthusiastic
  735.    feature-hungry programmers, adding too much to C++. A lot of big new
  736.    features have been added to C++ recently (notably templates and
  737.    exceptions). It's not that these new features are useless (after all
  738.    Ada programmers know the value of generics and exceptions!) but there
  739.    is a tendency to always add things in a most-decorated form (the
  740.    templates in C++ are much more general, but less safe, than Ada
  741.    generics, and the exceptions in C++ are much more elaborate, but less
  742.    efficient to implement, and trickier to understand). I think it will
  743.    be important for the C++ guys to make a real effort to keep the
  744.    continued development of the language under control to avoid going too
  745.    far in the feature-rich direction.
  746.  
  747.      _________________________________________________________________
  748.  
  749.  
  750. 5: Object-Oriented Programming with Ada
  751.  
  752.  
  753. 5.1: Why does Ada have "tagged types" instead of classes?
  754.  
  755.    (Tucker Taft responds):
  756.  
  757.    Someone recently asked me to explain the difference between the
  758.    meaning of the term "class" in C++ and its meaning in Ada 9X. Here is
  759.    a synopsis of the answer:
  760.  
  761.    In C++, the term "class" refers to three different, but related
  762.    things:
  763.      * a language construct, that encapsulates the definitions of data
  764.        members, member functions, nested types, etc.;
  765.  
  766.      * a particular kind of type, defined by a class construct (or by
  767.        "struct" which is a special case of "class");
  768.  
  769.      * a set of types consisting of a type and all of its derivatives,
  770.        direct and indirect.
  771.  
  772.  
  773.    In Ada 9X, the term "class" refers only to the third of the above
  774.    definitions. Ada 9X (and Ada 83) has three different terms for the
  775.    concepts corresponding to the above three things:
  776.      * a "package" encapsulates the definitions of types, objects,
  777.        operations, exceptions, etc which are logically related. (The
  778.        operations of a type defined immediately within the package where
  779.        the type is declared are called, in 9X, the "primitive operations"
  780.        of the type, and in some sense, define the "primitive" semantics
  781.        of the type, especially if it is a private type.)
  782.  
  783.      * a "type" is characterized by a set of values and a set of
  784.        primitive operations (there are a million definitions of "type,"
  785.        unfortunately, but you know what I mean...);
  786.  
  787.      * a "class" is a set of types with similar values and operations; in
  788.        particular, a type and and all of its derivatives, direct and
  789.        indirect, represents a (derivation) class. Also, the set of
  790.        integer types form the integer "class," and so on for the other
  791.        language-defined classes of types in the language.
  792.  
  793.  
  794.    Some OOP languages take an intermediary position. In CLOS, a "class"
  795.    is not an encapsulating construct (CLOS has "packages"). However, a
  796.    "class" is both a type and a set of types, depending on context.
  797.    (Methods "float" freely.)
  798.  
  799.    The distinction Ada 9X makes between types and classes (= set of
  800.    types) carries over into the semantic model, and allows some
  801.    interesting capabilities not present in C++. In particular, in Ada 9X
  802.    one can declare a "class-wide" object initialized by copy from a
  803.    "class-wide" formal parameter, with the new object carrying over the
  804.    underlying type of the actual parameter. For example:
  805.  
  806.      procedure Print_In_Bold (X : T'Class) is
  807.        -- Copy X, make it bold face, and then print it.
  808.        Copy_Of_X : T'Class := X;
  809.      begin
  810.         Make_Bold (Copy_Of_X);
  811.         Print (Copy_Of_X);
  812.      end P;
  813.  
  814.  
  815.    In C++, when you declare an object, you must specify the "exact" class
  816.    of the object -- it cannot be determined by the underlying class of
  817.    the initializing value. Implementing the above procedure in a general
  818.    way in C++ would be slightly more tedious.
  819.  
  820.    Similarly, in Ada 9X one can define an access type that designates
  821.    only one specific type, or alternatively, one can define one that can
  822.    designate objects of any type in a class (a "class-wide" access type).
  823.    For example:
  824.  
  825.      type Fancy_Window_Ptr is access Fancy_Window;
  826.        -- Only points at Fancy Windows -- no derivatives allowed
  827.      type Any_Window_Ptr is access Window'Class;
  828.        -- Points at Windows, and any derivatives thereof.
  829.  
  830.  
  831.    In C++, all pointers/references are "class-wide" in this sense; you
  832.    can't restrict them to point at only one "specific" type.
  833.  
  834.    In other words, C++ makes the distinction between "specific" and
  835.    "class-wide" based on pointer/reference versus object/value, whereas
  836.    in Ada 9X, this distinction is explicit, and corresponds to the
  837.    distinction between "type" (one specific type) and "class" (set of
  838.    types).
  839.  
  840.    The Ada 9X approach we believe (hope ;-) gives somewhat better control
  841.    over static versus dynamic binding, and is less error prone since it
  842.    is type-based, rather than being based on reference vs. value.
  843.  
  844.    In any case, in Ada 9X, C++, and CLOS it makes sense to talk about
  845.    "class libraries," since a given library will generally consist of a
  846.    set of interrelated types. In Ada 9X and CLOS, one could alternatively
  847.    talk about a set of "reusable packages" and mean essentially the same
  848.    thing.
  849.  
  850.  
  851. 5.2: Variant records seem like a dead feature now? When should I use them
  852. instead of tagged types?
  853.  
  854.    Hmm, good question.
  855.  
  856.  
  857. 5.3: What is meant by "interface inheritance" and how does Ada support it?
  858.  
  859.    This answer intentionally left blank.
  860.  
  861.  
  862. 5.4: How do you do multiple inheritance in Ada 9X?
  863.  
  864.    There is a lengthy paper on the AJPO ftp server (ajpo.sei.cmu.edu)
  865.    titled 9xm-inh.txt under /public/ada9x/docs(?)
  866.  
  867.    That document describes several mechanisms for achieving MI in Ada. It
  868.    is not unusual, however, to find complaints about the syntax and the
  869.    perceived burden it places on the developer. This is what Tucker Taft
  870.    had to say when responging to such a criticism on comp.lang.ada:
  871.  
  872.    Coming up with a syntax for multiple inheritance was not the
  873.    challenge. The challenge was coming up with a set of straightforward
  874.    yet flexible rules for resolving the well known problems associated
  875.    with multiple inheritance, namely:
  876.      * If the same type appears as an ancestor more than once, should all
  877.        or some of its data components be duplicated, or shared? If any
  878.        are duplicated, how are they referenced unambiguously?
  879.  
  880.      * If the same-named (including same parameter/result profile)
  881.        operation is inherited along two paths, how is the ambiguity
  882.        resolved? Can you override each with different code? How do you
  883.        refer to them later?
  884.  
  885.      * Etc...
  886.  
  887.  
  888.    For answers, you can look at the various languages that define a
  889.    built-in approach to multiple inheritance. Unfortunately, you will
  890.    generally get a different answer for each language -- hardly a
  891.    situation that suggests we will be able to craft an international
  892.    consensus. Eiffel uses renaming and other techniques, which seem quite
  893.    flexible, but at least in some examples, can be quite confusing (where
  894.    you override "B" to change what "A" does in some distant ancestor).
  895.    C++ has both non-virtual and virtual base clases, with a number of
  896.    rules associated with each, and various limitations relating to
  897.    downcasting and virtual base classes. CLOS uses simple name matching
  898.    to control "slot" merging. Some languages require that all but one of
  899.    the parent types be abstract, data-less types, so only interfaces are
  900.    being inherited; however if the interfaces happen to collide, you
  901.    still can end up with undesirable and potentially unresolvable
  902.    collisions (where you really want different code for same-named
  903.    interfaces inherited from different ancestors).
  904.  
  905.    One argument is that collisions are rare to begin with, so it doesn't
  906.    make much different how they are resolved. That is probably true, but
  907.    the argument doesn't work too well during an open language design
  908.    process -- people get upset at the most unbelievably trivial and
  909.    rarely uses features if not "correctly" designed (speaking from
  910.    experience here ;-).
  911.  
  912.    Furthermore, given that many of the predominant uses of MI (separation
  913.    of interface inheritance from implementation inheritance, gaining
  914.    convenient access to another class's features, has-a relationships
  915.    being coded using MI for convenience, etc.) are already handled very
  916.    well in Ada 9X, it is hard to justify getting into the MI language
  917.    design fray at all. As you nicely point out, the basic inheritance
  918.    model in Ada 9X is simple and elegant. Why clutter it up with a lot of
  919.    relatively ad-hoc rules to handle one particular approach to MI? For
  920.    the rare cases where MI is really critical, the last thing the
  921.    programmer wants in the language is the "wrong" MI approach built in.
  922.  
  923.    So the basic answer is that at this point in the evolution of OO
  924.    language design, it seemed wiser to provide MI building blocks, rather
  925.    than to foist the wrong approach on the programmer, and be regretting
  926.    it and working around it for years to come.
  927.  
  928.    Perhaps [Douglas Arndt] said it best...
  929.  
  930.      Final note: inheritance is overrated, especially MI. ...
  931.  
  932.  
  933.    If the only or primary type composition mechanism in the language is
  934.    based on inheritance, then by all means, load it up. But Ada 9X
  935.    provides several efficient and flexible type composition mechanisms,
  936.    and there is no need to overburden inheritance with unnecessary and
  937.    complicated baggage.
  938.  
  939.  
  940. 5.5: Why are Controlled types so, well, strange?
  941.  
  942.    (Tucker Taft responds):
  943.  
  944.    We considered many approaches to user-defined finalization and
  945.    user-defined assignment. Ada presents challenges that make it harder
  946.    to define assignment than in other languages, because assignment is
  947.    used implicitly in several operations (by-copy parameter passing,
  948.    function return, aggregates, object initialization, initialized
  949.    allocators, etc.), and because Ada has types whose set of components
  950.    can be changed as a result of an assignment.
  951.  
  952.    For example:
  953.  
  954.      type T (D : Boolean := False) is record
  955.        case D is
  956.          when False => null;
  957.          when True => H : In_Hands;
  958.        end case;
  959.      end record;
  960.  
  961.      X,Z : T;
  962.      Y : T := (True, H => ...);
  963.  
  964.      ...
  965.  
  966.      X := Y;   -- "X.H" component coming into existence
  967.      Y := Z;   -- "Y.H" component going out of existence
  968.  
  969.  
  970.    With a type like the one above, there are components that can come and
  971.    go as a result of assignment. The most obvious definition of
  972.    assignment would be:
  973.  
  974.      procedure ":="(Left : in out In_Hands; Right : in In_Hands);
  975.  
  976.  
  977.    Unfortunately, this wouldn't work for the "H" component, because there
  978.    is no preexisting "In_Hands" component to be assigned into in the
  979.    first case, and in the second case, there is no "In_Hands" component
  980.    to assign "from."
  981.  
  982.    Therefore, we decided to decompose the operation of assignment into
  983.    separable pieces: finalization of the left hand side; simple copying
  984.    of the data from the right hand side to the left hand side; and then
  985.    adjustment of the new left hand side. Other decompositions are
  986.    probably possible, but they generally suffer from not being easily
  987.    composable, or not handling situations like the variant record above.
  988.  
  989.    You seem to be proposing a function named ":=" that presumably returns
  990.    a copy of its in parameter. However, to do anything interesting it
  991.    will have to copy the in parameter into a local variable, and then
  992.    "fiddle" with than local variable (essentially what "Adjust" does),
  993.    and then return that local variable (which will make yet another
  994.    copy). The returned result will have to be put back into the desired
  995.    place (which might make yet another copy). For a large object, this
  996.    might involve several extra copies.
  997.  
  998.    By having the user write just that part of the operation that
  999.    "fiddles" with the result after making a copy, we allow the
  1000.    implementation to eliminate redundant copying. Furthermore, some
  1001.    user-defined representations might be position dependent. That is, the
  1002.    final "fiddling" has to take place on the object in its final
  1003.    location. For example, one might want the object to point to itself.
  1004.    If the implementation copies an object after the user code has
  1005.    adjusted it, such self-references will no longer point to the right
  1006.    place.
  1007.  
  1008.    So, as usual, once one gets into working out the details and all the
  1009.    interactions, the "obvious" proposal (such as a procedure ":=") no
  1010.    longer looks like the best answer, and the best answer one can find
  1011.    potentially looks "clumsy" (at least before you try to work out the
  1012.    details of the alternatives).
  1013.  
  1014.  
  1015. Archive-name: computer-lang/Ada/programming/part2
  1016. Comp-lang-ada-archive-name: programming/part2
  1017. Posting-Frequency: monthly
  1018. Last-modified: 7 February 1995
  1019. Last-posted: 19 January 1995
  1020.  
  1021.                                Ada Programmer's
  1022.                        Frequently Asked Questions (FAQ)
  1023.  
  1024.    IMPORTANT NOTE: No FAQ can substitute for real teaching and
  1025.    documentation. There is an annotated list of Ada books in the
  1026.    companion comp.lang.ada FAQ.
  1027.  
  1028. This is part 2 of a 3-part posting.
  1029. Part 3 begins with question 9.4; it should be the next posting in this thread.
  1030. Part 1 should be the previous posting in this thread.
  1031.  
  1032.  
  1033. 5.6: What do "covariance" and "contravariance" mean, and does Ada support
  1034. either or both?
  1035.  
  1036.    (From Robert Martin) [This is C++ stuff, it must be completely
  1037.    re-written for Ada. --MK]
  1038.  
  1039.  
  1040.  R> covariance:  "changes with"
  1041.  R> contravariance: "changes against"
  1042.  
  1043.  R> class A
  1044.  R> {
  1045.  R>    public:
  1046.  R>      A* f(A*);   // method of class A, takes A argument and returns A
  1047.  R>      A* g(A*);   // same.
  1048.  R> };
  1049.  
  1050.  R> class B : public A // class B is a subclass of class A
  1051.  R> {
  1052.  R>   public:
  1053.  R>     B* f(B*);  // method of class B overrides f and is covariant.
  1054.  R>     A* g(A*);  // method of class B overrides g and is contravariant.
  1055.  R> };
  1056.  
  1057.  R> The function f is covariant because the type of its return value and
  1058.  R> argument changes with the class it belongs to.  The function g is
  1059.  R> contravariant because the types of its return value and arguments does not
  1060.  R> change with the class it belongs to.
  1061.  
  1062.  
  1063.    Actually, I would call g() invariant. If you look in Sather, (one of
  1064.    the principle languages with contravariance), you will see that the
  1065.    method in the decendent class actually can have aruments that are
  1066.    superclasses of the arguments of its parent. So for example:
  1067.  
  1068. class A : public ROOT
  1069. {
  1070.    public:
  1071.      A* f(A*);   // method of class A, takes A argument and returns A
  1072.      A* g(A*);   // same.
  1073. };
  1074.  
  1075. class B : public A // class B is a subclass of class A
  1076. {
  1077.   public:
  1078.     B* f(B*);  // method of class B overrides f and is covariant.
  1079.     ROOT* g(ROOT*);  // method of class B overrides g and is contravariant.
  1080. };
  1081.  
  1082.  
  1083.    To my knowledge the uses for contravariance are rare or nonexistent.
  1084.    (Anyone?). It just makes the rules easy for the compiler to type
  1085.    check. On the other hand, co-variance is extremely useful. Suppose you
  1086.    want to test for equality, or create a new object of the same type as
  1087.    the one in hand:
  1088.  
  1089. class A
  1090. {
  1091.    public:
  1092.       BOOLEAN equal(A*);
  1093.       A* create();
  1094. }
  1095.  
  1096. class B: public A
  1097. {
  1098.    public:
  1099.       BOOLEAN equal(B*);
  1100.       B* create();
  1101. }
  1102.  
  1103.  
  1104.    Here covariance is exactly what you want. Eiffel gives this to you,
  1105.    but the cost is giving up 100% compile time type safety. This seem
  1106.    necessary in cases like these.
  1107.  
  1108.    In fact, Eiffel gives you automatic ways to make a method covariant,
  1109.    called "anchored types". So you could declare, (in C++/eiffese):
  1110.  
  1111. class A
  1112. {
  1113.    public:
  1114.       BOOLEAN equal(like Current *);
  1115.       like Current * create();
  1116. }
  1117.  
  1118.  
  1119.    Which says equal takes an argument the same type as the current
  1120.    object, and create returns an object of the same type as current. Now,
  1121.    there is not even any need to redeclare these in class B. Those
  1122.    transformations happen for free!
  1123.  
  1124.  
  1125. 5.7: What is meant by upcasting/expanding and downcasting/narrowing?
  1126.  
  1127.    (Tucker Taft replies):
  1128.  
  1129.    Here is the symmetric case to illustrate upcasting and downcasting.
  1130.  
  1131.      type A is tagged ...;   -- one parent type
  1132.  
  1133.      type B is tagged ...;   -- another parent type
  1134.  
  1135.      ...
  1136.  
  1137.      type C;   -- the new type, to be a mixture of A and B
  1138.  
  1139.      type AC (Obj : access C'Class) is
  1140.        new A
  1141.        with ...;
  1142.        -- an extension of A to be mixed into C
  1143.  
  1144.      type BC (Obj : access C'Class) is
  1145.        new B
  1146.        with ...;
  1147.        -- an extension of B to be mixed into C
  1148.  
  1149.      type C is
  1150.        tagged limited record
  1151.          A : AC (C'Access);
  1152.          B : BC (C'Access);
  1153.          ... -- other stuff if desired
  1154.        end record;
  1155.  
  1156.  
  1157.    We can now pass an object of type C to anything that takes an A or B
  1158.    as follows (this presumes that Foobar and QBert are primitives of A
  1159.    and B, respectively, so they are inherited; if not, then an explicit
  1160.    conversion (upcast) to A and B could be used to call the original
  1161.    Foobar and QBert).
  1162.  
  1163.      XC : C;
  1164.    ...
  1165.      Foobar (XC.A);
  1166.      QBert (XC.B);
  1167.  
  1168.  
  1169.    If we want to override what Foobar does, then we override Foobar on
  1170.    AC. If we want to override what QBert does, then we override QBert on
  1171.    BC.
  1172.  
  1173.    Note that there are no naming conflicts, since AC and BC are distinct
  1174.    types, so even if A and B have same-named components or operations, we
  1175.    can talk about them and/or override them individually using AC and BC.
  1176.  
  1177.  
  1178.    Upcasting (from C to A or C to B) is trivial -- A(XC.A) upcasts to A;
  1179.    B(XC.B) upcasts to B.
  1180.  
  1181.    Downcasting (narrowing) is also straightforward and safe. Presuming XA
  1182.    of type A'Class, and XB of type B'Class:
  1183.  
  1184.      AC(XA).Obj.all downcasts to C'Class (and verifies XA in AC'Class)
  1185.      BC(XB).Obj.all downcasts to C'Class (and verifies XB in BC'Class)
  1186.  
  1187.  
  1188.    You can check before the downcast to avoid a Constraint_Error:
  1189.  
  1190.      if XA not in AC'Class then -- appropriate complaint
  1191.  
  1192.      if XB not in BC'Class then -- ditto
  1193.  
  1194.  
  1195.    The approach is slightly simpler (though less symmetric) if we choose
  1196.    to make A the "primary" parent and B a "secondary" parent:
  1197.  
  1198.      type A is ...
  1199.      type B is ...
  1200.  
  1201.      type C;
  1202.  
  1203.      type BC (Obj : access C'Class) is
  1204.        new B
  1205.        with ...
  1206.  
  1207.      type C is
  1208.        new A
  1209.        with record
  1210.          B : BC (C'Access);
  1211.          ... -- other stuff if desired
  1212.        end record;
  1213.  
  1214.  
  1215.    Now C is a "normal" extension of A, and upcasting from C to A and
  1216.    (checked) downcasting from C'Class to A (or A'Class) is done with
  1217.    simple type conversions. The relationship between C and B is as above
  1218.    in the symmetric approach.
  1219.  
  1220.    Not surprisingly, using building blocks is more work than using a
  1221.    "builtin" approach for simple cases that happen to match the builtin
  1222.    approach, but having building blocks does ultimately provide mean more
  1223.    flexibility for the programmer -- there are many other structures that
  1224.    are possible in addition to the two illustrated above, using the
  1225.    access discriminant building block.
  1226.  
  1227.    For example, for mixins, each mixin "flavor" would have an access
  1228.    discriminant already:
  1229.  
  1230.      type Window is ...  -- The basic "vanilla" window
  1231.  
  1232.      -- Various mixins
  1233.      type Win_Mixin_1 (W : access Window'Class) is ...
  1234.  
  1235.      type Win_Mixin_2 (W : access Window'Class) is ...
  1236.  
  1237.      type Win_Mixin_3 (W : access Window'Class) is ...
  1238.  
  1239.  
  1240.    Given the above vanilla window, plus any number of window mixins, one
  1241.    can construct a desired window by including as many mixins as wanted:
  1242.  
  1243.      type My_Window is Window with
  1244.         M1 : Win_Mixin_1 (My_Window'access);
  1245.         M3 : Win_Mixin_3 (My_Window'access);
  1246.         M11 : Win_Mixin_1(My_Window'access);
  1247.        ... -- plus additional stuff, as desired.
  1248.      end record;
  1249.  
  1250.  
  1251.    As illustrated above, you can incorporate the same "mixin" multiple
  1252.    times, with no naming conflicts. Every mixin can get access to the
  1253.    enclosing object. Operations of individual mixins can be overridden by
  1254.    creating an extension of the mixin first, overriding the operation in
  1255.    that, and then incorporating that tweaked mixin into the ultimate
  1256.    window.
  1257.  
  1258.    I hope the above helps better illustrate the use and flexibility of
  1259.    the Ada 9X type composition building blocks.
  1260.  
  1261.  
  1262. 5.8: How does Ada do "narrowing"?
  1263.  
  1264.    Dave Griffith said
  1265.  
  1266.      . . . Nonetheless, The Ada9x committee chose a structure-based
  1267.      subtyping, with all of the problems that that is known to cause. As
  1268.      the problems of structure based subtyping usually manifest only in
  1269.      large projects maintained by large groups, this is _precisely_ the
  1270.      subtype paradigm that Ada9x should have avoided. Ada9x's model is,
  1271.      as Tucker Taft pointed out, quite easy to use for simple OO
  1272.      programming. There is, however, no good reason to _do_ simple OO
  1273.      programming. OO programmings gains click in somewhere around 10,000
  1274.      LOC, with greatest gains at over 100,000. At these sizes, "just
  1275.      declare it tagged" will result in unmaintainable messes. OO
  1276.      programming in the large rapidly gets difficult with structure based
  1277.      subtyping. Allowing by-value semantics for objects compounds these
  1278.      problems. All of this is known. All of this was, seemingly, ignored
  1279.      by Ada9x.
  1280.  
  1281.  
  1282.    (Tucker Taft answers)
  1283.  
  1284.    As explained in a previous note, Ada 9X supports the ability to hide
  1285.    the implementation heritage of a type, and only expose the desired
  1286.    interface heritage. So we are not stuck with strictly "structure-based
  1287.    subtyping." Secondly, by-reference semantics have many "well known"
  1288.    problems as well, and the designers of Modula-3 chose to, seemingly,
  1289.    ignore those ;-) ;-). Of course, in reality, neither set of language
  1290.    designers ignored either of these issues. Language design involves
  1291.    tradeoffs. You can complain we made the wrong tradeoff, but to
  1292.    continue to harp on the claim that we "ignored" things is silly. We
  1293.    studied every OOP language under the sun on which we could find any
  1294.    written or electronic material. We chose value-based semantics for
  1295.    what we believe are good reasons, based on reasonable tradeoffs.
  1296.  
  1297.    First of all, in the absence of an integrated garbage collector,
  1298.    by-reference semantics doesn't make much sense. Based on various
  1299.    tradeoffs, we decided against requiring an integrated garbage
  1300.    collector for Ada 9X.
  1301.  
  1302.    Secondly, many of the "known" problems with by-value semantics we
  1303.    avoided, by eliminating essentially all cases of "implicit
  1304.    truncation." One of the problems with the C++ version of "value
  1305.    semantics" is that on assignment and parameter passing, implicit
  1306.    truncation can take place mysteriously, meaning that a value that
  1307.    started its life representing one kind of thing gets truncated
  1308.    unintentionally so that it looks like a value of some ancestor type.
  1309.    This is largely because the name of a C++ class means differnt things
  1310.    depending on the context. When you declare an object, the name of the
  1311.    class determines the "exact class" of the object. The same thing
  1312.    applies to a by-value parameter. However, for references and pointers,
  1313.    the name of a class stands for that class and all of its derivatives.
  1314.    But since, in C++, a value of a subclass is always acceptable where a
  1315.    value of a given class is expected, you can get implicit truncation as
  1316.    part of assignment and by-value parameter passing. In Ada 9X, we avoid
  1317.    the implicit truncation because we support assignment for "class-wide"
  1318.    types, which never implicitly truncates, and one must do an explicit
  1319.    conversion to do an assignment that truncates. Parameter passing never
  1320.    implicitly truncates, even if an implicit conversion is performed as
  1321.    part of calling an inherited subprogram.
  1322.  
  1323.    In any case, why not either ignore Ada 9X or give it a fair shot? It
  1324.    is easy to criticize any particular design decision, but it is much
  1325.    harder to actually put together a complete integrated language design
  1326.    that meets the requirements of its user community, doesn't bankrupt
  1327.    the vendor community, and provides interesting fodder for the academic
  1328.    community ;-).
  1329.  
  1330.      _________________________________________________________________
  1331.  
  1332.  
  1333. 6: Ada Numerics
  1334.  
  1335.  
  1336. 6.1: Where can I find anonymous ftp sites for Ada math packages? In particular
  1337. where are the random number generators?
  1338.  
  1339.  
  1340.    bugs.nosc.mil (128.49.4.117)
  1341.           Stuff of high quality in pub/ada The random number generator
  1342.           and random deviates are recommended. These are mirrored at the
  1343.           next site, wuarchive.
  1344.  
  1345.    ftp.rational.com
  1346.           Freeware version of the ISO math packages on Rational's FTP
  1347.           server. It's a binding over the C Math library, in
  1348.           public/apex/freeware/math_lib.tar.Z
  1349.  
  1350.    wuarchive.wustl.edu
  1351.           Site of PAL, the Public Ada Library: math routines scattered
  1352.           about in the directories under languages/ada in particular, in
  1353.           subdirectory swcomps
  1354.  
  1355.    source.asset.com
  1356.           This is not an anonymous ftp site for math software. What you
  1357.           should do is log on anonymously under ftp, and download the
  1358.           file asset.faq from the directory pub. This will tell you how
  1359.           to get an account.
  1360.  
  1361.    ftp.cs.kuleuven.ac.be
  1362.           Go to directory pub/Ada-Belgium/cdrom. There's a collection of
  1363.           math intensive software in directory swcomps. Mirrors some of
  1364.           PAL at wuarchive.wustl.edu.
  1365.  
  1366.    ajpo.sei.cmu.edu
  1367.           Go to directory public/atip/adar to find extended-precision
  1368.           decimal arithmetic. Includes facilities for COBOL-like IO.
  1369.  
  1370.  
  1371. 6.2: How can I write portable code in Ada 83 using predefined types like Float
  1372. and Long_Float? Likewise, how can I write portable code that uses Math
  1373. functions like Sin and Log that are defined for Float and Long_Float?
  1374.  
  1375.    (from Jonathan Parker)
  1376.  
  1377.    Ada 83 was slow to arrive at a standard naming convention for
  1378.    elementary math functions and complex numbers. Furthermore, you'll
  1379.    find that some compilers call the 64-bit floating point type
  1380.    Long_Float; other compilers call it Float. Fortunately, it is easy to
  1381.    write programs in Ada that are independent of the naming conventions
  1382.    for floating point types and independent of the naming conventions of
  1383.    math functions defined on those types.
  1384.  
  1385.    One of the cleanest ways is to make the program generic:
  1386.  
  1387.      generic
  1388.        type Real is digits <>;
  1389.        with function Arcsin (X : Real) return Real is <>;
  1390.        with function    Log (X : Real) return Real is <>;
  1391.        --  This is the natural log, inverse of Exp(X), sometimes written Ln(X).
  1392.      package Example_1 is
  1393.        ...
  1394.      end Example_1;
  1395.  
  1396.  
  1397.    So the above package doesn't care what the name of the floating point
  1398.    type is, or what package the Math functions are defined in, just as
  1399.    long as the floating point type has the right attributes (precision
  1400.    and range) for the algorithm, and likewise the functions. Everything
  1401.    in the body of Example_1 is written in terms of the abstract names,
  1402.    Real, Arcsin, and Log, even though you instantiate it with compiler
  1403.    specific names that can look very different:
  1404.  
  1405.       package Special_Case is new Example_1 (Long_Float, Asin, Ln);
  1406.  
  1407.  
  1408.    The numerical algorithms implemented by generics like Example_1 can
  1409.    usually be made to work for a range of floating point precisions. A
  1410.    well written program will perform tests on Real to reject
  1411.    instantiations of Example_1 if the floating points type is judged
  1412.    inadequate. The tests may check the number of digits of precision in
  1413.    Real (Real'Digits) or the range of Real (Real'First, Real'Last) or the
  1414.    largest exponent of the set of safe numbers (Real'Safe_Emax), etc.
  1415.    These tests are often placed after the begin statement of package
  1416.    body, as in:
  1417.  
  1418.      package body Example_1 is
  1419.        ...
  1420.      begin
  1421.        if (Real'Machine_Mantissa > 60) or (Real'Machine_Emax < 256) then
  1422.          raise Program_Error;
  1423.        end if;
  1424.      end Example_1;
  1425.  
  1426.  
  1427.    Making an algorithm as abstract as possible, (independent of data
  1428.    types as much as possible) can do a lot to improve the quality of the
  1429.    code. Support for abstraction is one of the many things Ada-philes
  1430.    find so attractive about the language. The designers of Ada 95
  1431.    recognized the value of abstraction in the design of numeric
  1432.    algorithms and have generalized many of the features of the '83 model.
  1433.    For example, no matter what floating point type you instantiate
  1434.    Example_1 with, Ada 95 provides you with functions for examining the
  1435.    exponent and the mantissas of the numbers, for truncating, determining
  1436.    exact remainders, scaling exponents, and so on. (In the body of
  1437.    Example_1, and in its spec also of course, these functions are
  1438.    written, respectively: Real'Exponent(X), Real'Fraction(X),
  1439.    Real'Truncation(X), Real'Remainder(X,Y), Real'Scaling(X, N). There are
  1440.    others.) Also, in package Example_1, Ada 95 lets you do the arithmetic
  1441.    on the base type of Real (called Real'Base) which is liable to have
  1442.    greater precision and range than type Real.
  1443.  
  1444.    It is rare to see a performance loss when using generics like this.
  1445.    However, if there is an unacceptable performance hit, or if generics
  1446.    cannot be used for some other reason, then subtyping and renaming will
  1447.    do the job. Here is an example of renaming:
  1448.  
  1449.      with Someones_Math_Lib;
  1450.      procedure Example_2 is
  1451.  
  1452.        subtype Real is Long_Float;
  1453.  
  1454.        package  Math renames Someones_Math_Lib;
  1455.        function Arcsin(X : Real) return Real renames Math.Asin
  1456.        function   Log (X : Real) return Real renames Math.  Ln;
  1457.  
  1458.        --  Everything beyond this point is abstract with respect to
  1459.        --  the names of the floating point (Real), the functions (Arcsin
  1460.        --  and Log), and the package that exported them (Math).
  1461.        ...
  1462.      end Example_2;
  1463.  
  1464.  
  1465.    I prefer to make every package and subprogram (even test procedures)
  1466.    as compiler independent and machine portable as possible. To do this
  1467.    you move all of the renaming of compiler dependent functions and all
  1468.    of the "withing" of compiler dependent packages to a single package.
  1469.    In the example that follows, its called Math_Lib_8. Math_Lib_8 renames
  1470.    the 8-byte floating point type to Real_8, and makes sure the math
  1471.    functions follow the Ada 95 standard, at least in name. In this
  1472.    approach Math_Lib_8 is the only compiler dependent component.
  1473.  
  1474.    There are other, perhaps better, ways also. See for example, "Ada In
  1475.    Action", by Do-While Jones for a generic solution.
  1476.  
  1477.    Here's the spec of Math_Lib_8, which is a perfect subset of package
  1478.    Math_Env_8, available by FTP in file
  1479.    ftp://lglftp.epfl.ch/pub/Ada/FAQ/math_env_8.ada
  1480.  
  1481.  
  1482. --***************************************************************
  1483. -- Package Math_Lib_8
  1484. --
  1485. -- A minimal math package for Ada 83: creates a standard interface to vendor
  1486. -- specific double-precision (8-byte) math libraries.  It renames the 8 byte
  1487. -- Floating point type to Real_8, and uses renaming to create
  1488. -- (Ada 95) standard names for Sin, Cos, Log, Sqrt, Arcsin, Exp,
  1489. -- and Real_8_Floor, all defined for Real_8.
  1490. --
  1491. -- A more ambitious but perhaps less efficient
  1492. -- package would wrap the compiler specific functions in function calls, and
  1493. -- do error handling on the arguments to Ada 95 standards.
  1494. --
  1495. -- The package assumes that Real_8'Digits > 13, and that
  1496. -- Real_8'Machine_Mantissa < 61.  These are asserted after the
  1497. -- begin statement in the body.
  1498. --
  1499. -- Some Ada 83 compilers don't provide Arcsin, so a rational-polynomial+
  1500. -- Newton-Raphson method Arcsin and Arccos pair are provided in the body.
  1501. --
  1502. -- Some Ada 83 compilers don't provide for truncation of 8 byte floats.
  1503. -- Truncation is provided here in software for Compilers that don't have it.
  1504. -- The Ada 95 function for truncating (toward neg infinity) is called 'Floor.
  1505. --
  1506. -- The names of the functions exported below agree with the Ada9X standard,
  1507. -- but not, in all likelihood the semantics.   It is up to the user to
  1508. -- be careful...to do his own error handling on the arguments, etc.
  1509. -- The performance of these function can be non-portable,
  1510. -- but in practice they have their usual meanings unless you choose
  1511. -- weird arguments.  The issues are the same with most math libraries.
  1512. --***************************************************************
  1513.  
  1514. --with Math_Lib;                                  -- Meridian DOS Ada.
  1515.   with Long_Float_Math_Lib;                       -- Dec VMS
  1516. --with Ada.Numerics.Generic_Elementary_Functions; -- Ada9X
  1517. package Math_Lib_8 is
  1518.  
  1519. --subtype Real_8 is Float;                        -- Meridian 8-byte Real
  1520.   subtype Real_8 is Long_Float;                   -- Dec VMS  8-byte Real
  1521.  
  1522.  --package Math renames Math_Lib;                 -- Meridian DOS Ada
  1523.    package Math renames Long_Float_Math_Lib;      -- Dec VMS
  1524.  --package Math is new Ada.Numerics.Generic_Elementary_Functions(Real_8);
  1525.  
  1526.    --  The above instantiation of the Ada.Numerics child package works on
  1527.    --  GNAT, or any other Ada 95 compiler.  Its here if you want to use
  1528.    --  an Ada 95 compiler to compile Ada 83 programs based on this package.
  1529.  
  1530.    function Cos (X : Real_8) return Real_8 renames Math.Cos;
  1531.    function Sin (X : Real_8) return Real_8 renames Math.Sin;
  1532.    function Sqrt(X : Real_8) return Real_8 renames Math.Sqrt;
  1533.    function Exp (X : Real_8) return Real_8 renames Math.Exp;
  1534.  
  1535.  --function Log (X : Real_8) return Real_8 renames Math.Ln;        -- Meridian
  1536.    function Log (X : Real_8) return Real_8 renames Math.Log;       -- Dec VMS
  1537.  --function Log (X : Real_8) return Real_8 renames Math.Log;       -- Ada 95
  1538.  
  1539.  --function Arcsin (X : Real_8) return Real_8 renames Math.Asin;   -- Dec VMS
  1540.  --function Arcsin (X : Real_8) return Real_8 renames Math.Arcsin; -- Ada 95
  1541.    function Arcsin (X : Real_8) return Real_8;
  1542.    --  Implemented in the body.  Should work with any compiler.
  1543.  
  1544.  --function Arccos (X : Real_8) return Real_8 renames Math.Acos;   -- Dec VMS
  1545.  --function Arccos (X : Real_8) return Real_8 renames Math.Arccos; -- Ada 95
  1546.    function Arccos (X : Real_8) return Real_8;
  1547.    --  Implemented in the body.  Should work with any compiler.
  1548.  
  1549.  --function Real_8_Floor (X : Real_8) return Real_8 renames Real_8'Floor;-- 95
  1550.    function Real_8_Floor (X : Real_8) return Real_8;
  1551.    --  Implemented in the body.  Should work with any compiler.
  1552.  
  1553. end Math_Lib_8;
  1554.  
  1555.  
  1556. 6.3: Where's a good place to start learning the Ada 95 numerics model?
  1557.  
  1558.    (from Jonathan Parker)
  1559.  
  1560.    Start with the Ada 95 Rationale. Part 3 of the Rationale, Section 1.3
  1561.    provides a good introduction, with examples on use of elementary
  1562.    function packages. Part 3 of the Rationale, Section 6.1 discusses the
  1563.    design of the Complex number and Complex function packages. Section 6
  1564.    reviews the numerics annex, especially attributes and accuracy
  1565.    requirement.
  1566.  
  1567.    The Rationale can be obtained by anonymous ftp from ajpo.sei.cmu.edu.
  1568.    Another site to get the Ada 95 Rationale from is the Ada WWW homepage
  1569.    at http://lglwww.epfl.ch/Ada/ .
  1570.  
  1571.    The Ada 95 Reference Manual describes the Real valued elementary Math
  1572.    functions, the Random number packages, and the floating point
  1573.    attributes in section A5 (page 295). The Ada 95 Reference Manual may
  1574.    be obtained by anonymous ftp from ajpo.sei.cmu.edu, in directory
  1575.    public/ada9x/rm9x.
  1576.  
  1577.  
  1578. 6.4: How do I get Real valued and Complex valued math functions in Ada 95?
  1579.  
  1580.    (from Jonathan Parker)
  1581.  
  1582.    Complex type and functions are provided by compilers that support the
  1583.    numerics Annex. The packages that use Float for the Real number and
  1584.    for the Complex number are:
  1585.  
  1586.      Ada.Numerics.Elementary_Functions;
  1587.      Ada.Numerics.Complex_Types;
  1588.      Ada.Numerics.Complex_Elementary_Functions;
  1589.  
  1590.  
  1591.    The packages that use Long_Float for the Real number and for the
  1592.    Complex number are:
  1593.  
  1594.      Ada.Numerics.Long_Elementary_Functions;
  1595.      Ada.Numerics.Long_Complex_Types;
  1596.      Ada.Numerics.Long_Complex_Elementary_Functions;
  1597.  
  1598.  
  1599.    The generic versions are demonstrated in the following example. Keep
  1600.    in mind that the non-generic packages may have been better tuned for
  1601.    speed or accuracy. In practice you won't always instantiate all three
  1602.    packages at the same time, but here is how you do it:
  1603.  
  1604.      with Ada.Numerics.Generic_Complex_Types;
  1605.      with Ada.Numerics.Generic_Elementary_Functions;
  1606.      with Ada.Numerics.Generic_Complex_Elementary_Functions;
  1607.  
  1608.      procedure Do_Something_Numerical is
  1609.  
  1610.        type Real_8 is digits 15;
  1611.  
  1612.        package Real_Functions_8 is
  1613.          new Ada.Numerics.Generic_Elementary_Functions (Real_8);
  1614.  
  1615.        package Complex_Nums_8 is
  1616.          new Ada.Numerics.Generic_Complex_Types (Real_8);
  1617.  
  1618.        package Complex_Functions_8 is
  1619.          new Ada.Numerics.Generic_Complex_Elementary_Functions
  1620.            (Complex_Nums_8);
  1621.  
  1622.        use Real_Functions_8, Complex_Nums_8, Complex_Functions_8;
  1623.        ...
  1624.        ... -- Do something
  1625.        ...
  1626.      end Do_Something_Numerical;
  1627.  
  1628.  
  1629. 6.5: What libraries or public algorithms exist for Ada?
  1630.  
  1631.    An Ada version of Fast Fourier Transform is available. It's in
  1632.    journal "Computers & Mathematics with Applications," vol. 26, no. 2,
  1633.    pp. 61-65, 1993, with the title:
  1634.  
  1635.    "Analysis of an Ada Based Version of Glassman's General N Point Fast
  1636.    Fourier Transform"
  1637.  
  1638.    The package is now available in the AdaNET repository, object #: 6728,
  1639.    in collection: Transforms. If you're not an AdaNET user, contact Peggy
  1640.    Lacey (lacey@rbse.mountain.net).
  1641.  
  1642.      _________________________________________________________________
  1643.  
  1644.  
  1645. 7: Efficiency of Ada Constructs
  1646.  
  1647.  
  1648. 7.1: How much extra overhead do generics have?
  1649.  
  1650.    If you overgeneralize the generic, there will be more work to do for
  1651.    the compiler. How do you know when you have overgeneralized? For
  1652.    instance, passing arithmetic operations as parameters is a bad sign.
  1653.    So are boolean or enumeration type generic formal parameters. If you
  1654.    never override the defaults for a parameter, you probably
  1655.    overengineered.
  1656.  
  1657.    Code sharing (if implemented and requested) will cause an additional
  1658.    overhead on some calls, which will be partially offset by improved
  1659.    locality of reference. (Translation, code sharing may win most when
  1660.    cache misses cost most.) If a generic unit is only used once in a
  1661.    program, code sharing always loses.
  1662.  
  1663.    R.R. Software chose code sharing as the implementation for generics
  1664.    because 2 or more instantiations of Float_Io in a macro implementation
  1665.    would have made a program too large to run in the amount of memory
  1666.    available on the PC machines that existed in 1983 (usually a 128k or
  1667.    256k machine).
  1668.  
  1669.    Generics in Ada can also result in loss of information which could
  1670.    have helped the optimizer. Since the compiler is not restricted by Ada
  1671.    staticness rules within a single module, you can often avoid penalties
  1672.    by declaring (or redeclaring) bounds so that they are local:
  1673.  
  1674.      package Global is
  1675.        subtype Global_Int is
  1676.          Integer range X..Y;
  1677.  
  1678.        ...
  1679.      end Global;
  1680.  
  1681.  
  1682.      with Global;
  1683.      package Local is
  1684.        subtype Global_Int is
  1685.          Global.Global_Int;
  1686.  
  1687.        package Some_Instance is
  1688.          new Foo (Global_Int);
  1689.  
  1690.        ...
  1691.      end Local;
  1692.  
  1693.  
  1694.    Ada rules say that having the subtype redeclared locally does not
  1695.    affect staticness, but on a few occasions optimizers have been caught
  1696.    doing a much better job. Since optimizers are constantly changing,
  1697.    they may have been caught just at the wrong time.
  1698.  
  1699.      _________________________________________________________________
  1700.  
  1701.  
  1702. 8: Advanced Programming Techniques with Ada
  1703.  
  1704.  
  1705. 8.1: Does Ada have automatic constructors and destructors?
  1706.  
  1707.    (Tucker Taft replies)
  1708.  
  1709.    At least in Ada 9X, functions with controlling results are inherited
  1710.    (even if overriding is required), allowing their use with dynamic
  1711.    binding and class-wide types. In most other OOPs, constructors can
  1712.    only be called if you know at compile time the "tag" (or equivalent)
  1713.    of the result you want. In Ada 9X, you can use the tag determined by
  1714.    the context to control dispatching to a function with a controlling
  1715.    result. For example:
  1716.  
  1717.      type Set is abstract tagged private;
  1718.      function  Empty return Set is abstract;
  1719.      function  Unit_Set(Element : Element_Type) return Set is abstract;
  1720.      procedure Remove(S : in out Set; Element : out Element_Type) is abstract;
  1721.      function  Union(Left, Right : Set) return Set is abstract;
  1722.   ...
  1723.  
  1724.      procedure Convert(Source : Set'Class; Target : out Set'Class) is
  1725.        -- class-wide "convert" routine, can convert one representation
  1726.        --   of a set into another, so long as both set types are
  1727.        --   derived from "Set," either directly or indirectly.
  1728.  
  1729.        -- Algorithm:  Initialize Target to the empty set, and then
  1730.        --             copy all elements from Source set to Target set.
  1731.  
  1732.         Copy_Of_Source : Set'Class := Source;
  1733.         Element : Element_Type;
  1734.      begin
  1735.         Target := Empty;  -- Dispatching for Empty determined by Target'Tag.
  1736.  
  1737.         while Copy_Of_Source /= Empty loop
  1738.                        -- Dispatching for Empty based on Copy_Of_Source'Tag
  1739.  
  1740.             Remove_Element(Copy_Of_Source, Element);
  1741.  
  1742.             Target := Union(Target, Unit_Set(Element));
  1743.                        -- Dispatching for Unit_Set based on Target'Tag
  1744.         end loop;
  1745.      end Convert;
  1746.  
  1747.  
  1748.    The functions Unit_Set and Empty are essentially "constructors" and
  1749.    hence must be overridden in every extension of the abstract type Set.
  1750.    However, these operations can still be called with a class-wide
  1751.    expected type, and the controlling tag for the function calls will be
  1752.    determined at run-time by the context, analogous to the kind of
  1753.    (compile-time) overload resolution that uses context to disambiguate
  1754.    enumeration literals and aggregates.
  1755.  
  1756.  
  1757. 8.2: How can I redefine assignment operations?
  1758.  
  1759.    See "Tips and Tidbits #1: User Defined Assignment" by Brad Balfour
  1760.    (where is this located?)
  1761.  
  1762.  
  1763. 8.3: Should I stick to a one package, one type approach while writing Ada
  1764. software?
  1765.  
  1766.    (Robb Nebbe responds)
  1767.  
  1768.    Off hand I can think of a couple of advantages from separating the
  1769.    concepts of type and module in Ada.
  1770.  
  1771.    Separation of visibility and inheritance allows a programmer to
  1772.    isolate a derived type from the implementation details of its parent.
  1773.    To put it another way information hiding becomes a design decision
  1774.    instead of a decision that the programming language has already made
  1775.    for you.
  1776.  
  1777.    Another advantage that came "for free" is the distinction between
  1778.    subtyping and implementation inheritance. Since modules and types are
  1779.    independent concepts the interaction of the facilities for information
  1780.    hiding already present in Ada83 with inheritance provide an elegant
  1781.    solution to separating subtyping from implementation inheritance. (In
  1782.    my opinion more elegant than providing multiple forms of inheritance
  1783.    or two distinct language constructs.)
  1784.  
  1785.  
  1786. 8.4: What is the "Beaujolais Effect"?
  1787.  
  1788.    The "Beaujolais Effect" is detrimental, and language designers should
  1789.    try to avoid it. But what is it?
  1790.  
  1791.    (from Tucker Taft)
  1792.  
  1793.    The term "Beaujolais Effect" comes from a prize (a bottle of
  1794.    Beaujolais) offered by Jean Ichbiah during the original Ada design
  1795.    process to anyone who could find a situation where adding or removing
  1796.    a single "use" clause could change a program from one legal
  1797.    interpretation to a different legal interpretation. (Or equivalently,
  1798.    adding or removing a single declaration from a "use"d package.)
  1799.  
  1800.    At least one bottle was awarded, and if the offer was still open, a
  1801.    few more might have been awarded during the Ada 9X process. However,
  1802.    thanks to some very nice analysis by the Ada 9X Language Precision
  1803.    Team (based at Odyssey Research Associates) we were able to identify
  1804.    the remaining cases of this effect in Ada 83, and remove them as part
  1805.    of the 9X process.
  1806.  
  1807.    The existing cases in Ada 83 had to do with implicit conversion of
  1808.    expressions of a universal type to a non-universal type. The rules in
  1809.    Ada 9X are subtly different, making any case that used to result in a
  1810.    Beaujolais effect in Ada 83, illegal (due to ambiguity) in Ada 9X.
  1811.  
  1812.    The Beaujolais effect is considered "harmful" because it is expected
  1813.    that during maintenance, declarations may be added or removed from
  1814.    packages without being able to do an exhaustive search for all places
  1815.    where the package is "use"d. If there were situations in the language
  1816.    which resulted in Beaujolais effects, then certain kinds of changes in
  1817.    "use"d packages might have mysterious effects in unexpected places.
  1818.  
  1819.    (from Jean D. Ichbiah)
  1820.  
  1821.    It is worth pointing that many popular languages have Beaujolais
  1822.    effect: e.g. the Borland Pascal "uses" clause, which takes an
  1823.    additive, layer-after-layer, interpretation of what you see in the
  1824.    used packages (units) definitely exhibits a Beaujolais effect.
  1825.  
  1826.    Last time I looked at C++, my impression was that several years of
  1827.    Beaujolais vintage productions would be required.
  1828.  
  1829.    For component-based software development, such effects are undesirable
  1830.    since your application may stop working when you recompile it with the
  1831.    new -- supposedly improved -- version of a component.
  1832.  
  1833.  
  1834. 8.5: What about the "Ripple Effect"?
  1835.  
  1836.    (Tucker Taft explains)
  1837.  
  1838.    We have eliminated all remnants of the Beaujolais Effect, but we did
  1839.    debate various instances of the "Ripple" effect during the language
  1840.    revision process (apologies to Gallo Ripple Wine enthusiasts ;-).
  1841.  
  1842.    In brief, the (undesirable) Ripple effect was related to whether the
  1843.    legality of a compilation unit could be affected by adding or removing
  1844.    an otherwise unneeded "with" clause on some compilation unit on which
  1845.    the unit depended, directly or indirectly.
  1846.  
  1847.    This issue came up at least twice. One when we were considering rules
  1848.    relating to use of attributes like 'Address. In Ada 83 as interpreted
  1849.    by the ARG, if a compilation unit contains a use of 'Address, then
  1850.    there must be a "with" of package System somewhere in the set of
  1851.    library unit specs "with"ed by the compilation unit (directly or
  1852.    indirectly).
  1853.  
  1854.    In Ada 9X, we have eliminated this rule, as it was for some compilers
  1855.    an unnecessary implementation burden, and didn't really provide any
  1856.    value to the user (if anything, it created some confusion). The rule
  1857.    now is that the use of an attibute that returns a value of some
  1858.    particular type makes the compilation unit semantically dependent on
  1859.    the library unit in which the type is declared (whether or not it is
  1860.    "with"ed).
  1861.  
  1862.    The second place the Ripple effect came up was when we were trying to
  1863.    provide automatic direct visibility to (primitive) operators.
  1864.    Ultimately we ended up with an explicit "use type" clause for making
  1865.    operators directly visible. For a while we considered various rules
  1866.    that would make all primitive operators directly visible; some of the
  1867.    rules considered created the undesirable "Ripple" effects; others
  1868.    created annoying incompatibilities; all were quite tricky to implement
  1869.    correctly and efficiently.
  1870.  
  1871.      _________________________________________________________________
  1872.  
  1873.  
  1874. 9: Ada and Other Programming Languages
  1875.  
  1876.  
  1877. 9.1: Where can I find programs that will translate from (some language) to
  1878. Ada?
  1879.  
  1880.    (Job Honig)
  1881.  
  1882.    Probably not the answer you like to hear, but my advice would be to
  1883.    redesign the code, employing your knowledge of the current system, of
  1884.    course. I have done this twice, once for Coco, a parser generator for
  1885.    LALR left attributed grammars, and once for Flex, the well known
  1886.    scanner generator. Both attempts revealed errors in the original
  1887.    software, that were uncovered by designing the new system using the
  1888.    higher abstraction level allowed by Ada...
  1889.  
  1890.    So I would support your requirements analysis (transition to Ada), but
  1891.    not your proposed implementation (using a source code translator).
  1892.  
  1893.    (no longer Job Honig :-)
  1894.  
  1895.    Otherwise, it is generally advisable to simply interface to code that
  1896.    already works. Still, you may have compelling reasons to translate
  1897.    your existing source to Ada. In that case, here is a list of available
  1898.    translators:
  1899.  
  1900.      * Pascal to Ada:
  1901.  
  1902.        R.R. Software's Pastran program (Pascal to Ada Translator).
  1903.  
  1904.        To see the differences in programming style, see "Ada for
  1905.        Experienced Programmers", by A. Nico Habermann and Dewayne E.
  1906.        Perry (Addison-Wesley Pub. Co., Reading, Mass., 1983). Covers Ada
  1907.        and Pascal.
  1908.  
  1909.      * Fortran to Ada: ???
  1910.  
  1911.      * COBOL to Ada: ???
  1912.  
  1913.      * C++ to Ada: ???
  1914.  
  1915.      * C to Ada: ???
  1916.  
  1917.      * Modula-2 to Ada:
  1918.  
  1919.        (from Wayne R. Lawton)
  1920.        The Idaho National Engineering Laboratory (INEL), a Dept of Energy
  1921.        Lab has a basic capability for Modula-2 to Ada-83. The tool is
  1922.        "research grade" quality, but may provide a starting point for
  1923.        what you need. This is the same group of people who brought you
  1924.        AdaSAGE. Give them a ring at (208) 526-0656. This is an answer
  1925.        desk hotline in the section that wrote the tool.
  1926.  
  1927.        If you are looking for commercial quality, I wish you the best of
  1928.        luck. If you just need something to perform 80% of the grunt code
  1929.        translation, I think this might meet your needs. I know of two
  1930.        systems comprising about 250,000 lines of code that were
  1931.        originally developed in Modula-2 then translated and cleaned up in
  1932.        Ada 83 after Alsys 1.0 for the PC came out back around 1987.
  1933.  
  1934.      * Visual Basic to Ada: NOT! :-)
  1935.  
  1936.  
  1937. 9.2: How can I convert Ada 83 sources to Ada 9X?
  1938.  
  1939.    First you should read the following document, which will provide you
  1940.    with much useful information: "Changes to Ada -- 1987 to 1995", file
  1941.    ch83.{ps,doc}, in directory
  1942.    ftp://ajpo.sei.cmu.edu/public/ada9x/mrtcomments/rm9x/v5.95
  1943.  
  1944.    If you're using GNAT, the tool you are probably looking for is
  1945.    "gnatchop". In csh you could use something like this to quickly
  1946.    process existing files:
  1947.  
  1948.      cd dest_dir                    # The destination directory
  1949.      foreach f ( ../src_dir/*.a )   # ../src_dir is the source directory
  1950.        gnatchop $f
  1951.      end
  1952.  
  1953.    gnatchop will show you what sources are causing problems.
  1954.  
  1955.  
  1956. 9.3: I hear that Ada is slower than Fortran or C, is that true?
  1957.  
  1958.    First, note that you are comparing compilers, not languages. There is
  1959.    no such thing as "fast" Ada code any more than there is "fast" C++ or
  1960.    Fortran code. Now, when comparing execution speeds on similar
  1961.    platforms, you must keep in mind the optimization levels, OS tuning,
  1962.    etc. while making the comparisons. The bottom line is that
  1963.    benchmarking, especially between two different languages, requires
  1964.    _very_ careful measurement. In general, such results should be viewed
  1965.    with caution.
  1966.  
  1967.    (A message from Bevin Brett of DEC)
  1968.  
  1969.    I have been asked to comment on the relative performance of algorithms
  1970.    coded in Ada and in Fortran.
  1971.  
  1972.    This question has come up repeatedly over the years, and deserves a
  1973.    complete answer, rather than a simplistic one.
  1974.  
  1975.    There are many factors which influence the size and execution speed of
  1976.    the running program, and they all play together to get a full answer.
  1977.    I shall then discuss an exact Ada v. Fortran comparison that Digital
  1978.    was involved in.
  1979.  
  1980.    First, a position statement: The variation between Ada and Fortran is
  1981.    less than the variation within the language caused by the exact
  1982.    implementation details. A person versed in the Ada issues should do as
  1983.    well in Ada as a person versed in the Fortran issues will do in
  1984.    Fortran. The size and execution speed of the result should be within a
  1985.    few percent of each other.
  1986.  
  1987.    (a) Differences due to the compiler
  1988.  
  1989.    In the case of the DEC Ada and Fortran compilers, the optimizer and
  1990.        code generator are the same. Never-the-less, the exact inputs into
  1991.        the optimizer and code generator may differ slightly when the same
  1992.        algorithm is compiled by the Ada and Fortran compilers, and this
  1993.        can result in major differences in the generated code. In these
  1994.        cases the compiler front ends can usually be modified to correct
  1995.        the slower one.
  1996.  
  1997.        We have not observed any major differences in generated code
  1998.        quality between the DEC Ada and DEC Fortran compilers caused by
  1999.        such issues.
  2000.  
  2001.  
  2002.    (b) Differences due to the language
  2003.  
  2004.    It is very important that the same algorithm be written in the two
  2005.        languages. The biggest differences we have observed are
  2006.          1. Having the wrong dimension varying fastest, since it is
  2007.             desireable to have the first dimension changing fastest in
  2008.             Fortran, and the last dimension in Ada. Thus when an
  2009.             algorithm is transliterated, the array indexes must be
  2010.             reversed.
  2011.  
  2012.          2. Using compile-time-known bounds for arrays in Fortran, and
  2013.             using unconstrained arrays in the Ada code. Knowing the exact
  2014.             values of the dimensions at compile-time results in much
  2015.             better code.
  2016.  
  2017.          3. Not suppressing all the runtime checks in Ada. The Fortran
  2018.             compiler assumes all array bounds are in range, and all
  2019.             arithmetic operations do not overflow. You must use a pragma
  2020.             Suppress to tell this to the Ada compiler as well.
  2021.  
  2022.          4. Don't use arrays of Ada Booleans to match arrays of Fortran
  2023.             Integers, because accessing bytes on a RISC system might be
  2024.             much worse than accessing fullwords.
  2025.  
  2026.  
  2027.    (c) Differences due to the bindings
  2028.  
  2029.    The biggest bindings differences are related to Fortran's built-in
  2030.        support for complex types, and for various math routines such as
  2031.        SQRT and SIN, compared with Ada code that often uses hand-coded or
  2032.        ISO standardised versions of these functions with different
  2033.        requirements than are imposed on the Fortran versions.
  2034.  
  2035.        DEC Ada has built-in support for complex types, and also has
  2036.        bindings directly to the same primitives that Fortran uses for its
  2037.        math routines and so gets the same performance as Fortran does.
  2038.  
  2039.  
  2040.    (d) Differences due to the author
  2041.  
  2042.    The use of good Ada and Fortran style can also effect the generated
  2043.        code. Provided the author writes in good Ada style, and follows
  2044.        the above guidelines, the generated code should do as well as
  2045.        Fortran.
  2046.  
  2047.  
  2048.     The Ada Performance Benchmark
  2049.  
  2050.    A DEC Ada customer had a Fortran benchmark that had been translated
  2051.    into Ada without awareness of the above issues, and was running
  2052.    substantially slower with DEC Ada than the original was with DEC
  2053.    Fortran.
  2054.  
  2055.    Bevin Brett, a DEC Ada team member, developed the above guidelines in
  2056.    the process of retranslating the code into Ada.
  2057.  
  2058.    Portions of this translation are shown here (a) as an illustration of
  2059.    the application of the above rules, and (b) as an illustration of the
  2060.    kind of operations that were present in the benchmark.
  2061.  
  2062.    The whole benchmark has not been provided to avoid possible issues of
  2063.    ownership.
  2064.  
  2065.    The resulting Ada benchmark components each ran within a few percent
  2066.    of their Fortran counterparts. The Ada code is available by FTP, in
  2067.    file ftp://lglftp.epfl.ch/pub/Ada/FAQ/ada-vs-fortran.ada
  2068.  
  2069.  
  2070. Archive-name: computer-lang/Ada/programming/part3
  2071. Comp-lang-ada-archive-name: programming/part3
  2072. Posting-Frequency: monthly
  2073. Last-modified: 7 February 1995
  2074. Last-posted: 19 January 1995
  2075.  
  2076.                                Ada Programmer's
  2077.                        Frequently Asked Questions (FAQ)
  2078.  
  2079.    IMPORTANT NOTE: No FAQ can substitute for real teaching and
  2080.    documentation. There is an annotated list of Ada books in the
  2081.    companion comp.lang.ada FAQ.
  2082.  
  2083. This is part 3 of a 3-part posting.
  2084. Part 2 begins with question 5.6.
  2085. Parts 1 and 2 should be the previous postings in this thread.
  2086.  
  2087.  
  2088. 9.4: Isn't Ada less "elegant" than Eiffel?
  2089.  
  2090.    While it is true that programming-language support for "assertions"
  2091.    is an important contribution of Eiffel to software construction, this
  2092.    is not an issue of "elegance", and there are many other important
  2093.    factors to consider.
  2094.  
  2095.    Note also that preconditions and postconditions can be fairly easily
  2096.    and efficiently included in Ada code. Invariants seem difficult to
  2097.    emulate directly in Ada. If you're really interested in the formal use
  2098.    of assertions with Ada, maybe Anna is a solution for you.
  2099.  
  2100.    (Tucker Taft comments)
  2101.  
  2102.    I guess one thing that bothers me a little is that people are quick to
  2103.    say that Eiffel is "elegant" without really looking at it. I fear that
  2104.    such statements will become self-fulfilling prophecies, with those
  2105.    programmers interested in elegance migrating over to Eiffel rather
  2106.    than sticking with Ada.
  2107.  
  2108.    In particular, although I like the assertion stuff in Eiffel, I think
  2109.    the language has a number of "inelegant" aspects. For example:
  2110.  
  2111.     1. exception handlers only at the top level of a routine, with the
  2112.        only way to "handle" an exception being by retrying the whole
  2113.        routine.
  2114.  
  2115.     2. No way to return from a routine in the middle. This makes it a
  2116.        pain in the neck to search through a list for something in a loop,
  2117.        and then return immediately when you find what you want. (I have
  2118.        never found the addition of extra boolean control variable a help
  2119.        to the understanding of an algorithm.)
  2120.  
  2121.     3. Namespace control handled by a separate sublanguage, and no real
  2122.        higher level concept of "module" or "subsystem."
  2123.  
  2124.     4. An obscure notation like "!!" being used for an important and
  2125.        frequent operation (construction).
  2126.  
  2127.     5. No way to conveniently "use" another abstraction without
  2128.        inheriting from it.
  2129.  
  2130.     6. No strong distinctions between integer types used for array
  2131.        indexing.
  2132.  
  2133.     7. Using the same operator ":=" for both (aliasing) pointer
  2134.        assignment, and for value assignment, depending on whether the
  2135.        type is "expanded." (Simula's solution was far preferable, IMHO).
  2136.  
  2137.     And most critically:
  2138.  
  2139.  
  2140.     8. No separate interface for an abstraction. You can view a interface
  2141.        by running a tool, but this misses completely the importance of
  2142.        having a physical module that represents the interface, and acts
  2143.        as a contract between the specifier or user of an abstraction and
  2144.        its implementor. In Eiffel, one might not even be truly aware when
  2145.        one is changing the interface to an abstraction, because there is
  2146.        no particular physical separation between interface and
  2147.        implementation.
  2148.  
  2149.  
  2150.    I consider many of the above problems quite serious, with some of them
  2151.    being real throwbacks to the old style of programming languages where
  2152.    there were no well defined interfaces or modules.
  2153.  
  2154.    Hence, I cringe a bit when people say that Eiffel is the "most
  2155.    elegant" OOP and that they would use it if only it were practical to
  2156.    do so. In many ways, I think Ada is much better human-engineered than
  2157.    Eiffel, with important things like range constraints built into the
  2158.    language in a way that makes them convenient to use. Although general
  2159.    assertions are nice, they don't give you the kind of line-by-line
  2160.    consistency checks that Ada can give you.
  2161.  
  2162.    To summarize --
  2163.    Although Eiffel certainly has a number of nice features, I don't
  2164.    consider it ready for prime time as far as building and maintaining
  2165.    large systems with large numbers of programmers. And from a human
  2166.    engineering point of view, I think Ada is significantly better.
  2167.  
  2168.  
  2169. 9.5: Are there any papers detailing the differences between Ada and C++?
  2170.  
  2171.    Below are two references. Bear in mind that it is difficult to make
  2172.    such a comparison without exposing biases. However, the two papers
  2173.    below are well worth reading.
  2174.  
  2175.    "A Comparison of the OO features of Ada9x and C++" in Springer Lecture
  2176.    Notes in CS: "Ada Europe 93" pp.125-141 (short paper, good reading,
  2177.    enlightens idioms)
  2178.  
  2179.    ftp ajpo.sei.cmu.edu in directory: /public/ada9x, document:
  2180.    9x_cplus.hlp
  2181.  
  2182.  
  2183. 9.6: I keep hearing that Ada is a "strongly typed language", but it seems
  2184. different from what's meant in C++. Are they different?
  2185.  
  2186.    (Tucker Taft responds)
  2187.  
  2188.    I certainly agree that ANSI C and C++ are statically typed languages,
  2189.    but I would debate the "strength" of their typing.
  2190.  
  2191.    Essentially any support for implicit conversion (implicit "casting,"
  2192.    "promotion", "usual" arithmetic conversions, etc.) "weakens" a type
  2193.    system (but also makes it "friendlier" in some ways).
  2194.  
  2195.    C allows implicit conversion between all integer types and all
  2196.    enumeration types. C++ at least cuts off implicit conversion to
  2197.    enumeration types, but retains implicit conversion among all integer
  2198.    (and floating-point) types. Also, in both C and C++, typedefs for
  2199.    pointer/array types are essentially "macros"; all pointer types with
  2200.    the same target type are implicitly interconvertible.
  2201.  
  2202.    Finally C++ allows the user to define a number of their own implicit
  2203.    conversion operators, which basically allows the user to "weaken" the
  2204.    type system as they see fit.
  2205.  
  2206.    Of course, all of this implicit conversion serves a purpose, but it
  2207.    does tend to move C/C++ toward the "weaker" end of the weak vs. strong
  2208.    typing spectrum.
  2209.  
  2210.    Note that the "strong" distinctions between integer types helps
  2211.    dramatically in catching (at compile-time) array indexing errors in
  2212.    Ada programs, by making sure that if you have an array indexed by a
  2213.    count of apples, you don't index into it with a count of oranges
  2214.    (without an *explicit* conversion). The advantages of "strongly"
  2215.    distinguishing enumeration types is even more obvious (and the
  2216.    designers of C++ recognized this).
  2217.  
  2218.    The strong distinctions between access types (pointer types) in Ada
  2219.    also has advantages, allowing access types to be represented as
  2220.    offsets within their storage pool rather than as addresses, and giving
  2221.    more high-level control over storage management.
  2222.  
  2223.    Strong typing can be carried too far, and some amount of implicit
  2224.    conversion is essential to make OOP palatable. But note that in Ada
  2225.    9X, even with OOP, we don't allow implicit conversions that truncate
  2226.    the extension part of a record (this is a relatively common mistake in
  2227.    C++ when passing parameters by value). Instead, in Ada 9X, the
  2228.    language distinguishes between a specific type T and the class-wide
  2229.    type T'Class, and allows implicit conversions to T'Class from T or any
  2230.    of its derivatives, but not to the specific type T. Conversions to the
  2231.    class-wide type never implicitly truncate the extension part.
  2232.    Conversions to a specific type can truncate, and hence must be
  2233.    explicit.
  2234.  
  2235.    Note also that in Ada there are three distinct kinds of conversions,
  2236.    implicit ones, explicit ones, and unchecked ones. Only the unchecked
  2237.    ones are potentially unsafe. The explicit ones are safe, with either
  2238.    compile-time or run-time checks to ensure that. In C there are only
  2239.    implicit and explicit/unchecked conversions. C++ has recently added a
  2240.    checked, explicit "dynamic" cast, but still it will be common to use
  2241.    "normal" explicit casts for both checked and unchecked conversions,
  2242.    thereby making it more difficult to identify places where the type
  2243.    system might be compromised.
  2244.  
  2245.    Hence, the bottom line is that the type checking is (objectively)
  2246.    "stronger" in Ada than C/C++, though that doesn't necessarily mean
  2247.    "better" -- whether one is "better" for a particular style of
  2248.    programming than the other is a "religious" issue IMHO. I know my
  2249.    religion currently favors the stronger checking of Ada in most cases
  2250.    [except perhaps for multiply/divide, where I personally believe the
  2251.    checking should either be weaker, or directly support the concept of
  2252.    "units"/"dimensions"].
  2253.  
  2254.  
  2255. 9.7: I'm told Ada does all sorts of static type checking, but can't you get
  2256. the same effect using a tool like "lint" with C?
  2257.  
  2258.    No, here are a few reasons why (this list is by no means complete):
  2259.  
  2260.    (Submitted by Norm Cohen)
  2261.      * Running both Lint and a C compiler requires the program text to be
  2262.        parsed and semantically analyzed twice. The results of an Ada
  2263.        compiler's parse and semantic analysis are used directly in
  2264.        performing consistency checks.
  2265.  
  2266.      * The rules of Ada provide the opportunity for stronger consistency
  2267.        checks than are possible with C. For example, an Ada programmer
  2268.        can declare distinct integer types to represent distinct
  2269.        abstractions. An Ada compiler will catch an inadvertent
  2270.        intermixing of these two types, but there is no way a
  2271.        corresponding distinction can be made in C, so there is no way for
  2272.        Lint to perform a corresponding check. Similarly, in C, a pointer
  2273.        to an object of type T is indistinguishable from an array of
  2274.        objects of type T.
  2275.  
  2276.      * The rules of the Ada language ensure that the program text
  2277.        provides information allowing PRECISE consistency checks. For
  2278.        example, the expression in an Ada case statement can be written to
  2279.        have a static subtype, allowing the compiler to ascertain that all
  2280.        possible values have been covered without resorting to a default
  2281.        (when others) arm.
  2282.  
  2283.      * With lack of precise information, Lint has no choice but to be
  2284.        overly pessimistic or, with different settings for a complicated
  2285.        set of options, overly optimistic. When it is overly pessimistic,
  2286.        the user sees too many "false alarms" and may end up ignoring
  2287.        valid warnings. When it is overly optimistic, Lint overlooks
  2288.        certain errors.
  2289.  
  2290.      * It is impossible to forget to run consistency checks when using an
  2291.        Ada compiler. (Of course a C programming environment could be set
  2292.        up so that the C compiler could only be invoked from a script that
  2293.        also invokes Lint.)
  2294.  
  2295.      * A compilation that fails Ada consistency checks is rejected. A
  2296.        compilation that fails Lint consistency checks may still be
  2297.        compiled, and its object file used (intentionally or accidently)
  2298.        in building the system. (One cannot automate the rejection of
  2299.        programs that fail Lint unless one is certain that there will
  2300.        never be any false warnings.)
  2301.  
  2302.      * Ada enforces consistency among separately compiled units.
  2303.  
  2304.  
  2305.    Of course even stronger arguments can be made about Ada's RUN-TIME
  2306.    checks (which can be used with little additional overhead because the
  2307.    information contained in an Ada program and the knowledge that the
  2308.    program has passed compile-time consistency checks make it possible to
  2309.    optimize away the majority of the checks). These checks, which are
  2310.    absent in C, tend to smoke out errors early by detecting internal
  2311.    inconsistencies that might not otherwise be detected during testing.
  2312.    This reduces the likelihood of fielding a system that appears to work
  2313.    well during testing but fails in operational use.
  2314.  
  2315.  
  2316. 9.8: Does Ada have something like the Standard Template Library (STL) in C++,
  2317. or components like you find in Smalltalk environments?
  2318.  
  2319.    Yes, in various ways.
  2320.  
  2321.    Few components are part of the ISO standard. Ada 95 has an expanded
  2322.    set of predefined library units, covering e.g. strings of varying- or
  2323.    dynamic-length, elementary numerical functions, random number
  2324.    generators, complex numbers, and more; in addition, the Special Needs
  2325.    Annexes standardize many advanced services which have commonly been
  2326.    provided by separate components in the past.
  2327.  
  2328.    A lot of free Ada software components are available from anonymous FTP
  2329.    sites. There is also an upcoming release of the Booch Components for
  2330.    Ada 95 under the GNU Library General Public License (LGPL); this will
  2331.    give you the ability to freely include the library components in your
  2332.    application without any cost or obligation. (Contact
  2333.    dweller@neosoft.com for more details.)
  2334.  
  2335.     What about STL and the Smalltalk library?
  2336.  
  2337.    The C++ STL does not contain much. Breaking its source code down, it
  2338.    contains less than 3000 semicolons (~7000 total lines). The entire
  2339.    library exists in C++ header files as inlineable code (supposedly
  2340.    within a few percent of the efficiency of hand-optimized code).
  2341.  
  2342.    STL class hierarchy
  2343.  
  2344.      bool, heap     -- of course Ada does not need a bool class!
  2345.       \ function, pair, stack
  2346.          \ iterator, tempbuf, projection
  2347.             \ algobase
  2348.                \ algorithms, bitvector, deque, list, tree, vector
  2349.                   \ map, multimap, set, multiset
  2350.  
  2351.  
  2352.    The main author of the library, Alexander Stepanov, created the Ada
  2353.    Generic Library in the 1980's -- and later borrowed from this to
  2354.    create STL. (There is an interview with Stepanov in the March 1995
  2355.    issue of Dr. Dobb's Journal -- in the C Programming column beginning
  2356.    on page 115. Stepanov explains that these packages were first done in
  2357.    Ada.)
  2358.  
  2359.    The Smalltalk library is quite eclectic. It covers everything from
  2360.    Boolean to bitmaps, dictionaries and other collections. Parts of it
  2361.    have direct equivalents in Ada 95, parts are already available in
  2362.    components from anonymous FTP sites and/or will be in the Booch Ada 95
  2363.    components, and other parts are available from commercial Ada
  2364.    component suppliers.
  2365.  
  2366.  
  2367. 9.9: Where can I find the equivalent of "printf" in Ada?
  2368.  
  2369.    While the standard package Text_IO provides many features, the
  2370.    request for a printf-like function is not unusual.
  2371.  
  2372.    (solution based on a suggestion by Tucker Taft)
  2373.  
  2374.    It is possible to produce a printf-like capability by overloading the
  2375.    "&" operator to take an object of type Format and an object of some
  2376.    type and return the Format, properly advanced, after having performed
  2377.    the appropriate output. The remaining format can be converted back to
  2378.    a string--e.g. to examine what is left at the end of the format
  2379.    string-- or simply printed to display whatever remains at the end. For
  2380.    example:
  2381.  
  2382.      with Text_IO;
  2383.      package Formatted_Output is
  2384.        type Format is
  2385.          limited private;
  2386.  
  2387.        function Fmt (Str : String)
  2388.          return Format;
  2389.  
  2390.        function "&" (Left : Format; Right : Integer)
  2391.          return Format;
  2392.        function "&" (Left : Format; Right : Float)
  2393.          return Format;
  2394.        function "&" (Left : Format; Right : String)
  2395.          return Format;
  2396.        ... -- other overloadings of "&"
  2397.  
  2398.        procedure Print (Fmt : Format);
  2399.  
  2400.        function To_String (Fmt : Format)
  2401.          return String;
  2402.  
  2403.      private
  2404.        ...
  2405.      end Formatted_Output;
  2406.  
  2407.      with Formatted_Output; use Formatted_Output;
  2408.      procedure Test is
  2409.        X, Y : Float;
  2410.      begin
  2411.        Print (Fmt("%d * %d = %d\n") & X & Y & X*Y);
  2412.      end Test;
  2413.  
  2414.    The private part and body of Formatted_Output are left as an exercise
  2415.    for the reader ;-).
  2416.  
  2417.    A "File : File_Type" parameter could be added to an overloading of Fmt
  2418.    if desired (to create something analogous to fprintf).
  2419.  
  2420.    This capability is analogous to that provided by the "<<" stream
  2421.    operator of C++.
  2422.  
  2423.      _________________________________________________________________
  2424.  
  2425.  
  2426. 10: Interfacing with Ada
  2427.  
  2428.  
  2429. 10.1: I am writing software that used the Distributed Interactive Simulation
  2430. (DIS) interface, does an interface exist in Ada?
  2431.  
  2432.    Yes. DIS is a standard for communications between simulators using an
  2433.    Internet Protocol network (IP). DIS provides a unified virtual
  2434.    environment for multiple simulator users on a network. It is used
  2435.    mostly in the DoD simulations business, but it is applicable to ANY
  2436.    simulation. It is an industry initiative involving military training
  2437.    and procurement organisations, simulator vendors and universities
  2438.    mostly in the US, but the technology is unclassified.
  2439.  
  2440.    The Institute of Simulation and Training, URL
  2441.    http://www.tiig.ist.ucf.edu/ is a center at the University of Central
  2442.    Florida (UCF) which serves as the support contractor for the
  2443.    Simulation and Training Command (STRICOM). Current (published)
  2444.    standards can be found there, as are BBS's for the DIS working groups
  2445.    who are attempting to push those standards forward. The BBS contains
  2446.    an Ada binding for DIS.
  2447.  
  2448.    Note that the above provides a thin binding to C code. It may be
  2449.    worthwhile to take the time to make high level DIS bindings. Someone
  2450.    reports having done it in over 2 man-months using an experienced Ada
  2451.    engineer, and that it was well worth it. Many bugs were found in the C
  2452.    DIS code of the machine they were networked with. "A strongly-typed
  2453.    interface is the network programmer's best friend."
  2454.  
  2455.    At TRI-Ada'94 there was a demonstration by Coleman Research
  2456.    Corporation (CRC); here's their short pitch: "CRC presents Ada
  2457.    VR-Link, the first commercially available DIS NIV. It provides all of
  2458.    the facilities necessary to jump start your DIS compliant simulation
  2459.    development efforts. For more information call (205) 922-6000."
  2460.  
  2461.    Also, the AJPO sponsored an Ada Technology Insertion Program (ATIP)
  2462.    relating to this, FY93 ATIP project 17, titled "Ada Distributed
  2463.    Interactive Simulation (ADIS)". According to its charter, "The primary
  2464.    purpose of the ADIS project will be the creation of Ada interface
  2465.    bindings to allow an Ada simulation application to use the DIS
  2466.    protocols." As with any other AJPO-related work, contact the Ada
  2467.    Information Clearinghouse for more information.
  2468.  
  2469.    There are several sources of information available on DIS itself. The
  2470.    IEEE version of the DIS standard is available (and only available)
  2471.    through IEEE (IEEE standard number is ??). Draft versions of the
  2472.    standard are available from the Institute for Simulation and Training
  2473.    at the University of Central Florida. They take orders at (407)
  2474.    855-0881, and questions (about ordering) at (407) 658-5054.
  2475.  
  2476.  
  2477. 10.2: Is there any support for Common Object Request Broker Architecture
  2478. (CORBA) for Ada 9X?
  2479.  
  2480.    (from Bill Beckwith, Bill.Beckwith@ois.com)
  2481.  
  2482.    Objective Interface Systems, Inc. (OIS), MITRE, and DISA have been
  2483.    working on a mapping from CORBA IDL to Ada 95 for about six months. I
  2484.    will send a recent copy of the mapping document to any interested
  2485.    parties. OC Systems, Rational, and OIS are planning on selling CORBA
  2486.    products for Ada.
  2487.  
  2488.    Note that CORBA IDL to Ada 95 mapping specifies a mapping, not a
  2489.    binding. This will put Ada 95 on equal footing with the C++ and
  2490.    Smalltalk products. (except, of course, the Ada mapping is cleaner ;-)
  2491.  
  2492.  
  2493.      _________________________________________________________________
  2494.  
  2495.  
  2496. 11: Finding Additional Information
  2497.  
  2498.  
  2499. 11.1: Where can I find Ada books?
  2500.  
  2501.    Try the comp.lang.ada FAQ, or the Ada WWW homepage
  2502.    (http://lglwww.epfl.ch/Ada/). Michael Feldman maintains the "Annotated
  2503.    Sampling of Ada-Oriented Textbooks", if you don't have access to WWW,
  2504.    drop him a note at mfeldman@seas.gwu.edu
  2505.  
  2506.  
  2507. 11.2: Are there other Ada-related FAQs?
  2508.  
  2509.    Yes. They all appear in comp.lang.ada at regular intervals:
  2510.    comp.lang.ada FAQ, public Ada library FAQ, and Ada WWW server FAQ. All
  2511.    these are permanently available in hypertext format from the Ada WWW
  2512.    Server (see below) and in ASCII format from
  2513.    ftp://lglftp.epfl.ch/Ada/FAQ
  2514.  
  2515.  
  2516. 11.3: What is the "Ada WWW Server"?
  2517.  
  2518.    The Ada WWW Server is alive and heavily used. It is a hypertext,
  2519.    multimedia information server for the Ada programming language.
  2520.  
  2521.    The URL of the Ada WWW Server is
  2522.  
  2523.         http://lglwww.epfl.ch/Ada/
  2524.  
  2525.    [don't forget the trailing '/'.]
  2526.  
  2527.    The Ada WWW Server provides Ada-related information and hypertext
  2528.    access in areas including:
  2529.      * Historical notes on Ada
  2530.      * References
  2531.      * Ada FAQs
  2532.      * State of Ada 9X revision process
  2533.      * Standards
  2534.      * Bindings
  2535.      * Tools and Components
  2536.      * Intellectual Ammunition
  2537.      * Introductory Material
  2538.      * Resources
  2539.      * CS Technical Reports
  2540.      * FTP and WWW Sites--including mirror sites
  2541.      * Calendar of Ada-related events
  2542.      * Ada Today
  2543.      * Frequently Asked Questions--with Answers (from comp.lang.ada)
  2544.  
  2545.  
  2546.    For instance, you will find a list of schools using Ada in CS1 or CS2,
  2547.    an article on commercial success stories, information about software
  2548.    components, as well as hypertext versions of the Ada reference manual
  2549.    (both 83 and draft 9X).
  2550.  
  2551.    The Ada WWW Server keeps growing. All comments, ideas, and requests
  2552.    for additions or corrections, are welcome (e-mail to
  2553.    Magnus.Kempe@di.epfl.ch).
  2554.  
  2555.      _________________________________________________________________
  2556.  
  2557.  
  2558. 12: Pretty-printing Ada Source Code
  2559.  
  2560.  
  2561. 12.1: Is there software that generates a pretty PostScript file from Ada
  2562. source code?
  2563.  
  2564.    Pretty Ada code in PostScript means that e.g. reserved words are in
  2565.    bold and comments are in italics. This is a separate issue from
  2566.    re-formatting and automatic indenting.
  2567.  
  2568.    If you use the new Ada Mode for GNU Emacs (available from
  2569.    ftp://cs.nyu.edu/pub/gnat), go and get the package ps-print.el from
  2570.    any emacs archive (e.g. in directory
  2571.    ftp://archive.cis.ohio-state.edu/pub/gnu/emacs/elisp-archive). With
  2572.    this package you can print your code as you see it on the screen, say
  2573.    with bold keywords and italic comments.
  2574.  
  2575.    Another possibility is to feed the source to "vgrind" (see below),
  2576.    then pipe the result through "pscat" (to get PostScript) or "lpr -t"
  2577.    (to print), e.g.:
  2578.  
  2579.      vgrind -d <vgrind_defs_file> -lada -o1- -t -w $* | lpr -t
  2580.  
  2581.  
  2582. 12.2: I use vgrind to do "pretty printing" of my source. Is there a vgrind
  2583. definition for Ada?
  2584.  
  2585.  
  2586. # Ada!
  2587. ada|Ada:\
  2588.         :pb=(^\d?(procedure|function|package|package body))\d\p:\
  2589.         :bb=if|case|begin|loop:be=end:\
  2590.         :cb=--:ce=$:\
  2591.         :sb=":se=":\
  2592.         :lb=':le=':\
  2593.         :id=_.:\
  2594.         :oc:\
  2595.         :kw=abort abs abstract accept access aliased all and array at\
  2596.         begin body case constant declare delay delta digits do else\
  2597.         elsif end entry exception exit for function generic goto if in is\
  2598.         limited loop mod new not null of or others out package pragma\
  2599.         private procedure protected raise range record rem renames requeue\
  2600.         return reverse select separate subtype tagged task terminate then\
  2601.         type until use when while with xor:
  2602.  
  2603.  
  2604.    Note that the above has a problem with attributes, because the "lb"
  2605.    and "le" terms make two-attributes-20-lines-apart look like one
  2606.    "string literal." Ada 95 keywords are recognized.
  2607.  
  2608.    Here is another definition, which "fixes" this problem (not perfect,
  2609.    but probably better). Only Ada 83 keywords are recognized.
  2610.  
  2611.  # In order to get the ticks to work, we are assuming that there will be
  2612.  # whitespace before a literal (like '"') and *not* when used for an
  2613.  # attribute (like 'Length).
  2614.  # For sb/se, we are ALSO assuming that literals have whitespace before/after.
  2615. Ada|ada:\
  2616.         :pb=^\d?(procedure|function|package|package\dbody)\d\p:\
  2617.         :bb=begin:be=end:\
  2618.         :cb=--:ce=$:\
  2619.         :sb=( |\t|\()":se="( |\t|;|,|\)):\
  2620.         :lb=(>| |\t)':le='(\)| |\t|;):\
  2621.         :tl:\
  2622.         :oc:\
  2623.         :kw=abort abs accept access all and array at begin body case constant\
  2624.         declare delay delta digits do else elsif end entry exception exit for\
  2625.         function generic goto if in is limited loop mod new not null of or\
  2626.         others out package pragma private procedure raise range record rem\
  2627.         renames return reverse select separate subtype task terminate then\
  2628.         type use when while with xor:
  2629.  
  2630.  
  2631. 12.3: How about a source code reformatter?
  2632.  
  2633.    If you can run a Perl script (Perl is freely available for almost
  2634.    every OS in the world), you can use the program aimap, written by Tom
  2635.    Quiggle of SGI. It can be found (where ???).
  2636.  
  2637.      _________________________________________________________________
  2638.  
  2639.  
  2640. 13: Common Confusions
  2641.  
  2642.  
  2643. 13.1: Wasn't Ada designed by some committee? What kind of a language could you
  2644. possibly get from that kind of approach?
  2645.  
  2646.    (Tucker Taft, the principal designer of Ada 95, responds)
  2647.  
  2648.    I believe most reviewers of Ada 9X (and Ada 83 for that matter) will
  2649.    assure you that it was most certainly not designed by committee ;-).
  2650.  
  2651.    In fact, with respect to MI, the situation was just the opposite.
  2652.    There were several reviewers who pushed hard for building in a
  2653.    particular approach to MI. The principle designer (;-) was unconvinced
  2654.    that the benefits of building in a particular MI approach outweighed
  2655.    the costs as far as complexity. There was no clear winner to use as a
  2656.    model in the outside world; even Sather and Eiffel couldn't agree
  2657.    exactly on how to resolve the intricacies of MI, despite their strong
  2658.    similarities in other areas.
  2659.  
  2660.  
  2661. 13.2: I've heard the DoD is dropping all Military standards to reduce costs,
  2662. doesn't that mean the mandate to use Ada goes away too?
  2663.  
  2664.    The following memo explains how that decision affects the Ada
  2665.    mandate:
  2666.  
  2667.                  OFFICE OF THE SECRETARY OF DEFENSE
  2668.  
  2669.                      Washington, DC  20301-1000
  2670.  
  2671.                            August 26, 1994
  2672.  
  2673.  
  2674.   MEMORANDUM FOR SECRETARIES OF THE MILITARY DEPARTMENTS
  2675.                  CHAIRMAN OF THE JOINT CHIEFS OF STAFF
  2676.                  UNDER SECRETARY OF DEFENSE (PERSONNEL AND
  2677.                  READINESS)
  2678.                  UNDER SECRETARY OF DEFENSE (POLICY)
  2679.                  COMPTROLLER OF THE DEPARTMENT OF DEFENSE
  2680.                  GENERAL COUNSEL OF THE DEPARTMENT OF DEFENSE
  2681.                  INSPECTOR GENERAL OF THE DEPARTMENT OF DEFENSE
  2682.                  DIRECTOR OF OPERATIONAL TEST AND EVALUATION
  2683.                  DIRECTORS OF THE DEFENSE AGENCIES
  2684.  
  2685.   SUBJECT:  Use of Ada
  2686.  
  2687.        The purpose of this memorandum is to reiterate the Department
  2688.   of Defense (DoD) commitment to the use of Ada.
  2689.  
  2690.        It is DoD policy to use commercial off-the-shelf (COTS)
  2691.   software whenever it meets our requirements.  However, when COTS
  2692.   software is not available to satisfy requirements and the DoD must
  2693.   develop unique software to meet its needs, that software must be
  2694.   written in the Ada programming language in accordance with DoD
  2695.   Directive 3405.1 and DoD Instruction 5000.2.
  2696.  
  2697.        Secretary Perry's June 29, 1994 memorandum, "Specification &
  2698.   Standards -- A New Way of Doing Business," states that military
  2699.   standards will only be used "as a last resort, with an appropriate
  2700.   waiver."  This direction has caused some confusion regarding the
  2701.   Ada requirement since most references to Ada cite its MIL-STD
  2702.   nomenclature, MIL-STD-1815A.  Ada is also a Federal Information
  2703.   Processing Standard (FIPS 119), an American National Standards
  2704.   Institute (ANSI) standard (ANSI-1815A-1983), and an International
  2705.   Standards Organization (ISO) standard (ISO 8652-1987).  Any of
  2706.   these alternative references may be utilized in place of the MIL-
  2707.   STD reference in request for proposals, contracts, and other
  2708.   similar documents.  Thus, the Ada requirement does not conflict
  2709.   with the Secretary's direction, and compliance with both policies
  2710.   can be achieved simultaneously.
  2711.  
  2712.        Use of other programming languages can be considered if
  2713.   proposed by a contractor as part of his best practices since
  2714.   waivers to the use of Ada can be granted, where cost-effective, in
  2715.   accordance with procedures established in the policy referenced
  2716.   above.  However, such proposals require strong justification to
  2717.   prove that the overall life-cycle cost will be less than the use of
  2718.   Ada will provide.
  2719.  
  2720.        Secretary Perry's memorandum encourages practices that satisfy
  2721.   the Department's need to build high quality systems that meet
  2722.   requirements at affordable costs an in a timely manner.  This
  2723.   includes practices which support the development of Defense
  2724.   Software.  Ada is not only a facilitator of software engineering
  2725.   best practice, but also has inherent features which uniquely
  2726.   support both real-time systems and safety-critical systems.  Use of
  2727.   Ada also facilitates software reuse and has demonstrated reduced
  2728.   support costs.  Accordingly, Ada is a foundation for sound software
  2729.   engineering practice.
  2730.  
  2731.   /signed/                           /signed/
  2732.  
  2733.   Noel Longuemare                    Emmett Paige, Jr.
  2734.   Under Secretary of Defense         Assistant Secretary of Defense
  2735.   (Acquisition and Technology)       (Command, Control,
  2736.   (Acting)                           Communications, and
  2737.                                      Intelligence)
  2738.  
  2739.   cc:
  2740.   DDR&E
  2741.  
  2742.  
  2743.      _________________________________________________________________
  2744.  
  2745.  
  2746. 14: Credits
  2747.  
  2748.    The following persons have contributed (directly or indirectly,
  2749.    intentionally or unintentionally, through e.g. comp.lang.ada) to the
  2750.    information gathered in this FAQ: TuckeráTaft, DaveáWeller,
  2751.    BilláBeckwith, ChipáBennett, BevináBrett, NormáCohen,
  2752.    TheodoreáE.áDennison, RobertáDewar, BobáDuff, RobertáEachus,
  2753.    RolfáEbert, LaurentáGuerby, JeffreyáL.áGrover, RichardáG.áHash,
  2754.    JobáHonig, JeanáD.áIchbiah, NasseráKettani, WayneáR.áLawton,
  2755.    RobertáMartin, RobbáNebbe, JonathanáParker, IsaacáPentinmaki,
  2756.    BruceáPetrick, PauláPukite, RichardáRiehle, DavidáShochat,
  2757.    JoyceáTokar, FraseráWilson, and the maintainer has simply :-)
  2758.    organized, polished, or added some information for your satisfaction.
  2759.    The general HTML structure of this FAQ was inspired by the WWW FAQ.
  2760.  
  2761.      _________________________________________________________________
  2762.  
  2763.  
  2764. 15: Copying this FAQ
  2765.  
  2766.    This FAQ is Copyright 1994, 1995 by Magnus Kempe. It may be freely
  2767.    redistributed as long as it is completely unmodified and that no
  2768.    attempt is made to restrict any recipient from redistributing it on
  2769.    the same terms. It may not be sold or incorporated into commercial
  2770.    documents without the explicit written permission of the copyright
  2771.    holder.
  2772.  
  2773.    Permission is granted for this document to be made available under the
  2774.    same conditions for file transfer from sites offering unrestricted
  2775.    file transfer on the Internet and from Forums on e.g. Compuserve and
  2776.    Bix.
  2777.  
  2778.    This document is provided as is, without any warranty.
  2779.  
  2780.