Pitch: Partial Implementations

MOTIVATION:

In current Swift, a pattern has emerged among some developers, in order to logically group parts of a class or struct’s declaration, particularly around protocols:

class Foo {
  …
}

extension Foo: SomeProtocol {
  ...
}

extension Foo: SomeOtherProtocol {
  ...
}

This has certain appealing characteristics; in addition to the obvious organizational property, this pattern also keeps protocol implementations close to the declaration of conformance to the protocol. Unfortunately, there are a couple of problems:

1. Extensions cannot contain stored properties. This means that if a protocol requires a property, and it makes sense for that property to be stored, its conformance cannot be completely contained within the extension, but rather some of it must be in the main declaration.

2. It’s not uncommon for these protocol conformances to need access to the type’s private internal state, but extensions do not have access to private members within the state. This necessitates declaring the needed state as fileprivate rather than private, a fact has been a primary rallying point in the battle that’s currently raging on this mailing list over whether we should keep the ‘private’ access modifier, and which I would surmise is probably the major remaining use of ‘fileprivate’ in modern Swift code.

3. Since members that are declared ‘fileprivate’ cannot be accessed outside the file, these protocol conformance extensions must belong to the same file as the original declaration, which can lead to very long file sizes when the code to implement a protocol is very long, or when a type supports a large number of protocols.

PROPOSED SOLUTION:

Add a keyword to declare only part of a type’s implementation. I am suggesting ‘partial’ as the keyword, but this can be changed for a better name if needed. Partial conformances would be declared like this:

class Foo {
  private func somePrivateMethod() { … }
}

partial Foo: SomeProtocol {
  var someRequiredProperty: Int = 5

  func someRequiredMethod() {
    self.somePrivateMethod()
  }
}

partial Foo: SomeOtherProtocol {
  func someOtherRequiredMethod() {
    self.somePrivateMethod()
  }
}

When compiling this, the compiler would simply treat all the contents of partial declarations as if they were located within the original declaration, making the above equivalent to this:

class Foo: SomeProtocol, SomeOtherProtocol {
  private func somePrivateMethod() { … }

  var someRequiredProperty: Int = 5

  func someRequiredMethod() {
    self.somePrivateMethod()
  }

  func someOtherRequiredMethod() {
    self.somePrivateMethod()
  }
}

Obviously, partial declarations would only be allowed within the same module (or submodule, once we get them) as the original declaration.

The advantages to this approach are:

1. Given a pattern that many developers are adopting, this proposal would provide a mechanism to follow that pattern properly instead of repurposing a mechanism—extensions—which was intended for something else. The Swift manual claims that extensions are meant to add things “to a type that is declared elsewhere, or even to a type that you imported from a library or a framework,” not for separating your own code into parts.

2. Partial implementations can now implement the entirety of a protocol, including stored properties if the protocol necessitates them.

3. Since the contents of all partial implementations are considered to be part of the same declaration, the contents of partial implementations can access private members, which should allow the almost complete elimination of ‘fileprivate’ from developers’ codebases, simplifying the access control model.

4. Since partial implementations are not dependent on file-based organization, they can be stored in separate files, as long as those files are compiled into the same module, thus allowing for smaller, leaner, source files that are easier to read and understand.

What do you think?

Charles

-1

I would much rather see the ability to introduce stored properties in extensions (within the module) + simple file-based submodules.

Also, I think you are missing important parts of the extensions + fileprivate pattern. Sure, a big part of it is being able to group conformances together in code. But another large part is being able to group related code across classes and structs (avoiding the need for “friends”).

It would not, as you say, completely eliminate fileprivate from my code, it would just further complicate things by having to remember to use a different keyword (‘partial’) when I needed storage in extensions.

There have been a few proposals now, where I think the core idea was to enforce best practices from another language. But these end up being harmful (despite good intentions) because swift is a different beast, and thus will have different best practices. In particular, extensions allow cross-cutting concerns to be placed together. I can have a little bit of this class and a little bit of that one. That leads to different opportunities and challenges than those found in languages where a class has to be defined in one place, and it means we need different solutions…

As you say, we do have an issue of very large files being created right now, but there isn’t a type/scope-based solution which will actually fix that, because they all block those cross-cutting concerns. I suspect this will stop being an issue once we have both submodules and stored properties in extensions (which have both been listed as likely enhancements, but out of scope for Swift 4).

···

On Mar 23, 2017, at 11:12 AM, Charles Srstka via swift-evolution <swift-evolution@swift.org> wrote:

MOTIVATION:

In current Swift, a pattern has emerged among some developers, in order to logically group parts of a class or struct’s declaration, particularly around protocols:

class Foo {
  …
}

extension Foo: SomeProtocol {
  ...
}

extension Foo: SomeOtherProtocol {
  ...
}

This has certain appealing characteristics; in addition to the obvious organizational property, this pattern also keeps protocol implementations close to the declaration of conformance to the protocol. Unfortunately, there are a couple of problems:

1. Extensions cannot contain stored properties. This means that if a protocol requires a property, and it makes sense for that property to be stored, its conformance cannot be completely contained within the extension, but rather some of it must be in the main declaration.

2. It’s not uncommon for these protocol conformances to need access to the type’s private internal state, but extensions do not have access to private members within the state. This necessitates declaring the needed state as fileprivate rather than private, a fact has been a primary rallying point in the battle that’s currently raging on this mailing list over whether we should keep the ‘private’ access modifier, and which I would surmise is probably the major remaining use of ‘fileprivate’ in modern Swift code.

3. Since members that are declared ‘fileprivate’ cannot be accessed outside the file, these protocol conformance extensions must belong to the same file as the original declaration, which can lead to very long file sizes when the code to implement a protocol is very long, or when a type supports a large number of protocols.

PROPOSED SOLUTION:

Add a keyword to declare only part of a type’s implementation. I am suggesting ‘partial’ as the keyword, but this can be changed for a better name if needed. Partial conformances would be declared like this:

class Foo {
  private func somePrivateMethod() { … }
}

partial Foo: SomeProtocol {
  var someRequiredProperty: Int = 5

  func someRequiredMethod() {
    self.somePrivateMethod()
  }
}

