[swift-evolution] Compile-time generic specialization
Abe Schneider
abe.schneider at gmail.com
Fri Feb 10 10:30:44 CST 2017
Hi Slava,
I'm actually less worried about the performance issue and more on the
impact on design. Specifically, calling one generic from another
effectively loses type information. Because of this, specializations
stop working, disallowing certain design patterns. While you can put
your functions inside a protocol or class to overcome this problem,
this can create large monolithic classes (in my case it makes one of
my classes go from ~300 lines to ~1500 lines of code).
I think it might be possible to deal with some of these issues if: (a)
extensions could define methods, not in the protocol, that got
dynamically called; (b) constraints could be placed on extensions of
protocols.
My preference is still allow generics to behave in a fashion similar
to C++ templates (regardless of the underlying implementation), as
making everything have to rely on protocols or classes makes Swift
feel less mixed paradigm (like c++) and more OOP focused (like Java).
That said, it sounds like that may be difficult to accomplish at least
in the immediate future.
Thanks!
Abe
On Wed, Feb 8, 2017 at 12:03 AM, Slava Pestov <spestov at apple.com> wrote:
>
>> On Feb 5, 2017, at 8:28 AM, Abe Schneider via swift-evolution <swift-evolution at swift.org> wrote:
>
>> The suggested method to get around this issue is to use a protocol to create a witness table, allowing for runtime dispatch. However, this approach is not ideal in all cases because: (a) the overhead of runtime dispatch may not be desirable, especially because this is something that can be determined at compile time; and
>
> Just as the compiler is able to generate specializations of generic functions, it can also devirtualize protocol method calls. The two optimizations go hand-in-hand.
>
>> One potential solution would be to add/extend an attribute for generic functions that would force multiple versions of that function to be created. There is already there is a `@_specialize` attribute, but you have to: (a) manually write out all the cases you want to cover; and (b) only affects the compiled code, which does not change this behavior. Due to the fact that `@_specialize` exists, I’m going to assume it wouldn’t be a major change to the language to extend the behavior to compile-time dispatch.
>
> In Swift, specialization and devirtualization are optimization passes which are performed in the SIL intermediate representation, long after type checking, name lookup and overload resolution. In this sense it is completely different from C++, where parsed templates are stored as a sort of untyped AST, allowing some delayed name lookup to be performed.
>
> Implementing C++-style templates would be a major complication in Swift and not something we’re likely to attempt at any point in time. The combination of specialization and devirtualization should give you similar performance characteristics, with the improved type safety gained from being able to type-check the unspecialized generic function itself.
>
>>
>>
>> Thanks!
>> Abe
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
More information about the swift-evolution
mailing list