Hot questions for Using Cap'n Proto in generics

Question:

I cannot figure out how to instantiate an Option(T) type in pycapnp.

I have tried to instantiate a new message and then set the value of 'some', but it loses type information in doing so.

struct Option(T) {
  union {
    none @0 :Void;
    some @1 :T;
  }
}

struct Something {
  a @0 :Int16;
}
o = Option.new_message()
o.some = Something.new_message(a=5)
o.some.a // throws error

I would expect the option to become typed by virtue of the added struct, but it loses all type information and I cannot access the members of the object placed in the 'some' union value.


Answer:

Cap'n Proto generics aren't really designed to work that way. They are designed for static type checking (with statically-typed languages in mind, i.e. not Python). An instance of a generic type cannot "become typed" after the fact -- the type must be known statically / at construction.

If a type parameter isn't specified, then it is assumed to be AnyPointer. I believe that means you need to access some like this:

o.some.as_struct(Something).a

I think that in Python there is no way to construct a generic type with type parameter specified at runtime. The only way you can really use generics is when the containing type specifies type parameters, like:

struct ContainingType {
  option @0 :Option(Something);
}

If you then construct a ContainingType and then access its option field, you'll get an Option object that knows that the type of some is Something, not AnyPointer.