partial Foo: SomeOtherProtocol {
  func someOtherRequiredMethod() {
    self.somePrivateMethod()
  }
}

When compiling this, the compiler would simply treat all the contents of partial declarations as if they were located within the original declaration, making the above equivalent to this:

class Foo: SomeProtocol, SomeOtherProtocol {
  private func somePrivateMethod() { … }

  var someRequiredProperty: Int = 5

  func someRequiredMethod() {
    self.somePrivateMethod()
  }

  func someOtherRequiredMethod() {
    self.somePrivateMethod()
  }
}

Obviously, partial declarations would only be allowed within the same module (or submodule, once we get them) as the original declaration.

The advantages to this approach are:

1. Given a pattern that many developers are adopting, this proposal would provide a mechanism to follow that pattern properly instead of repurposing a mechanism—extensions—which was intended for something else. The Swift manual claims that extensions are meant to add things “to a type that is declared elsewhere, or even to a type that you imported from a library or a framework,” not for separating your own code into parts.

2. Partial implementations can now implement the entirety of a protocol, including stored properties if the protocol necessitates them.

3. Since the contents of all partial implementations are considered to be part of the same declaration, the contents of partial implementations can access private members, which should allow the almost complete elimination of ‘fileprivate’ from developers’ codebases, simplifying the access control model.

4. Since partial implementations are not dependent on file-based organization, they can be stored in separate files, as long as those files are compiled into the same module, thus allowing for smaller, leaner, source files that are easier to read and understand.

What do you think?

Charles

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

MOTIVATION:

In current Swift, a pattern has emerged among some developers, in order to logically group parts of a class or struct’s declaration, particularly around protocols:

class Foo {
  …
}

extension Foo: SomeProtocol {
  ...
}

extension Foo: SomeOtherProtocol {
  ...
}

This has certain appealing characteristics; in addition to the obvious organizational property, this pattern also keeps protocol implementations close to the declaration of conformance to the protocol. Unfortunately, there are a couple of problems:

1. Extensions cannot contain stored properties. This means that if a protocol requires a property, and it makes sense for that property to be stored, its conformance cannot be completely contained within the extension, but rather some of it must be in the main declaration.

2. It’s not uncommon for these protocol conformances to need access to the type’s private internal state, but extensions do not have access to private members within the state. This necessitates declaring the needed state as fileprivate rather than private, a fact has been a primary rallying point in the battle that’s currently raging on this mailing list over whether we should keep the ‘private’ access modifier, and which I would surmise is probably the major remaining use of ‘fileprivate’ in modern Swift code.

3. Since members that are declared ‘fileprivate’ cannot be accessed outside the file, these protocol conformance extensions must belong to the same file as the original declaration, which can lead to very long file sizes when the code to implement a protocol is very long, or when a type supports a large number of protocols.

PROPOSED SOLUTION:

Add a keyword to declare only part of a type’s implementation. I am suggesting ‘partial’ as the keyword, but this can be changed for a better name if needed. Partial conformances would be declared like this:

class Foo {
  private func somePrivateMethod() { … }
}

partial Foo: SomeProtocol {
  var someRequiredProperty: Int = 5

  func someRequiredMethod() {
    self.somePrivateMethod()
  }
}

partial Foo: SomeOtherProtocol {
  func someOtherRequiredMethod() {
    self.somePrivateMethod()
  }
}

When compiling this, the compiler would simply treat all the contents of partial declarations as if they were located within the original declaration, making the above equivalent to this:

class Foo: SomeProtocol, SomeOtherProtocol {
  private func somePrivateMethod() { … }

  var someRequiredProperty: Int = 5

  func someRequiredMethod() {
    self.somePrivateMethod()
  }

  func someOtherRequiredMethod() {
    self.somePrivateMethod()
  }
}

Obviously, partial declarations would only be allowed within the same module (or submodule, once we get them) as the original declaration.

The advantages to this approach are:

1. Given a pattern that many developers are adopting, this proposal would provide a mechanism to follow that pattern properly instead of repurposing a mechanism—extensions—which was intended for something else. The Swift manual claims that extensions are meant to add things “to a type that is declared elsewhere, or even to a type that you imported from a library or a framework,” not for separating your own code into parts.

2. Partial implementations can now implement the entirety of a protocol, including stored properties if the protocol necessitates them.

3. Since the contents of all partial implementations are considered to be part of the same declaration, the contents of partial implementations can access private members, which should allow the almost complete elimination of ‘fileprivate’ from developers’ codebases, simplifying the access control model.

4. Since partial implementations are not dependent on file-based organization, they can be stored in separate files, as long as those files are compiled into the same module, thus allowing for smaller, leaner, source files that are easier to read and understand.

What do you think?

If we wanted to allow code like this to be written we wouldn’t need a new keyword to do it. You are proposing two things here:

1) Allow stored properties in same-module extensions. This has been discussed in the past and is a possibility, but I suspect it is not in scope for consideration during Swift 4.
2) Change the meaning of `private` to not mean lexical scope anymore, but instead be lexical scope or an extension of the type introducing the lexical scope in the same module. Changes to access control other than the proposal currently under review are out of scope for Swift 4.

···

On Mar 23, 2017, at 1:12 PM, Charles Srstka via swift-evolution <swift-evolution@swift.org> wrote:

Charles

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

I think the access levels should be revised, no need to introduce a new concept.

Regards,
Rien

Site: http://balancingrock.nl
Blog: http://swiftrien.blogspot.com
Github: Balancingrock (Rien) · GitHub
Project: http://swiftfire.nl

···

On 23 Mar 2017, at 19:12, Charles Srstka via swift-evolution <swift-evolution@swift.org> wrote:

MOTIVATION:

In current Swift, a pattern has emerged among some developers, in order to logically group parts of a class or struct’s declaration, particularly around protocols:

class Foo {
  …
}

extension Foo: SomeProtocol {
  ...
}

extension Foo: SomeOtherProtocol {
  ...
}

This has certain appealing characteristics; in addition to the obvious organizational property, this pattern also keeps protocol implementations close to the declaration of conformance to the protocol. Unfortunately, there are a couple of problems:

