I'm going over Ada code "cloned" from the Rosetta Code web site; I think this topic was discussed earlier, but couldn't find it

Hi;

There is a Rosetta Code task for which the Ada solution fails to compile for me.

I have not added any pragma to the code nor have I used any GNAT flags.

I think that this topic was discussed here previously, but I can’t seem to find it…

Here is the result from gnatmake:

test_amb.adb:18:04: warning: type "Amb" is frozen by body [enabled by default]
test_amb.adb:18:04: warning: an equality operator cannot be declared after this point [enabled by default]
test_amb.adb:39:13: error: equality operator must be declared before type "Amb" is frozen (RM 4.5.2 (9.8)) (Ada 2012)

So, is the code as written on the web site correct and I have add the appropriate GNAT flag(s) and/or an Ada pragma; or is the code incorrect?

Here’s the code as it currently stands on the Rosetta Code web site:

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

procedure Test_Amb is
   type Alternatives is array (Positive range <>) of Unbounded_String;

   type Amb (Count : Positive) is record
      This : Positive := 1;
      Left : access Amb; 
      List : Alternatives (1..Count);
   end record;
   
   function Image (L : Amb) return String is
   begin
      return To_String (L.List (L.This));
   end Image;

   function "/" (L, R : String) return Amb is
      Result : Amb (2);
   begin
      Append (Result.List (1), L);
      Append (Result.List (2), R);
      return Result;
   end "/";
   
   function "/" (L : Amb; R : String) return Amb is
      Result : Amb (L.Count + 1);
   begin
      Result.List (1..L.Count) := L.List ;
      Append (Result.List (Result.Count), R);
      return Result;
   end "/";

   function "=" (L, R : Amb) return Boolean is
      Left : Unbounded_String renames L.List (L.This);
   begin
      return Element (Left, Length (Left)) = Element (R.List (R.This), 1);
   end "=";
   
   procedure Failure (L : in out Amb) is
   begin
      loop
         if L.This < L.Count then
            L.This := L.This + 1;
         else
            L.This := 1;
            Failure (L.Left.all);
         end if;
         exit when L.Left = null or else L.Left.all = L;
      end loop;
   end Failure;

   procedure Join (L : access Amb; R : in out Amb) is
   begin
      R.Left := L;
      while L.all /= R loop
         Failure (R);
      end loop;
   end Join;

   W_1 : aliased Amb := "the" / "that" / "a";
   W_2 : aliased Amb := "frog" / "elephant" / "thing";
   W_3 : aliased Amb := "walked" / "treaded" / "grows";
   W_4 : aliased Amb := "slowly" / "quickly";
begin
   Join (W_1'Access, W_2);
   Join (W_2'Access, W_3);
   Join (W_3'Access, W_4);
   Put_Line (Image (W_1) & ' ' & Image (W_2) & ' ' & Image (W_3) & ' ' & Image (W_4));
end Test_Amb;

I’m on MacOS (Apple Silicon).

/opt/gnat-aarch64-darwin-15.1.0-2/bin/gnatmake

gnat --version
GNAT 15.0.1 20250418 (prerelease)
Copyright (C) 1996-2025, Free Software Foundation, Inc.

Thanks,
RBE

It was here:

1 Like

Thank you for providing the link to the prior desparate call for help which I completely missed.

RBE