[swift-evolution] continuations - "extensions on steroids" idea
Adam Kemp
adam.kemp at apple.com
Mon Oct 30 22:22:10 CDT 2017
This I actually support. In C# the same concept exists in the form of partial classes. A class must be declared as partial everywhere in order to support it. It only works within a single assembly (similar to a module).
There are a few important use cases for this in C#:
1. Code generation. For instance, Interface Builder could modify a separate file for things like outlets and actions, and it could freely wipe and regenerate that file from scratch without touching any of your own code. Some people also generate parts of classes from templates while filling in the rest in another file.
2. Cross platform code. A common strategy in C# is to have a class split into parts, where one part is compiled on all platforms, and the other files are each specific to one platform or another. For instance, you may have Foo.swift, Foo.macOS.swift, and Foo.iOS.swift. Foo.swift would be compiled on both platforms, but then the iOS build would only include Foo.iOS.swift. This is a preferred alternative to using #ifs.
3. The use case Mike described. Sometimes we fail at making classes small, or maybe someone else failed and we’re stuck with it. Splitting a single class into pieces can be useful to organize cohesive chunks. That’s not something I tend to encourage as a design pattern, but it still happens anyway.
A related feature in C# is partial methods, which are just void-returning methods that have been declared as partial without an implementation. If an implementation is provided by another file (in another part of the partial class) then it is used. If no file provides an implementation then calls to that method are just stripped out by the compiler. This is also commonly used for cross-platform code. Maybe one platform needs to do something at a particular time but another doesn’t. Rather than using #ifs or having empty stubs in other platforms you can declare it partial and provide an implementation on just the one platform that needs it.
> On Oct 30, 2017, at 6:12 PM, Mike Kluev via swift-evolution <swift-evolution at swift.org> wrote:
>
> a general feeling that there are two very different use cases of extensions -- one to extend own classes and another to extend other people classes; a lengthy discussion in a nearby thread; a disparity of features of class and it's extensions and different access right treatment depending upon whether the extension is in the same with the main class or a different file lead me to the following idea. hopefully you will find this idea useful and we may even see it one day in swift.
>
> introducing class / struct / enum continuations.
>
> in a few words the are:
>
> 1) "extensions on steroids". in fact very similar to Objective-C "class extensions" but can be more than one and in more than one file.
>
> 2) as good as the classes they continue (or other continuations they continue)
>
> 3) can declare variables
>
> 4) have full access to "private" members of the class or other continuations
> regardless whether they are in the same or in a different files. no need for "public/internal/module" fallbacks to pass though files boundaries. similarly the class itself can use private members of its continuations.
>
> 5) "by invitation only" system. can only be written if declared by the class or some continuation of it.
>
> 6) A particular continuation only defined once (of course). There can be an arbitrary number of different continuations to a class similar to extensions.
>
> 7) alternative name considered: "extending" (as a noun). shall definitely be a different name than say, "extension" with some bracket-syntax variation - the two use cases are very different and shall be named differently.
>
> 8) the particular syntax is preliminary of course.
>
> example:
>
> ============= Some.swift ==================
>
> class Some {
>
> private func private_method_of_class() {
>
> // *** can use private methods of continuations even if they are in a different file
> private_method_defined_in_a_continuation()
> }
>
> // *** "by invitation" system
>
> continuation Feature // *** declaring a continuation
> continuation SomethingElse // *** Capitalized names, like classes
> }
>
> ============= Some-Feature.swift ==================
>
> // *** similar naming convetion to "Some+Feature.swift"
> // used for extensions, just with "-" instead
>
> // *** this is merely a naming convention, no need to
> necessarily follow it, can put more than one thing into
> a file, the continuation can reside in the same file as
> the main class fie, etc.
>
> continuation Feature of Some {
>
> // *** as good as class itself. first-class citizen
> // *** same syntax can be used for structs and enums
>
> var x: Int // *** can declare variables
>
> private func private_method_defined_in_a_continuation() {
> private_method_of_class()
>
> // *** can use private methods of the class or of other
> continuations even if they are in a different file
> }
>
> // *** continuations are as good as classes and can
> // *** declare other continuations if needed
>
> continuation CanDoThis
> }
>
> ============= Any file ==================
>
> continuation Feature of Some { // *** error, continuation is already defined
> }
>
> continuation Other of Some { // *** error: Other is not a continuation of Some
> }
>
> thoughts?
>
> Mike
>
> _______________________________________________
> 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