1. Extensions cannot contain stored properties. This means that if a protocol requires a property, and it makes sense for that property to be stored, its conformance cannot be completely contained within the extension, but rather some of it must be in the main declaration.

2. It’s not uncommon for these protocol conformances to need access to the type’s private internal state, but extensions do not have access to private members within the state. This necessitates declaring the needed state as fileprivate rather than private, a fact has been a primary rallying point in the battle that’s currently raging on this mailing list over whether we should keep the ‘private’ access modifier, and which I would surmise is probably the major remaining use of ‘fileprivate’ in modern Swift code.

3. Since members that are declared ‘fileprivate’ cannot be accessed outside the file, these protocol conformance extensions must belong to the same file as the original declaration, which can lead to very long file sizes when the code to implement a protocol is very long, or when a type supports a large number of protocols.

PROPOSED SOLUTION:

Add a keyword to declare only part of a type’s implementation. I am suggesting ‘partial’ as the keyword, but this can be changed for a better name if needed. Partial conformances would be declared like this:

class Foo {
  private func somePrivateMethod() { … }
}

partial Foo: SomeProtocol {
  var someRequiredProperty: Int = 5

  func someRequiredMethod() {
    self.somePrivateMethod()
  }
}

partial Foo: SomeOtherProtocol {
  func someOtherRequiredMethod() {
    self.somePrivateMethod()
  }
}

When compiling this, the compiler would simply treat all the contents of partial declarations as if they were located within the original declaration, making the above equivalent to this:

class Foo: SomeProtocol, SomeOtherProtocol {
  private func somePrivateMethod() { … }

  var someRequiredProperty: Int = 5

  func someRequiredMethod() {
    self.somePrivateMethod()
  }

  func someOtherRequiredMethod() {
    self.somePrivateMethod()
  }
}

Obviously, partial declarations would only be allowed within the same module (or submodule, once we get them) as the original declaration.

The advantages to this approach are:

1. Given a pattern that many developers are adopting, this proposal would provide a mechanism to follow that pattern properly instead of repurposing a mechanism—extensions—which was intended for something else. The Swift manual claims that extensions are meant to add things “to a type that is declared elsewhere, or even to a type that you imported from a library or a framework,” not for separating your own code into parts.

2. Partial implementations can now implement the entirety of a protocol, including stored properties if the protocol necessitates them.

3. Since the contents of all partial implementations are considered to be part of the same declaration, the contents of partial implementations can access private members, which should allow the almost complete elimination of ‘fileprivate’ from developers’ codebases, simplifying the access control model.

4. Since partial implementations are not dependent on file-based organization, they can be stored in separate files, as long as those files are compiled into the same module, thus allowing for smaller, leaner, source files that are easier to read and understand.

What do you think?

Charles

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

I agree with all of this, and I lack strong feelings about whether this should be restricted to the same compilation unit or allowed in multiple compilation units.

···

On March 23, 2017 at 1:12:51 PM, Charles Srstka via swift-evolution (swift-evolution@swift.org) wrote:

MOTIVATION:

In current Swift, a pattern has emerged among some developers, in order to logically group parts of a class or struct’s declaration, particularly around protocols:

class Foo {

}

extension Foo: SomeProtocol {
...
}

extension Foo: SomeOtherProtocol {
...
}

This has certain appealing characteristics; in addition to the obvious organizational property, this pattern also keeps protocol implementations close to the declaration of conformance to the protocol. Unfortunately, there are a couple of problems:

1. Extensions cannot contain stored properties. This means that if a protocol requires a property, and it makes sense for that property to be stored, its conformance cannot be completely contained within the extension, but rather some of it must be in the main declaration.

2. It’s not uncommon for these protocol conformances to need access to the type’s private internal state, but extensions do not have access to private members within the state. This necessitates declaring the needed state as fileprivate rather than private, a fact has been a primary rallying point in the battle that’s currently raging on this mailing list over whether we should keep the ‘private’ access modifier, and which I would surmise is probably the major remaining use of ‘fileprivate’ in modern Swift code.

3. Since members that are declared ‘fileprivate’ cannot be accessed outside the file, these protocol conformance extensions must belong to the same file as the original declaration, which can lead to very long file sizes when the code to implement a protocol is very long, or when a type supports a large number of protocols.

PROPOSED SOLUTION:

Add a keyword to declare only part of a type’s implementation. I am suggesting ‘partial’ as the keyword, but this can be changed for a better name if needed. Partial conformances would be declared like this:

class Foo {
private func somePrivateMethod() { … }
}

partial Foo: SomeProtocol {
var someRequiredProperty: Int = 5

func someRequiredMethod() {
self.somePrivateMethod()
}
}

partial Foo: SomeOtherProtocol {
func someOtherRequiredMethod() {
self.somePrivateMethod()
}
}

When compiling this, the compiler would simply treat all the contents of partial declarations as if they were located within the original declaration, making the above equivalent to this:

class Foo: SomeProtocol, SomeOtherProtocol {
private func somePrivateMethod() { … }

var someRequiredProperty: Int = 5

func someRequiredMethod() {
self.somePrivateMethod()
}

func someOtherRequiredMethod() {
self.somePrivateMethod()
}
}

Obviously, partial declarations would only be allowed within the same module (or submodule, once we get them) as the original declaration.

The advantages to this approach are:

1. Given a pattern that many developers are adopting, this proposal would provide a mechanism to follow that pattern properly instead of repurposing a mechanism—extensions—which was intended for something else. The Swift manual claims that extensions are meant to add things “to a type that is declared elsewhere, or even to a type that you imported from a library or a framework,” not for separating your own code into parts.

2. Partial implementations can now implement the entirety of a protocol, including stored properties if the protocol necessitates them.

3. Since the contents of all partial implementations are considered to be part of the same declaration, the contents of partial implementations can access private members, which should allow the almost complete elimination of ‘fileprivate’ from developers’ codebases, simplifying the access control model.

4. Since partial implementations are not dependent on file-based organization, they can be stored in separate files, as long as those files are compiled into the same module, thus allowing for smaller, leaner, source files that are easier to read and understand.

