Channel Buffering in Ada

Based on the provided input, here’s the translation of the Go code to Ada, formatted in Markdown suitable for Hugo:

Ada does not have built-in channels like Go, so we’ll use a protected object to simulate a buffered channel. This example demonstrates how to create a buffered “channel” in Ada using a protected object with a fixed-size array.

with Ada.Text_IO; use Ada.Text_IO;

procedure Channel_Buffering is

   Buffer_Size : constant := 2;

   protected type Buffered_Channel is
      entry Put (Item : in String);
      entry Get (Item : out String);
   private
      Buffer : array (1 .. Buffer_Size) of String (1 .. 20);
      Count  : Natural := 0;
      In_Index, Out_Index : Positive := 1;
   end Buffered_Channel;

   protected body Buffered_Channel is
      entry Put (Item : in String) when Count < Buffer_Size is
      begin
         Buffer (In_Index) := (others => ' ');
         Buffer (In_Index)(1 .. Item'Length) := Item;
         In_Index := (In_Index mod Buffer_Size) + 1;
         Count := Count + 1;
      end Put;

      entry Get (Item : out String) when Count > 0 is
      begin
         Item := Buffer (Out_Index);
         Out_Index := (Out_Index mod Buffer_Size) + 1;
         Count := Count - 1;
      end Get;
   end Buffered_Channel;

   Messages : Buffered_Channel;

begin
   -- Because this channel is buffered, we can send these
   -- values into the channel without a corresponding
   -- concurrent receive.
   Messages.Put ("buffered");
   Messages.Put ("channel");

   -- Later we can receive these two values as usual.
   declare
      Msg : String (1 .. 20);
   begin
      Messages.Get (Msg);
      Put_Line (Msg);
      Messages.Get (Msg);
      Put_Line (Msg);
   end;
end Channel_Buffering;

In this Ada example, we’ve created a Buffered_Channel protected type that simulates a buffered channel. The Buffer_Size constant is set to 2, allowing the channel to buffer up to 2 values.

The Put entry adds items to the buffer, while the Get entry retrieves items from the buffer. The Count variable keeps track of the number of items in the buffer, and In_Index and Out_Index manage the circular buffer.

In the main procedure, we demonstrate how to use this buffered channel:

  1. We create an instance of Buffered_Channel called Messages.
  2. We put two strings into the channel using Messages.Put.
  3. We then retrieve and print these two values using Messages.Get.

This example shows how Ada can implement a concept similar to buffered channels, providing a way to send multiple values without immediate corresponding receives.

To compile and run this Ada program:

$ gnatmake channel_buffering.adb
$ ./channel_buffering
buffered
channel

This example demonstrates how Ada can implement buffered communication between tasks, which is conceptually similar to buffered channels in other languages.