Type expected "Integer" as argument of put_line... with Text_IO, NOT Integer_Text_IO

Hi,
Can you try to compile the following piece of code ? The line indicated causes the message:

essai.adb:22:34: error: expected type “Standard.Integer”
essai.adb:22:34: error: found type “Appointment_Type” defined at line 7

But it makes no sense to me, I made sure to avoid name space issues, I only withed Text_IO and not Integer_Text_IO so there’s no way “Put_line” excepts an Integer, since I defined Details to return a String.

with Ada.Calendar, Ada.Containers.Indefinite_Holders, Ada.Text_IO; use Ada.Text_IO, Ada.Calendar;

procedure Essai is
   package A is
   	package SH is new Ada.Containers.Indefinite_Holders (String); use SH;
      subtype SHolder is SH.Holder;
      type Appointment_Type is
         record
            Details : SHolder;
         end record;
      function Details (Appt : Appointment_Type) return String;
      function Appointment (Details : String)    return Appointment_Type;
   end A;

   package body A is
      function Details (Appt : Appointment_Type) return String is
        (Appt.Details.Element);
      function Appointment (Details : String)
                          return Appointment_Type is
      Apt : Appointment_Type := (Details => To_Holder (Details));
      begin
	      Put_Line (Details (Apt)); -- HERE
         return Apt;
      end Appointment;
   end A;
begin
   null;
end Essai;

If you replace the Appointment function by this :

      function Appointment (Details : String)
                          return Appointment_Type is
      Appt : Appointment_Type := (Details => To_Holder (Details));
               begin
                  Put_Line (Details (Appt => Appt));
                  return Appt;
      end Appointment;

then you’ll get instead “essai.adb:22:29: error: invalid prefix in call”… even though there’s no prefix at all in this line (the same, Put_line) !

Your function appointment has a variable named Details which is indexible by a Positive (subtype of Integer).

Your line in question is getting confused between the variable Details and the function Details and since the Variable is the more locally declared one, it takes precedence.

You want to prefix your Details call with the package name:
Put_Line (A.Details (Apt)); -- Notice the added package name

This allows the compiler to know you want the higher scoped version of Details instead of the locally scoped version of Details.

1 Like

I didn’t consider the parameter… I shouldn’t use parameter names identical to that of subprograms or variables.
Somehow I think that the worst difficulty with the language is not the language, for it usually works exactly as intended, although reading the intent somewhere in an intelligible language isn’t always easy. Something you can read in all books, yes, but it took me a lot of mental efforts to actually get down to it,
I think I’ve understood the point of “software engineering”, thinking ahead and testing every piece of code systematically with valid or invalid input/output. To try and try again until it works (what I’ve been doing) is just so dumb

1 Like

A lot of that is just going to boil down to having more experience and also establishing yourself coding patterns (you could make your own coding standard and hold yourself too it).

For any high level language that targets catching mistakes at compile time (like Rust and Ada), you are gonna spend more time fighting the compiler than in other languages, but that is by design. Otherwise the other end of the stick is having your code compile easily but then run a very high risk of it crashing and burning and you not having a clue why it is seg faulting or code just isn’t running (to be clear you can run into this in Ada or Rust or similar, but the odds are much less likely and the impact is usually easier to diagnose).

My best advice to you is practice. The more time you put into a language, the better you will be at this part (working with the compiler). Take for example your previous question. Just by the error mentioning something like “expecting a variable”, I already had in my head a first thought that you had something constant that the code expected to be modifiable, so I started looking at the function calls to see which had “in out” parameters.

This question, based on the code looking ok at glance, my first instinct is you duplicated a name and it was confused (which did end up being the issue) OR that you had multiple use clauses that had conflicts (this did not end up being the case). So I had a couple of avenues to check out to start with. A lot of it is just experience.

In some ways I now like the compiler to be noisy about my code (I didn’t used to). There is something freeing to me to write 20-30 lines of code, hit compile and know the compiler will catch my basic mistakes. I can focus on the design of the code more and not worry if I botch a variable name or such.

5 Likes