What do you think?

Charles

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Allowing stored properties and overridable methods in same-*file* extensions would be trivial to implement.

Same-module extensions are still tricky to generalize because in non-WMO mode, the class (and its metadata, such as stored property layout and vtable) could be emitted in a different translation unit than the extension, so we’d have to ’stitch’ together the definitions somehow and deal with the lack of static knowledge of things like the size of the class and the virtual methods it defines.

Slava

···

On Mar 23, 2017, at 11:21 AM, Matthew Johnson via swift-evolution <swift-evolution@swift.org> wrote:

1) Allow stored properties in same-module extensions. This has been discussed in the past and is a possibility, but I suspect it is not in scope for consideration during Swift 4.

Neither, actually:

1) I’m proposing we no longer encourage extensions at all for this purpose. My proposal is simply to allow breaking up declarations into parts, instead.

2) I’m not proposing changing the meaning of ‘private’ here. Since partial implementations would all glom into one lexical scope, all the current access control rules would apply as they currently do. This is simply a way to write a class or struct declaration in multiple parts, without having to use extensions.

Charles

···

On Mar 23, 2017, at 1:21 PM, Matthew Johnson <matthew@anandabits.com> wrote:

If we wanted to allow code like this to be written we wouldn’t need a new keyword to do it. You are proposing two things here:

1) Allow stored properties in same-module extensions. This has been discussed in the past and is a possibility, but I suspect it is not in scope for consideration during Swift 4.
2) Change the meaning of `private` to not mean lexical scope anymore, but instead be lexical scope or an extension of the type introducing the lexical scope in the same module. Changes to access control other than the proposal currently under review are out of scope for Swift 4.

MOTIVATION:

In current Swift, a pattern has emerged among some developers, in
order to logically group parts of a class or struct’s declaration,
particularly around protocols:

>> ...

What do you think?

If we wanted to allow code like this to be written we wouldn’t need a
new keyword to do it. You are proposing two things here:

1) Allow stored properties in same-module extensions. This has been
discussed in the past and is a possibility, but I suspect it is not in
scope for consideration during Swift 4.

Are we really expect to have stored properties in same-module extensions?
As I remember, there a lot of questions were raised during discussions so for some reason *I* had a feeling that we should not expect this happens in near feature. Probably I missed something.

FWIW I really like the *feature* proposed to structure declaration of my type as I want/need, this leads to more clear and separated code which(at declaration level) supports "single responsibility" principle.

I too think that proposed feature should be solved by extensions where stored properties are allowed(instead of separate syntax), *but* I believe we can(should) have the proposed feature even before we allow(if?) stored properties for same-module extensions: allow them for extensions in the same *file* only.

It seems like currently file is treated as code unit(especially when we are reverting back meaning of 'private' to same-file), which should be controlled by single person or contains not too complex logic so can be supported by different developers, inside which details should not be hidden and "you know what you do". So, IMO it will be naturally if compiler allows stored properties for extensions in same file with type declaration and treat these extensions just as partial class declaration.

···

On 23.03.2017 21:21, Matthew Johnson via swift-evolution wrote:

On Mar 23, 2017, at 1:12 PM, Charles Srstka via swift-evolution >> <swift-evolution@swift.org> wrote:

> 2) Change the meaning of

`private` to not mean lexical scope anymore, but instead be lexical
scope or an extension of the type introducing the lexical scope in the
same module. Changes to access control other than the proposal
currently under review are out of scope for Swift 4.

Charles

_______________________________________________ swift-evolution
mailing list swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________ swift-evolution mailing
list swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

If we wanted to allow code like this to be written we wouldn’t need a new keyword to do it. You are proposing two things here:

1) Allow stored properties in same-module extensions. This has been discussed in the past and is a possibility, but I suspect it is not in scope for consideration during Swift 4.
2) Change the meaning of `private` to not mean lexical scope anymore, but instead be lexical scope or an extension of the type introducing the lexical scope in the same module. Changes to access control other than the proposal currently under review are out of scope for Swift 4.

Neither, actually:

1) I’m proposing we no longer encourage extensions at all for this purpose. My proposal is simply to allow breaking up declarations into parts, instead.

What I’m suggesting is that we could accomplish the same functionality by enhancing extensions. You can make a case that using a different keyword for same-module extensions that are allowed to have stored properties is a good idea. I’m not sure I would support that though.

2) I’m not proposing changing the meaning of ‘private’ here. Since partial implementations would all glom into one lexical scope, all the current access control rules would apply as they currently do. This is simply a way to write a class or struct declaration in multiple parts, without having to use extensions.

This does not fit with any definition of “lexical scope” I am familiar with. I wouldn’t want to see Swift adopt this definition of lexical scope.

···

On Mar 23, 2017, at 2:04 PM, Charles Srstka <cocoadev@charlessoft.com> wrote:

On Mar 23, 2017, at 1:21 PM, Matthew Johnson <matthew@anandabits.com <mailto:matthew@anandabits.com>> wrote:

Charles

I think limiting it to same-file extensions should be enough to handle most cases. It’s good that it keeps it local to the original declaration, since it would affect things like implicit initialisers.

···

On 23 Mar 2017, at 21:36, Slava Pestov via swift-evolution <swift-evolution@swift.org> wrote:

On Mar 23, 2017, at 11:21 AM, Matthew Johnson via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

1) Allow stored properties in same-module extensions. This has been discussed in the past and is a possibility, but I suspect it is not in scope for consideration during Swift 4.

Allowing stored properties and overridable methods in same-*file* extensions would be trivial to implement.

Same-module extensions are still tricky to generalize because in non-WMO mode, the class (and its metadata, such as stored property layout and vtable) could be emitted in a different translation unit than the extension, so we’d have to ’stitch’ together the definitions somehow and deal with the lack of static knowledge of things like the size of the class and the virtual methods it defines.

Slava
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

I can see why some people might want to do stored properties in extensions to structure things, but personally I quite like the lack of flexibility as it encourages the initial type declaration to focus on what a type contains, while extensions focus on what it does. I've really taken to that style, as I now almost never declare methods or computed properties in an initial type declaration, unless it's a very simple one; instead doing all my methods and protocol conformances in their own extensions.

