Using default function parameters to do a "fake" variadic function?

Ada does not natively support variadic functions/procedures (let’s exclude calling imported C variadic functions). Nonetheless, I am trying to obtain something similar to variadic.

To make this more concrete, suppose foo should take as arguments UP TO, say, 3 unconstrained arrays). A call to foo may have 1 argument, or 2, or 3. One idea might be to use default parameter values which would be ignored in the program body:

   type UA is array (Integer range <>) of Float;
   procedure foo( A1 : UA := null ; A2 : UA := null ; A3 : UA := null ) is

      -- process each non-null input

Some questions:

  1. Does this look a reasonable way to go? Is there a better approach?

  2. How should this “null” really be implemented? (Related: how would UA be given a “null” default initialization?)

Thanks for any suggestions.

Ada is a typed language, ergo no arguments of unknown types.

That is not variadic arguments, it is a variable number of arguments having the same type. For that you can use an array, provided that arguments are identically constrained:

type Arguments is array (Positive range <>, Positive range <>) of Float;
procedure Foo (List : Arguments);

or overloading:

type Argument is array (Positive range <>) of Float;
procedure Foo (A1 : Argument);
procedure Foo (A1, A2 : Argument);
procedure Foo (A1, A2, A3 : Argument);

No. As Python illustrates it is very difficult to handle because of combinatorial explosion of variants. Consider passing “null” to A1 and A3 and non-null to A2.

You can use an empty array if that is an illegal value. Or you can wrap array:

type Argument is array (Positive range <>) of Float;
subtype Count is range -1..Positive'Last;
type Optional_Array (Length : Count) is record
   case Length is
      when -1 =>
         null;
      when others =>
         Value : Argument (1..Length);
   end case;
end record;