Yeah, I think if we really really wanted to do this, the approach I'd take is to have the capnp code generator output full specializations for each permutation of primitive type arguments. The really hard part is deciding which permutations to generate. You don't really know which specializations are needed until they are used, but if you generate them at the usage site, then you potentially end up with duplicates -- these are all the same problems that C++ templates have. I suppose we could do what C++ compilers do and, like, output weak symbols, but even if that works in C++, I suspect it won't work in many other languages.
And we'd have to come up with some other hack to support dynamically loading schemas from schema.capnp format -- that format has offsets precomputed, which again implies that specializations involving primitive types actually have to have their own separate compiled schema representations... ugh. -Kenton On Thu, Apr 30, 2020 at 5:32 PM Samuel Ainsworth <[email protected]> wrote: > Thanks for the quick response! I see... I guess I was thinking that types > would not have defined sizes until they became fully specialized to their > arguments. This would make code generation less straightforward, but it's > not unlike what goes on in many modern compilers these days. Easier said > than done though. > > Best, > Samuel > > On Thursday, April 30, 2020 at 3:18:45 PM UTC-7, Kenton Varda wrote: >> >> Hi Samuel, >> >> Basically, because all pointers are the same size regardless of their >> type, so varying the type of a pointer does not change the overall layout >> of the containing struct. >> >> If the field can actually change sizes for different generic types, then >> it could affect the size and position of other fields around it. For >> example, imagine this: >> >> struct Foo(T) { >> a @0 :Int16; >> b @1 :Int32; >> c @2 :T; >> d @3 :Int64; >> } >> >> If we replace `T` with the type `Int16`, then the struct will be laid out >> like this: >> >> 0...16 a >> 16...32 c >> 32...64 b >> 64...128 d >> >> But if we replace `T` with type `Int32`, then the struct looks like this: >> >> 0...16 a >> 16...32 (empty padding) >> 32...64 b >> 64...96 c >> 96...128 (empty padding) >> 128...192 d >> >> Notice that the offset to field `d` differs between these. Also notice >> that deciding the offset of d depends on the specific details of all the >> fields that come before it. >> >> Because of this complexity, if we wanted Cap'n Proto generics to support >> varying primitive types, we'd essentially be forced to output a whole copy >> of the class for each combination of type parameters, because potentially >> all the offsets could differ for each permutation. >> >> *Or* we would need to say that generic types are laid out differently >> from the equivalent substituted type. >> >> Either of these options seemed unreasonably bad in practice. So the only >> other option was to support varying pointer types only. >> >> Note that this rule doesn't apply to List(T) because List(T) is a >> built-in type, not a generic. >> >> -Kenton >> >> On Thu, Apr 30, 2020 at 5:04 PM Samuel Ainsworth <[email protected]> >> wrote: >> >>> Following the schema introduction (https://capnproto.org/language.html), >>> I have something like the following: >>> >>> struct Map(Key, Value) { >>> entries @0 :List(Entry); >>> struct Entry { >>> key @0 :Key; >>> value @1 :Value; >>> } >>> } >>> >>> >>> struct Directory { >>> contents @0 :Map(UInt64, UInt64); >>> } >>> >>> >>> But capnproto isn't too happy about this: >>> >>> src/newworld/filetree.capnp:51:23-29: error: Sorry, only pointer types >>> can be used as generic parameters. >>> >>> I understand what this is saying, but I'm a bit puzzled as to why this >>> constraint exists... Why are only pointer types allowed as the >>> instantiations of generic parameters? >>> >>> Thanks, >>> Samuel >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "Cap'n Proto" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to [email protected]. >>> To view this discussion on the web visit >>> https://groups.google.com/d/msgid/capnproto/9668d18e-63d3-4643-ac24-a32f11fc8bde%40googlegroups.com >>> <https://groups.google.com/d/msgid/capnproto/9668d18e-63d3-4643-ac24-a32f11fc8bde%40googlegroups.com?utm_medium=email&utm_source=footer> >>> . >>> >> -- > You received this message because you are subscribed to the Google Groups > "Cap'n Proto" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To view this discussion on the web visit > https://groups.google.com/d/msgid/capnproto/d33a330b-0aac-48d9-8f41-82d25fe1c7ba%40googlegroups.com > <https://groups.google.com/d/msgid/capnproto/d33a330b-0aac-48d9-8f41-82d25fe1c7ba%40googlegroups.com?utm_medium=email&utm_source=footer> > . > -- You received this message because you are subscribed to the Google Groups "Cap'n Proto" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/capnproto/CAJouXQmdS6eofKA9LNiPowKHj%3Dg_a50WtS-3wNZU_YYy8kv0_A%40mail.gmail.com.