i.e- I quite like that by the time you've finished your type declaration you have finalised what its size will be, and nothing else can change that, spreading it out feels like it could make that more confusing. It also IMO helps to encourage you to keep a type's contents fairly simple, as you can see in one place if you've made it very complicated.

I suppose there's an argument for having the freedom to do it however you want, but I don't think spreading out across a module is a good idea; unless we're assuming that module in this context applies like in other proposals, where fileprivate is a "module" with only one file.

I dunno, I just think that as a pattern the current requirement to keep stored properties within a type declaration enforces some good practices. I found it a bit jarring at first too, but after adapting to the type + extensions style I find I actually really like doing things that way.

···

On 23 Mar 2017, at 21:10, Vladimir.S via swift-evolution <swift-evolution@swift.org> wrote:

On 23.03.2017 21:21, Matthew Johnson via swift-evolution wrote:

On Mar 23, 2017, at 1:12 PM, Charles Srstka via swift-evolution >>> <swift-evolution@swift.org> wrote:

MOTIVATION:

In current Swift, a pattern has emerged among some developers, in
order to logically group parts of a class or struct’s declaration,
particularly around protocols:

>> ...

What do you think?

If we wanted to allow code like this to be written we wouldn’t need a
new keyword to do it. You are proposing two things here:

1) Allow stored properties in same-module extensions. This has been
discussed in the past and is a possibility, but I suspect it is not in
scope for consideration during Swift 4.

Are we really expect to have stored properties in same-module extensions?
As I remember, there a lot of questions were raised during discussions so for some reason *I* had a feeling that we should not expect this happens in near feature. Probably I missed something.

What I’m suggesting is that we could accomplish the same functionality by enhancing extensions. You can make a case that using a different keyword for same-module extensions that are allowed to have stored properties is a good idea. I’m not sure I would support that though.

The problem is that people are using extensions to implement part of the original class definition. Part of what is making that pattern awkward is that private members are not accessible from the extensions. Given the SE-0159 discussion, it appears that there is a non-negligible threat of losing the very ability to have scoped members at all if we don’t think of a better alternate solution.

2) I’m not proposing changing the meaning of ‘private’ here. Since partial implementations would all glom into one lexical scope, all the current access control rules would apply as they currently do. This is simply a way to write a class or struct declaration in multiple parts, without having to use extensions.

This does not fit with any definition of “lexical scope” I am familiar with. I wouldn’t want to see Swift adopt this definition of lexical scope.

No definitions required. All I’m proposing is basically preprocessing the thing into one type declaration.

class Foo {
  func bar() {}
}

partial Foo {
  func baz() {}
}

just becomes syntactic sugar for:

class Foo {
  func bar() {}
  func baz() {}
}

After this conversion, bar and baz are in the same lexical scope. No new definitions of anything are required.

You can also think of the “Foo_Private.h” headers that can be shared amongst several different files in Objective-C.

Charles

···

On Mar 23, 2017, at 2:15 PM, Matthew Johnson <matthew@anandabits.com> wrote:

If you have a complex class (especially in UI code), you sometimes don’t really care about the size of the class and would prefer data to be grouped in broader functional groups. For example, I might like my toolbar-related iVars to be in one extension, and my datasource-related iVars in another, maybe with a couple of protocol conformances with require the odd state variable.

Requiring all of the stored properties live in the initial declaration means that the code is ultimately less clear: instead of being locally-declared (and perhaps even privately-scoped), the variable is now thousands of lines away from the only place I want to access it directly and visible throughout my implementation for me to one day muck up its state.

Allowing stored extensions within the same file seems like a good compromise to me, especially if its “trivial” to implement ;) Perhaps we could require such types to have some special annotation or magic “ExtensionVariables” item, for the benefit of readability? Just trying to find what you’d feel would be acceptable.

- Karl

···

On 24 Mar 2017, at 10:50, Haravikk via swift-evolution <swift-evolution@swift.org> wrote:

On 23 Mar 2017, at 21:10, Vladimir.S via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On 23.03.2017 21:21, Matthew Johnson via swift-evolution wrote:

On Mar 23, 2017, at 1:12 PM, Charles Srstka via swift-evolution >>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

MOTIVATION:

In current Swift, a pattern has emerged among some developers, in
order to logically group parts of a class or struct’s declaration,
particularly around protocols:

>> ...

What do you think?

If we wanted to allow code like this to be written we wouldn’t need a
new keyword to do it. You are proposing two things here:

1) Allow stored properties in same-module extensions. This has been
discussed in the past and is a possibility, but I suspect it is not in
scope for consideration during Swift 4.

Are we really expect to have stored properties in same-module extensions?
As I remember, there a lot of questions were raised during discussions so for some reason *I* had a feeling that we should not expect this happens in near feature. Probably I missed something.

I can see why some people might want to do stored properties in extensions to structure things, but personally I quite like the lack of flexibility as it encourages the initial type declaration to focus on what a type contains, while extensions focus on what it does. I've really taken to that style, as I now almost never declare methods or computed properties in an initial type declaration, unless it's a very simple one; instead doing all my methods and protocol conformances in their own extensions.

i.e- I quite like that by the time you've finished your type declaration you have finalised what its size will be, and nothing else can change that, spreading it out feels like it could make that more confusing. It also IMO helps to encourage you to keep a type's contents fairly simple, as you can see in one place if you've made it very complicated.

I suppose there's an argument for having the freedom to do it however you want, but I don't think spreading out across a module is a good idea; unless we're assuming that module in this context applies like in other proposals, where fileprivate is a "module" with only one file.

I dunno, I just think that as a pattern the current requirement to keep stored properties within a type declaration enforces some good practices. I found it a bit jarring at first too, but after adapting to the type + extensions style I find I actually really like doing things that way.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

MOTIVATION:

In current Swift, a pattern has emerged among some developers, in
order to logically group parts of a class or struct’s declaration,
particularly around protocols:

>> ...

What do you think?

If we wanted to allow code like this to be written we wouldn’t need a
new keyword to do it. You are proposing two things here:

