Generic conundrum

I’m trying to reproduce an Ada generic use case. I can’t quite get Oxygene to do the same thing, and it might not even be possible.

I defined a generic interface for fixed length messaging:

namespace IO.Interfaces.Messaging.Fixed;

interface
  type Message = array of Byte;

  type Messenger<M> = public interface where M is Message;
    procedure Send(msg : M);
    procedure Receive(var msg : M);
  end;

  procedure Dump(msg : Message);

implementation
end.

Now I’m trying to instantiate an interface for 64-byte messages:

namespace IO.Interfaces.Message64;
  type Message = array [0 .. 63] of Byte;
  type MessengerInterface = IO.Interfaces.Messaging.Fixed.Messenger<Message>;
end.

I can’t get it to work because the static array type IO.Interfaces.Message64.Message isn’t compatible with the open array type IO.Interfaces.Messaging.Fixed.Message.

In Ada, with an unconstrained array type like String, you can either declare a constrained object (variable) or derive a constrained type:

x : String(1 .. 10);
type FixedString is new String(1 .. 10);
y : FixedString;

x and y are both constrained 10-byte variables allocated on the stack.

Is there some way to either declare IO.Interfaces.Messaging.Fixed.Message as a static array with bounds to be determined, or to define IO.Interfaces.Message64.Message as some kind of constrained descendant of IO.Interfaces.Messaging.Fixed.Message?

1 Like

FTR, while im not familiar with Ada per so, many langauges have very different ideas of generics, and ors are most closely modeled after .NET, across all platforms (as close as we can get them, elsewhere, often with some limits). For example, Swift generics are a totally different beast, and one too the man hy reasons why we’ve decided to stop keeping up with 100% Swift support…

yes, unfortunately, “array of Byte” and "array [0 … 63] of Byte"a r every different types, one is memory allocated at runtime depending on the actual size needed, and a pointer, while the other is allocated inline on stack or inside the class/record structure where it’s defined. Even if that were not the case, I don’t think our generic system would support something like this.

The closest you could come is defining a custom Message class (or record – I’m not sure, we support record ancestry now, but I don’t know how well that plays with generic constraints, ion runtime level), which contains the array, and enforces the size in code, say

type
  Message = public class
  protected
    fData: array of Byte;
  end;

  64ByteMessage = public class
  public
     constructor; 
     begin
       fData := new Byte[64];
     end;
  end;

  ArnitraryMessage = public class
  public
     constructor(aLimit: Integer); 
     begin
       fData := new Byte[aLimit];
     end;
  end;
...

and so forth.
1 Like