How to build an extendable parametric struct

I want to build a package with a struct that relies on some element type parameters but can be extended to work with additional element types as well. Suppose this is the basic structure:

struct MyStruct[*Ts: AnyType]:
   ...

struct MyPowerfulStruct:
   var _data = MyStruct[MyType1, MyType2, MyType3]
   ...

I would like to achieve that package users can add further types to MyPowerfulStruct. Are there design concepts for this kind of problem? Can this be solved with Mojo at the moment?

My first thought was to do something along the lines of the following:


struct MyPowerfulStruct[*Ts: AnyType]:
   var _data = MyStruct[MyType1, MyType2, MyType3, *Ts]
   ...

Will this be possible in the near future? Is there any other / more elegant way to achieve this?

1 Like

We don’t have any planned support for “inheritance” of structs, but we should be able to do what you’re talking about with containment like that. It sounds like you’re looking for better support for variadic types?

The major challenge we have right now is that we don’t support nice variadic unpacking - there are a variety of workarounds, but I agree it is not very beautiful. For example, you can see how various types build on top of heterogenous varadic types in the standard library: Tuple is the canonical example, and the VariadicPack type in the standard library is what is used to implement the syntax.

Hmm. “Not beautiful but works” would be totally fine for me at the moment. Nonetheless, though I think I have looked at several places of the standard library and tried out quite a couple of things, I did not find any way to do some of the things I need. In particular, this are

  • concatenation of variadic arguments / packs
  • conversion between different variadic types (e.g. variadic list to variadic pack)
  • parametrizing based on multiple variadic arguments (such as below:)
struct S1[*Ts: AnyType]:
    pass

struct S2[*Ts: AnyType]:
    pass

sruct Connector[Ts1, Ts2]:
    var s1: S1[*Ts1]
    var s2: S2[*Ts2]

To me these things look like they should not be too difficult to implement in principle (as I assume that they the behaviour is somewhat clearly defined, maybe with exception of the last case, which would require support for some packaging of types), but I cannot say I can accurately assess the difficulty of implementing this. Therefore my question.