1) Allow stored properties in same-module extensions. This has been
discussed in the past and is a possibility, but I suspect it is not in
scope for consideration during Swift 4.

Are we really expect to have stored properties in same-module extensions?
As I remember, there a lot of questions were raised during discussions so
for some reason *I* had a feeling that we should not expect this happens
in near feature. Probably I missed something.

I can see why some people might want to do stored properties in extensions
to structure things, but personally I quite like the lack of flexibility as
it encourages the initial type declaration to focus on what a type
*contains*, while extensions focus on what it *does*. I've really taken to
that style, as I now almost never declare methods or computed properties in
an initial type declaration, unless it's a very simple one; instead doing
all my methods and protocol conformances in their own extensions.

The main problem I currently see with extensions: you can't conform to protocol in extension if you want to have stored properties to implement the protocol. And conforming to separate protocol in separate extension is a common practice and usually you need this in the same file when you define the type.
*This* was my main point when I suggest to allow stored properties *only in the same file where the type is declared*.

i.e- I quite like that by the time you've finished your type declaration
you have finalised what its size will be, and nothing else can change that,
spreading it out feels like it could make that more confusing. It also IMO
helps to encourage you to keep a type's contents fairly simple, as you can
see in one place if you've made it very complicated.

I suppose there's an argument for having the freedom to do it however you
want, but I don't think spreading out across a module is a good idea;
unless we're assuming that module in this context applies like in other
proposals, where fileprivate is a "module" with only one file.

Personally, I don't suggest "spreading out across a module", just across the file where the type is declared. I agree that we should not allow this for across the module.

I dunno, I just think that as a pattern the current requirement to keep
stored properties within a type declaration enforces some good practices. I
found it a bit jarring at first too, but after adapting to the type +
extensions style I find I actually really like doing things that way.

Actually, *personally* I see no problems at all to have initially proposed 'partial' syntax in addition to current extensions.

They can solve different problems, while at some situations you can be confused - both can be used to solve the same problem - i.e. you'll have a question, if you want 'extension' or 'partial' to just add utility method / conform to protocol(without stored properties) in *same* source.
*I'm* not afraid of this confusion, it will not be exposed abroad of the file, but I understand that such confusion is a show-stopper for proposal to be accepted.

But I do think that 'partial' should be allowed only in the same file(and later probably only in same submodule)

Moreover, actually I even prefer require a 'partial' modifier for base type declaration also, so even in the same file you can see that type will have additional blocks of declaration:

partial class MyType { // oh, there are additional parts of declarations in *this* file only.
   ...
}

partial MyType {
   ...
}

partial MyType : SomeProtocol {
   ...
}

Even more, I believe that there is an important difference exists between proposed 'partial' as method to split declaration of type(so, we should think about it as compiler will combine all the parts into one single definition) and between extension with allowed stored properties: access to scoped 'private' members. Consider this code:

partial class MyType {
  private var x = 10
  
  func someFunc() { print(boo) } // boo declared in partial
}

extension MyType {
  private var y = 20 // suppose stored properties are allowed
  func foo() {
    print(x) // can access 'x' in the *same* file?
  }
}

extension MyType {
  private var z = 30 // suppose stored properties are allowed
  func bar() {
    print(z+y) // can access 'y' in the same file ?
  }
}

partial MyType {
  private var boo = 100

  func baz() {
    print(x) // should 'partial' access 'x'?
      // (given partial allowed only in the same file)
  }
}

I believe extension should not access the scoped 'private' memeber of type or another extension, while partial declaration should be able to access as this is just the same definition of type like

partial class MyType {
  private var x = 10
  
  func someFunc() { print(boo) }

  private var boo = 100

  func baz() { print(x) }
}

So I want both: extensions and 'partial', But I understand that this can not be accepted because of "level of confusion"(tm) and "cognitive load"(tm) 'partial' adds to the syntax.

So, at least, I'd like to have extensions with stored properties in the same file, even if 'scoped' members can't be exposed to them. It seems like this is a reasonable compromise between "best" and "nothing".

···

On 24.03.2017 12:50, Haravikk wrote:

On 23 Mar 2017, at 21:10, Vladimir.S via swift-evolution >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
On 23.03.2017 21:21, Matthew Johnson via swift-evolution wrote:

On Mar 23, 2017, at 1:12 PM, Charles Srstka via swift-evolution >>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I agree with Haravikk, enabling stored properties in extension will lead to
abuse of the feature, and people will start putting any and everything
while modeling classes retroactively, rather than think about the real
meaning and purpose of extensions which is to provide extended
functionality or convenience methods on objects without change in its basic
structure.

If someone wishes to really make an object which has added properties they
should look into subclassing rather than extending.

···

On 24 March 2017 at 15:20, Haravikk via swift-evolution < swift-evolution@swift.org> wrote:

On 23 Mar 2017, at 21:10, Vladimir.S via swift-evolution < > swift-evolution@swift.org> wrote:

On 23.03.2017 21:21, Matthew Johnson via swift-evolution wrote:

On Mar 23, 2017, at 1:12 PM, Charles Srstka via swift-evolution > <swift-evolution@swift.org> wrote:

MOTIVATION:

In current Swift, a pattern has emerged among some developers, in
order to logically group parts of a class or struct’s declaration,
particularly around protocols:

>> ...

What do you think?

If we wanted to allow code like this to be written we wouldn’t need a
new keyword to do it. You are proposing two things here:

1) Allow stored properties in same-module extensions. This has been
discussed in the past and is a possibility, but I suspect it is not in
scope for consideration during Swift 4.

Are we really expect to have stored properties in same-module extensions?
As I remember, there a lot of questions were raised during discussions so
for some reason *I* had a feeling that we should not expect this happens in
near feature. Probably I missed something.

I can see why some people might want to do stored properties in extensions
to structure things, but personally I quite like the lack of flexibility as
it encourages the initial type declaration to focus on what a type
*contains*, while extensions focus on what it *does*. I've really taken
to that style, as I now almost never declare methods or computed properties
in an initial type declaration, unless it's a very simple one; instead
doing all my methods and protocol conformances in their own extensions.

