Note that this is roughly the same reason that Java has a similar
restriction imposed on its generics.

-Kenton

On Thu, Apr 30, 2020 at 5:18 PM Kenton Varda <[email protected]> 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/CAJouXQmd1vK9wtG1TpykEeBsjUwAqzB09GZOkXJyu09tcQe5mg%40mail.gmail.com.

Reply via email to