Slices in Ada

Ada doesn’t have a direct equivalent to Go’s slices, but we can use arrays and vectors (from the Ada.Containers.Vectors package) to demonstrate similar concepts. Here’s an Ada program that shows some comparable operations:

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Containers.Vectors;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;

procedure Slices_Example is
   package String_Vectors is new Ada.Containers.Vectors
     (Index_Type => Natural, Element_Type => Unbounded_String);
   use String_Vectors;

   procedure Print_Vector (V : Vector) is
   begin
      Put ("[");
      for E of V loop
         Put (To_String (E) & " ");
      end loop;
      Put_Line ("]");
   end Print_Vector;

   V : Vector;
   C : Vector;
begin
   -- An uninitialized vector is empty
   Put_Line ("uninit: " & Boolean'Image (V.Is_Empty) & " " & Natural'Image (V.Length));

   -- Create a vector with initial capacity
   V := To_Vector (Capacity => 3);
   Put ("emp: ");
   Print_Vector (V);
   Put_Line ("len: " & Natural'Image (V.Length) & " cap: " & Natural'Image (V.Capacity));

   -- We can set and get elements
   V.Append (To_Unbounded_String ("a"));
   V.Append (To_Unbounded_String ("b"));
   V.Append (To_Unbounded_String ("c"));
   Put ("set: ");
   Print_Vector (V);
   Put_Line ("get: " & To_String (V (2)));

   -- Length of the vector
   Put_Line ("len: " & Natural'Image (V.Length));

   -- Append to the vector
   V.Append (To_Unbounded_String ("d"));
   V.Append (To_Unbounded_String ("e"));
   V.Append (To_Unbounded_String ("f"));
   Put ("apd: ");
   Print_Vector (V);

   -- Copy a vector
   C := V.Copy;
   Put ("cpy: ");
   Print_Vector (C);

   -- Slice of a vector (note: Ada uses inclusive ranges)
   declare
      Slice : Vector := V.Slice (3, 5);
   begin
      Put ("sl1: ");
      Print_Vector (Slice);
   end;

   -- Slice from start
   declare
      Slice : Vector := V.Slice (V.First_Index, 5);
   begin
      Put ("sl2: ");
      Print_Vector (Slice);
   end;

   -- Slice to end
   declare
      Slice : Vector := V.Slice (3, V.Last_Index);
   begin
      Put ("sl3: ");
      Print_Vector (Slice);
   end;

   -- Declare and initialize a vector in one line
   declare
      T : constant Vector := To_Vector (
        (To_Unbounded_String ("g"),
         To_Unbounded_String ("h"),
         To_Unbounded_String ("i")));
   begin
      Put ("dcl: ");
      Print_Vector (T);
   end;

   -- Ada doesn't have a built-in slice comparison, but we can implement one
   declare
      T : constant Vector := To_Vector (
        (To_Unbounded_String ("g"),
         To_Unbounded_String ("h"),
         To_Unbounded_String ("i")));
      T2 : constant Vector := To_Vector (
        (To_Unbounded_String ("g"),
         To_Unbounded_String ("h"),
         To_Unbounded_String ("i")));
   begin
      if T = T2 then
         Put_Line ("t == t2");
      end if;
   end;

   -- Two-dimensional vector (vector of vectors)
   declare
      TwoD : Vector_Of_Vectors.Vector;
   begin
      for I in 1 .. 3 loop
         declare
            Inner : Vector;
         begin
            for J in 1 .. I loop
               Inner.Append (To_Unbounded_String (Integer'Image (I + J - 2)));
            end loop;
            TwoD.Append (Inner);
         end;
      end loop;
      Put ("2d: ");
      for Inner of TwoD loop
         Print_Vector (Inner);
      end loop;
   end;
end Slices_Example;

This Ada program demonstrates concepts similar to Go’s slices using Ada’s vectors. Here’s a breakdown of the main points:

  1. We use the Ada.Containers.Vectors package to create a vector of unbounded strings, which is similar to a slice of strings in Go.

  2. The Print_Vector procedure is a helper to display the contents of a vector.

  3. We show that an uninitialized vector is empty, similar to a nil slice in Go.

  4. We create a vector with an initial capacity, append elements to it, and access elements by index.

  5. We demonstrate vector operations like appending, copying, and slicing. Note that Ada uses inclusive ranges for slicing.

  6. We show how to declare and initialize a vector in one line.

  7. Ada doesn’t have a built-in slice comparison like Go’s slices.Equal, but we can compare vectors directly.

  8. Finally, we create a two-dimensional vector (vector of vectors) to show how to work with multi-dimensional data structures.

While Ada’s vectors are not exactly the same as Go’s slices, they provide similar functionality for working with dynamic arrays of elements. The main differences are in syntax and some specific operations, but the general concepts of dynamic sizing and slicing are present in both languages.