i.e- I quite like that by the time you've finished your type declaration
you have finalised what its size will be, and nothing else can change that,
spreading it out feels like it could make that more confusing. It also IMO
helps to encourage you to keep a type's contents fairly simple, as you can
see in one place if you've made it very complicated.

I suppose there's an argument for having the freedom to do it however you
want, but I don't think spreading out across a module is a good idea;
unless we're assuming that module in this context applies like in other
proposals, where fileprivate is a "module" with only one file.

I dunno, I just think that as a pattern the current requirement to keep
stored properties within a type declaration enforces some good practices. I
found it a bit jarring at first too, but after adapting to the type +
extensions style I find I actually really like doing things that way.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
*Pranshu Goyal*
*iOS Developer*
*tlkn*

What I’m suggesting is that we could accomplish the same functionality by enhancing extensions. You can make a case that using a different keyword for same-module extensions that are allowed to have stored properties is a good idea. I’m not sure I would support that though.

The problem is that people are using extensions to implement part of the original class definition. Part of what is making that pattern awkward is that private members are not accessible from the extensions. Given the SE-0159 discussion, it appears that there is a non-negligible threat of losing the very ability to have scoped members at all if we don’t think of a better alternate solution.

2) I’m not proposing changing the meaning of ‘private’ here. Since partial implementations would all glom into one lexical scope, all the current access control rules would apply as they currently do. This is simply a way to write a class or struct declaration in multiple parts, without having to use extensions.

This does not fit with any definition of “lexical scope” I am familiar with. I wouldn’t want to see Swift adopt this definition of lexical scope.

No definitions required. All I’m proposing is basically preprocessing the thing into one type declaration.

class Foo {
  func bar() {}
}

partial Foo {
  func baz() {}
}

just becomes syntactic sugar for:

class Foo {
  func bar() {}
  func baz() {}
}

After this conversion, bar and baz are in the same lexical scope. No new definitions of anything are required.

Sure, but this does effectively violate lexical scope boundaries as they exist in the original source.

···

On Mar 23, 2017, at 2:37 PM, Charles Srstka <cocoadev@charlessoft.com> wrote:

On Mar 23, 2017, at 2:15 PM, Matthew Johnson <matthew@anandabits.com <mailto:matthew@anandabits.com>> wrote:

You can also think of the “Foo_Private.h” headers that can be shared amongst several different files in Objective-C.

Charles

Even, so I think this is kind of the right way to do it; protocols don't specify stored properties, only a name and type, so IMO it doesn't necessarily follow that fulfilling that requirement with a store property belongs in an extension.

Consider for example a conformance to Indexable, I want to do this in an extension and I need to decide to how I'm going to handle the startIndex and endIndex properties. For some reason I decide I'll store one in my type and compute the other:

  struct MyCollection<E> {
    let startIndex:Int = 0
  }

  extension MyCollection : Indexable {
    var lastIndex:Int { return someValue() } // it's a really bad collection
  }

Bit contrived I know, but here I've been forced to think about where to put each, hopefully making it more obvious that my choice for startIndex was a waste of space, since it has made MyCollection 4/8 bytes larger.

I just really like that property of the pattern; it also means that, if I keep the type declaration clean, then at a glance I can see what contributes to the type's actual contents and size. Here someone new to the code would immediately see that I was an idiot :wink:

