Saturday, August 11, 2012

AdaTutor - The Format of an Ada Program (3)

Making the Dot Notation Automatic

These two programs are equivalent:
with Ada.Text_IO;                 with Ada.Text_IO; use Ada.Text_IO;
procedure Hello is                procedure Hello is
begin                             begin
  Ada.Text_IO.Put_Line("Hello!");   Put_Line("Hello!");
end Hello;                        end Hello;
Since the statement with Ada.Text_IO; makes the package visible, our program can call the procedures and functions in it.  To call a procedure in Ada.Text_IO, we write the name of the package, a dot, and the name of the procedure.  But the statement use Ada.Text_IO; tells the compiler to supply the name of the package and the dot for us.  That's why the two programs above are equivalent.

Remember, in Ada with provides visibility; use asks the compiler to supply the package name and the dot.  A package must be withed before we can use it.

The Ada meanings of the words with and use are more or less reversed from their meanings in Pascal.  Also, in Ada we can't use records, only packages.

A program can with and use several packages.  For example, there's a package that comes with Ada called Ada.Calendar.  (In Ada 83, the name is just Calendar, and Ada 95 accepts the shorter name for compatibility.)  Suppose we've also compiled a package of our own, My_Pkg.  Then our program might say
      with Ada.Text_IO, Ada.Calendar, My_Pkg;
      use  Ada.Text_IO, Ada.Calendar, My_Pkg;
In this case, when the compiler sees the call to Put_Line, it searches all three packages that we've used for a procedure Put_Line that takes one String parameter (or "argument").  If it finds no procedure Put_Line, the compiler displays an error message, like "Undeclared identifier Put_Line" or "Put_Line is undefined."

But what if there are several procedures Put_Line among the three packages?  Will the compiler stop searching when it finds the first Put_Line?  No.

If the compiler finds several Put_Line's, the name Put_Line is said to be overloaded.  In that case the compiler uses the number and types of parameters (arguments) to try to select the right Put_Line.  For example, if Ada.Text_IO contains a Put_Line that takes one String parameter, and My_Pkg contains a Put_Line that takes one Integer parameter, the compiler writes a call to Ada.Text_IO.Put_Line and not My_Pkg.Put_Line, because the calling statement supplies one String parameter.

If there's more than one Put_Line that takes exactly one String parameter, then the call is ambiguous and the compiler can't resolve the overloading.  The compiler gives an error message, perhaps "Ambiguity detected during overload resolution" or "Ambiguous expression."  In that case, we'd have to specify Ada.Text_IO.Put_Line even though we said use Ada.Text_IO;.

Finally, if there are procedures Put_Line, but none of them has the right number and types of parameters, again the compiler gives an error message, perhaps "Inconsistency detected during overloading resolution" or "Unresolvable expression" or "Invalid parameter list in call."

In summary, the compiler searches all the packages that we've used for a procedure with the correct number and types of parameters.  If it finds exactly one, everything's fine.  An error message can result from the compiler finding no procedure with the correct name, several procedures with the correct name and the correct number and types of parameters, or several procedures with the correct name, none of which has the correct number and types of parameters.

Overloading may seem like an unnecessary complication at this point, but you'll see later how very useful it can be.  Overloading is especially useful with the infix operators when we create our own types.  All of this will be covered later.

Question

Which one of the following would most likely be the cause of the message "Invalid parameter list in call"?
  1. You tried to use a package that you didn't with.
  2. You misspelled the name of a package in a call using dot notation.
  3. You misspelled the name of a procedure or function in a call.
  4. You called a procedure or function with the wrong number or types ofparameters.

Ada.Text_IO contains both a procedure Put and a procedure Put_Line (among other things).  Put_Line displays its String parameter followed by a Carriage Return and a Line Feed, while Put displays its String parameter without the CR-LF.  Ada.Text_IO also contains a procedure New_Line which produces only CR-LF.  For example, the following program will display Hi there, leave a blank line, and display everybody!:
with Ada.Text_IO; use Ada.Text_IO;
procedure Hi_There is
begin
   Put("Hi");
   Put_Line(" there,");
   New_Line;
   Put_Line("everybody!");
end Hi_There;

We'll learn much more about Ada.Text_IO later.

< prev   next >

No comments: