Variadic Functions in Ada

Variadic functions can be called with any number of trailing arguments. For example, `fmt.Println` is a common variadic function.

Here's a function that will take an arbitrary number of `int`s as arguments.

```ada
with Ada.Text_IO; use Ada.Text_IO;

procedure Variadic_Functions is

   procedure Sum (Nums : in Integer) is
   begin
      Put_Line (Nums'Img & " ");
   end Sum;

   procedure Sum (Nums : in Integer_Array) is
      Total : Integer := 0;
   begin
      for Num of Nums loop
         Total := Total + Num;
      end loop;
      Put_Line (Integer'Image (Total));
   end Sum;

begin
   Sum (1, 2);
   Sum (1, 2, 3);

   declare
      Nums : constant Integer_Array (1 .. 4) := (1, 2, 3, 4);
   begin
      Sum (Nums);
   end;

end Variadic_Functions;

Within the function, the type of Nums is equivalent to array of Integer. We can call Nums'Length, iterate over it with for loop, etc.

Variadic functions can be called in the usual way with individual arguments.

Sum (1, 2);
Sum (1, 2, 3);

If you already have multiple args in an array, apply them to a variadic function using procedure(array) like this.

declare
   Nums : constant Integer_Array (1 .. 4) := (1, 2, 3, 4);
begin
   Sum (Nums);
end;
$ gnatmake Variadic_Functions.adb
$ ./variadic_functions
[1 2] 3
[1 2 3] 6
[1 2 3 4] 10

Another key aspect of functions in Ada is their ability to form closures, which we’ll look at next.

Next example: Closures.