I'll agree that there's some separation from the protocol that it was actually required by, but I prefer it that way to having stored properties scattered around, even within the same file (especially since we're often talking about very large files here for complex types). This "feature" is good for someone new to the code as it makes it easy to learn what is a stored vs computed property, especially if it has encouraged the developer to keep the number of stored properties to a minimum.

I dunno, maybe it comes from having once had header files for everything, but I like this separation of concrete components of a type.

There was a proposal a while ago as an alternative to stored properties in regular extensions, which was the use of "mix-ins", which would be its own category. The aim of those is to modularly build up a type and quickly add conformances from reusable mix-ins, but you could also do it just for a single type.

I preferred that idea because it formalises that this is something you can't just do to an imported type, and gets away from this idea of having something you can do with an extension, but only at the file-scope, which I feel kind of weird about.

···

On 24 Mar 2017, at 12:13, Vladimir.S <svabox@gmail.com> wrote:

On 24.03.2017 12:50, Haravikk wrote:
I can see why some people might want to do stored properties in extensions
to structure things, but personally I quite like the lack of flexibility as
it encourages the initial type declaration to focus on what a type
*contains*, while extensions focus on what it *does*. I've really taken to
that style, as I now almost never declare methods or computed properties in
an initial type declaration, unless it's a very simple one; instead doing
all my methods and protocol conformances in their own extensions.

The main problem I currently see with extensions: you can't conform to protocol in extension if you want to have stored properties to implement the protocol. And conforming to separate protocol in separate extension is a common practice and usually you need this in the same file when you define the type.
*This* was my main point when I suggest to allow stored properties *only in the same file where the type is declared*.

I agree with Haravikk, enabling stored properties in extension will lead to
abuse of the feature, and people will start putting any and everything
while modeling classes retroactively, rather than think about the real
meaning and purpose of extensions which is to provide extended
functionality or convenience methods on objects without change in its basic
structure.

I believe current consensus is that stored properties (at least for now) should be allowed in extensions in the same file with type declaration (probably in submodule also, when we'll have them), not across the module.

If someone wishes to really make an object which has added properties they
should look into subclassing rather than extending.

Also I believe that in most cases we discuss the problem of class *declaration* in the same file, where you often want to use extensions to separate protocol conformances and to separate different kind of type's logic.

To Charles Srstka: would you start new pitch about the proposal for allowing stored properties in extensions in same file? I.e. such proposal IMO has chances to be supported and will solve the main problem you are trying to solve in current proposal.
IMO It is obvious that current proposal "as it is" will not be supported.

···

On 24.03.2017 14:09, Pranshu Goyal wrote:

On 24 March 2017 at 15:20, Haravikk via swift-evolution > <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

    On 23 Mar 2017, at 21:10, Vladimir.S via swift-evolution >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

    On 23.03.2017 21:21, Matthew Johnson via swift-evolution wrote:

    On Mar 23, 2017, at 1:12 PM, Charles Srstka via swift-evolution >>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

    MOTIVATION:

    In current Swift, a pattern has emerged among some developers, in
    order to logically group parts of a class or struct’s declaration,
    particularly around protocols:

    >> ...

    What do you think?

    If we wanted to allow code like this to be written we wouldn’t need a
    new keyword to do it. You are proposing two things here:

    1) Allow stored properties in same-module extensions. This has been
    discussed in the past and is a possibility, but I suspect it is not in
    scope for consideration during Swift 4.

    Are we really expect to have stored properties in same-module extensions?
    As I remember, there a lot of questions were raised during
    discussions so for some reason *I* had a feeling that we should not
    expect this happens in near feature. Probably I missed something.

    I can see why some people might want to do stored properties in
    extensions to structure things, but personally I quite like the lack of
    flexibility as it encourages the initial type declaration to focus on
    what a type *contains*, while extensions focus on what it *does*. I've
    really taken to that style, as I now almost never declare methods or
    computed properties in an initial type declaration, unless it's a very
    simple one; instead doing all my methods and protocol conformances in
    their own extensions.

    i.e- I quite like that by the time you've finished your type
    declaration you have finalised what its size will be, and nothing else
    can change that, spreading it out feels like it could make that more
    confusing. It also IMO helps to encourage you to keep a type's contents
    fairly simple, as you can see in one place if you've made it very
    complicated.

    I suppose there's an argument for having the freedom to do it however
    you want, but I don't think spreading out across a module is a good
    idea; unless we're assuming that module in this context applies like in
    other proposals, where fileprivate is a "module" with only one file.

    I dunno, I just think that as a pattern the current requirement to keep
    stored properties within a type declaration enforces some good
    practices. I found it a bit jarring at first too, but after adapting to
    the type + extensions style I find I actually really like doing things
    that way.

    _______________________________________________
    swift-evolution mailing list
    swift-evolution@swift.org <mailto:swift-evolution@swift.org>
    https://lists.swift.org/mailman/listinfo/swift-evolution
    <https://lists.swift.org/mailman/listinfo/swift-evolution&gt;

--
/Pranshu Goyal/
/iOS Developer/
/tlkn/

Hello Karl,

Don't you think stored properties in extensions would encourage the kind of
code you talked about. I believe may you're doing it while understanding
it's implications and also accepting the fact that it's not easy to write
UI code in a modular way, but do we want everyone to think like this?
Should we accept defeat on the face of this problem that there's no way to
write UI code in a modular way where we don't have to put everything in one
massive view controller?

I feel we would be just raising our hands up if we do it this way

···

On 24 March 2017 at 16:49, Karl Wagner via swift-evolution < swift-evolution@swift.org> wrote:

On 24 Mar 2017, at 10:50, Haravikk via swift-evolution < > swift-evolution@swift.org> wrote:

On 23 Mar 2017, at 21:10, Vladimir.S via swift-evolution < > swift-evolution@swift.org> wrote:

On 23.03.2017 21:21, Matthew Johnson via swift-evolution wrote:

On Mar 23, 2017, at 1:12 PM, Charles Srstka via swift-evolution > <swift-evolution@swift.org> wrote:

MOTIVATION:

In current Swift, a pattern has emerged among some developers, in
order to logically group parts of a class or struct’s declaration,
particularly around protocols:

>> ...

What do you think?

If we wanted to allow code like this to be written we wouldn’t need a
new keyword to do it. You are proposing two things here:

1) Allow stored properties in same-module extensions. This has been
discussed in the past and is a possibility, but I suspect it is not in
scope for consideration during Swift 4.

Are we really expect to have stored properties in same-module extensions?
As I remember, there a lot of questions were raised during discussions so
for some reason *I* had a feeling that we should not expect this happens in
near feature. Probably I missed something.

I can see why some people might want to do stored properties in extensions
to structure things, but personally I quite like the lack of flexibility as
it encourages the initial type declaration to focus on what a type
*contains*, while extensions focus on what it *does*. I've really taken
to that style, as I now almost never declare methods or computed properties
in an initial type declaration, unless it's a very simple one; instead
doing all my methods and protocol conformances in their own extensions.

i.e- I quite like that by the time you've finished your type declaration
you have finalised what its size will be, and nothing else can change that,
spreading it out feels like it could make that more confusing. It also IMO
helps to encourage you to keep a type's contents fairly simple, as you can
see in one place if you've made it very complicated.

I suppose there's an argument for having the freedom to do it however you
want, but I don't think spreading out across a module is a good idea;
unless we're assuming that module in this context applies like in other
proposals, where fileprivate is a "module" with only one file.

I dunno, I just think that as a pattern the current requirement to keep
stored properties within a type declaration enforces some good practices. I
found it a bit jarring at first too, but after adapting to the type +
extensions style I find I actually really like doing things that way.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

If you have a complex class (especially in UI code), you sometimes don’t
really care about the size of the class and would prefer data to be grouped
in broader functional groups. For example, I might like my toolbar-related
iVars to be in one extension, and my datasource-related iVars in another,
maybe with a couple of protocol conformances with require the odd state
variable.

Requiring all of the stored properties live in the initial declaration
means that the code is ultimately less clear: instead of being
locally-declared (and perhaps even privately-scoped), the variable is now
thousands of lines away from the only place I want to access it directly
and visible throughout my implementation for me to one day muck up its
state.

Allowing stored extensions within the same file seems like a good
compromise to me, especially if its “trivial” to implement ;) Perhaps we
could require such types to have some special annotation or magic
“ExtensionVariables” item, for the benefit of readability? Just trying to
find what you’d feel would be acceptable.

- Karl

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
*Pranshu Goyal*
*iOS Developer*
*tlkn*

If the yeas have it on SE-0159, and “private” is turned into “fileprivate”, the lexical scope boundaries of *everything* will be violated as they exist in the original source.

Charles

···

On Mar 23, 2017, at 2:45 PM, Matthew Johnson <matthew@anandabits.com> wrote:

Sure, but this does effectively violate lexical scope boundaries as they exist in the original source.