Re: [swift-evolution] Protected Access

2016-10-07 Thread Charles Srstka via swift-evolution
While that’s true, it’s pretty clearly a hack. Having this built into the 
language would not only be a lot more elegant, but could also prevent 
override-only methods from showing up in Xcode’s autocomplete.

Charles

> On Oct 7, 2016, at 6:36 PM, Callionica (Swift) via swift-evolution 
>  wrote:
> 
> For overridable, but not callable, you can use the technique outlined at 
> http://www.callionica.com/developer/#swift-protected 
> 
> (give your method a parameter of a type that only the base class can create)
> 
> On Friday, October 7, 2016, Jonathan Hull via swift-evolution 
> > wrote:
> The discussion of private/fileprivate reminded me of other access modifier 
> issues that have been bugging me.  I agree that the old system is better, but 
> I am ambivalent about changing it back…
> 
> What I pretty much constantly want is an access modifier which lets me access 
> something from an extension (which is potentially in a different file), but 
> otherwise have it be private.  The vast majority of my use of “fileprivate” 
> is so that I can access internal properties/functions from an extension 
> (which I am forced to place in the same file).
> 
> Access from subclasses is a larger discussion, but I run into this most often 
> with Structs and their extensions.
> 
> 
> The other pieces which seem to be missing are modifiers which allow finer 
> grained control of how class methods are overridden and used.
> 
> It is a fairly common pattern in cocoa, for example, to have customization 
> point methods which are designed to be overridden, but are not supposed to be 
> called directly. Right now, this is enforced via documentation.  One 
> potential solution is to have a @noExternalCall attribute which says that it 
> can only be called from the class/subclass/extensions… but if you think about 
> it, this is basically another view of the first issue. If we could mark that 
> method as only visible within the class/subclasses/extensions, then the 
> behavior we want just falls out naturally. It can’t be called externally, 
> because no one on the outside can see it.
> 
> I also occasionally run into this with protocols.  I find that I have a 
> property on the protocol which is needed for default implementations, but I 
> really want to make it private with respect to the protocol (and its 
> inheritors/extensions).  That is, I want the implementor of the protocol to 
> have visibility for that property, but not the caller of the protocol.  Right 
> now, I have to expose it to everyone (which clutters my external API), and 
> then note in documentation not to call those properties.
> 
> Basically, I want to do the following:
> 
> protocol P {
> hidden var a:Int
> var b:Int
> }
> 
> extension P {
> var c:Int { return self.a + self.b}
> }
> 
> struct A:P {
> private var a:Int = 5  // ‘A’ must implement, but it doesn’t 
> have to expose it externally
> var b:Int = 2
> }
> 
> struct B:P{
> var a:Int = 3  // ‘B’ chooses to expose, which is ok too
> var b:Int = 4
> }
> 
> let ans = A().c  // 7
> let ohNo = A().a // Error!
> 
> Basically ‘hidden’ in the protocol means that the implementor must implement 
> the property, but it is not required to expose it to the world.  I don’t 
> really care whether that is spelled hidden, protected, or private, but I 
> would use this fairly often.
> 
> Thanks,
> Jon
> 
> 
> ___
> 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

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


Re: [swift-evolution] Protected Access

2016-10-07 Thread Xiaodi Wu via swift-evolution
Jon--earlier in the week, there was another thread which once against
raised the idea of internal or private protocol conformances; would that be
another way of addressing your use case here?


On Fri, Oct 7, 2016 at 6:36 PM, Callionica (Swift) via swift-evolution <
swift-evolution@swift.org> wrote:

> For overridable, but not callable, you can use the technique outlined at
> http://www.callionica.com/developer/#swift-protected
> (give your method a parameter of a type that only the base class can
> create)
>
>
> On Friday, October 7, 2016, Jonathan Hull via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> The discussion of private/fileprivate reminded me of other access
>> modifier issues that have been bugging me.  I agree that the old system is
>> better, but I am ambivalent about changing it back…
>>
>> What I pretty much constantly want is an access modifier which lets me
>> access something from an extension (which is potentially in a different
>> file), but otherwise have it be private.  The vast majority of my use of
>> “fileprivate” is so that I can access internal properties/functions from an
>> extension (which I am forced to place in the same file).
>>
>> Access from subclasses is a larger discussion, but I run into this most
>> often with Structs and their extensions.
>>
>>
>> The other pieces which seem to be missing are modifiers which allow finer
>> grained control of how class methods are overridden and used.
>>
>> It is a fairly common pattern in cocoa, for example, to have
>> customization point methods which are designed to be overridden, but are
>> not supposed to be called directly. Right now, this is enforced via
>> documentation.  One potential solution is to have a @noExternalCall
>> attribute which says that it can only be called from the
>> class/subclass/extensions… but if you think about it, this is basically
>> another view of the first issue. If we could mark that method as only
>> visible within the class/subclasses/extensions, then the behavior we want
>> just falls out naturally. It can’t be called externally, because no one on
>> the outside can see it.
>>
>> I also occasionally run into this with protocols.  I find that I have a
>> property on the protocol which is needed for default implementations, but I
>> really want to make it private with respect to the protocol (and its
>> inheritors/extensions).  That is, I want the implementor of the protocol to
>> have visibility for that property, but not the caller of the protocol.
>> Right now, I have to expose it to everyone (which clutters my external
>> API), and then note in documentation not to call those properties.
>>
>> Basically, I want to do the following:
>>
>> protocol P {
>> hidden var a:Int
>> var b:Int
>> }
>>
>> extension P {
>> var c:Int { return self.a + self.b}
>> }
>>
>> struct A:P {
>> private var a:Int = 5  // ‘A’ must implement, but it
>> doesn’t have to expose it externally
>> var b:Int = 2
>> }
>>
>> struct B:P{
>> var a:Int = 3  // ‘B’ chooses to expose, which is ok too
>> var b:Int = 4
>> }
>>
>> let ans = A().c  // 7
>> let ohNo = A().a // Error!
>>
>> Basically ‘hidden’ in the protocol means that the implementor must
>> implement the property, but it is not required to expose it to the world.
>> I don’t really care whether that is spelled hidden, protected, or private,
>> but I would use this fairly often.
>>
>> Thanks,
>> Jon
>>
>>
>> ___
>> 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
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Protected Access

2016-10-07 Thread Callionica (Swift) via swift-evolution
For overridable, but not callable, you can use the technique outlined at
http://www.callionica.com/developer/#swift-protected
(give your method a parameter of a type that only the base class can create)

On Friday, October 7, 2016, Jonathan Hull via swift-evolution <
swift-evolution@swift.org> wrote:

> The discussion of private/fileprivate reminded me of other access modifier
> issues that have been bugging me.  I agree that the old system is better,
> but I am ambivalent about changing it back…
>
> What I pretty much constantly want is an access modifier which lets me
> access something from an extension (which is potentially in a different
> file), but otherwise have it be private.  The vast majority of my use of
> “fileprivate” is so that I can access internal properties/functions from an
> extension (which I am forced to place in the same file).
>
> Access from subclasses is a larger discussion, but I run into this most
> often with Structs and their extensions.
>
>
> The other pieces which seem to be missing are modifiers which allow finer
> grained control of how class methods are overridden and used.
>
> It is a fairly common pattern in cocoa, for example, to have customization
> point methods which are designed to be overridden, but are not supposed to
> be called directly. Right now, this is enforced via documentation.  One
> potential solution is to have a @noExternalCall attribute which says that
> it can only be called from the class/subclass/extensions… but if you think
> about it, this is basically another view of the first issue. If we could
> mark that method as only visible within the class/subclasses/extensions,
> then the behavior we want just falls out naturally. It can’t be called
> externally, because no one on the outside can see it.
>
> I also occasionally run into this with protocols.  I find that I have a
> property on the protocol which is needed for default implementations, but I
> really want to make it private with respect to the protocol (and its
> inheritors/extensions).  That is, I want the implementor of the protocol to
> have visibility for that property, but not the caller of the protocol.
> Right now, I have to expose it to everyone (which clutters my external
> API), and then note in documentation not to call those properties.
>
> Basically, I want to do the following:
>
> protocol P {
> hidden var a:Int
> var b:Int
> }
>
> extension P {
> var c:Int { return self.a + self.b}
> }
>
> struct A:P {
> private var a:Int = 5  // ‘A’ must implement, but it
> doesn’t have to expose it externally
> var b:Int = 2
> }
>
> struct B:P{
> var a:Int = 3  // ‘B’ chooses to expose, which is ok too
> var b:Int = 4
> }
>
> let ans = A().c  // 7
> let ohNo = A().a // Error!
>
> Basically ‘hidden’ in the protocol means that the implementor must
> implement the property, but it is not required to expose it to the world.
> I don’t really care whether that is spelled hidden, protected, or private,
> but I would use this fairly often.
>
> Thanks,
> Jon
>
>
> ___
> 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


Re: [swift-evolution] Protected Access

2016-10-07 Thread Shawn Erickson via swift-evolution
I agree with and also feel access modifiers / controls are missing and the
ones we have may not be the best if you factor in these additional needs. I
also agree that I would prefer the discussion be more focused on this type
of thing. Thanks for capturing some of the things you have seen (I have
been meaning to do that myself but lacking in time and will do far).
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] Protected Access

2016-10-07 Thread Jonathan Hull via swift-evolution
The discussion of private/fileprivate reminded me of other access modifier 
issues that have been bugging me.  I agree that the old system is better, but I 
am ambivalent about changing it back…

What I pretty much constantly want is an access modifier which lets me access 
something from an extension (which is potentially in a different file), but 
otherwise have it be private.  The vast majority of my use of “fileprivate” is 
so that I can access internal properties/functions from an extension (which I 
am forced to place in the same file).

Access from subclasses is a larger discussion, but I run into this most often 
with Structs and their extensions.


The other pieces which seem to be missing are modifiers which allow finer 
grained control of how class methods are overridden and used.  

It is a fairly common pattern in cocoa, for example, to have customization 
point methods which are designed to be overridden, but are not supposed to be 
called directly. Right now, this is enforced via documentation.  One potential 
solution is to have a @noExternalCall attribute which says that it can only be 
called from the class/subclass/extensions… but if you think about it, this is 
basically another view of the first issue. If we could mark that method as only 
visible within the class/subclasses/extensions, then the behavior we want just 
falls out naturally. It can’t be called externally, because no one on the 
outside can see it.

I also occasionally run into this with protocols.  I find that I have a 
property on the protocol which is needed for default implementations, but I 
really want to make it private with respect to the protocol (and its 
inheritors/extensions).  That is, I want the implementor of the protocol to 
have visibility for that property, but not the caller of the protocol.  Right 
now, I have to expose it to everyone (which clutters my external API), and then 
note in documentation not to call those properties.

Basically, I want to do the following:

protocol P {
hidden var a:Int
var b:Int
}

extension P {
var c:Int { return self.a + self.b}
}

struct A:P {
private var a:Int = 5  // ‘A’ must implement, but it doesn’t 
have to expose it externally
var b:Int = 2
}

struct B:P{
var a:Int = 3  // ‘B’ chooses to expose, which is ok too
var b:Int = 4
}

let ans = A().c  // 7
let ohNo = A().a // Error!

Basically ‘hidden’ in the protocol means that the implementor must implement 
the property, but it is not required to expose it to the world.  I don’t really 
care whether that is spelled hidden, protected, or private, but I would use 
this fairly often.

Thanks,
Jon


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


Re: [swift-evolution] Protected access level / multiple class/struct/protocol APIs

2016-04-28 Thread Andrey Tarantsov via swift-evolution
Let me bump this thread. How do we move forward?

Here's an interface of another Swift class I've just made (slowly rewriting my 
Obj-C components to Swift here):

public class SoloContainerViewController: UIViewController {

private var _contentViewController: UIViewController?

public var contentViewController: UIViewController?  // delegates to 
setContentViewController:animated:completion:

public init(contentViewController: UIViewController?) { ... }

public required init?(coder aDecoder: NSCoder) { ... }

public override func viewDidLoad() { ... }

public func setContentViewController(contentViewController: 
UIViewController?, animated: Bool, completion completionBlock: 
dispatch_block_t?) { ... }

public /*protected*/ func transition(fromView oldView: UIView?, toView 
newView: UIView?, animated: Bool, completion completionBlock: (finished: Bool) 
-> Void) { ... }

public /*protected*/ func 
willTransitionToContentViewController(newViewController: UIViewController?) { 
... }

public /*protected*/ func 
didTransitionFromContentViewController(oldViewController: UIViewController?) { 
... }

}

This is madness, we have to do SOMETHING!

This class is designed to be subclassed, with a bunch of hooks that subclasses 
may be interested in. Most of the reusable views and view controllers that I 
make look like this.

Even when I use delegates, I still forward delegate calls through overridable 
protected methods, based on my long history of subclassing UIScrollView (and 
other controls) and wishing that the subclass had access to the delegate 
methods.

Nobody outside of the class should be interested in those protected methods; 
they are not safe to call, they're override points.

And I often have to pick very telling method names, so that I don't end up 
accidentally calling one of those methods from outside. Sometimes that's fairly 
hard, like when there's a public save(), a private saveNow() and a protected 
saveContent().


Our best consensus the last time was:

>>> My point is that "protected" *isn't* access control. If we added it, it 
>>> would have to be as an independent modifier.
> 
> Okay. So you see it as “public subclassonly”, leaving space for “internal 
> subclassonly” (which makes sense, although not as important in practice).
> 
> I can agree with that, let's consider it a new strawman.


So how do we move forward?

A.

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


Re: [swift-evolution] Protected access level / multiple class/struct/protocol APIs

2016-04-03 Thread Andrey Tarantsov via swift-evolution
>> My point is that "protected" *isn't* access control. If we added it, it 
>> would have to be as an independent modifier. Private/internal/public 
>> fundamentally affect semantics—private and internal code is only accessible 
>> within a module, so we have full knowledge of their use sites at compile 
>> time and can be more permissive with extensions, implicit constructors, and 
>> other features. Public API can be used by arbitrary unknown external code so 
>> requires additional restrictions to ensure that the interface remains 
>> stable. "Only usable by subclasses" is an orthogonal axis to this—if a 
>> method is only usable by external subclasses, it requires all of the same 
>> restrictions as public code. If a method is only usable by subclasses within 
>> the module, it can behave like a private or internal method.

Okay. So you see it as “public subclassonly”, leaving space for “internal 
subclassonly” (which makes sense, although not as important in practice).

I can agree with that, let's consider it a new strawman.

I wonder, though, if you guys have additional, fresh ideas on the underlying 
problem. We're not really limiting to subclasses here — we're limiting to 
“extenders” aka “service providers”, and those don't necessarily take a form of 
a subclass. I've listed some examples in my strawman: an implementation of a 
protocol, an extension of a class/protocol.

Are there any novel and fresh ideas that would take care of all that in a 
straightforward and uncomplicated way?

A.

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


Re: [swift-evolution] Protected access level / multiple class/struct/protocol APIs

2016-03-31 Thread Thorsten Seitz via swift-evolution

> Am 31.03.2016 um 17:51 schrieb Joe Groff :
> 
>> 
>> On Mar 30, 2016, at 11:31 PM, Thorsten Seitz  wrote:
>> 
>> 
>> 
>> Am 31. März 2016 um 05:15 schrieb Andrey Tarantsov via swift-evolution 
>> :
>> 
 The problem with protected is that it provides virtually no protection at 
 all; you can trivially expose it in a derived class
>>> 
>>> +
>>> 
 Extensions further dilute the enforceability of "protected", since anyone 
 would be able to use an extension to dump methods into a class's namespace 
 and access its supposedly-protected bits.
>>> 
>>> I don't understand the need to protect against exposing something 
>>> deliberately. We don't have a goal of restricting other developers, we're 
>>> only saving them from accidental mistakes.
>> 
>> Totally agree, access control is not intended to be protection against 
>> hacking. If a derived class wants to expose something then that is 
>> absolutely fine as long as it makes sense for the derived class.
> 
> My point is that "protected" *isn't* access control. If we added it, it would 
> have to be as an independent modifier. Private/internal/public fundamentally 
> affect semantics—private and internal code is only accessible within a 
> module, so we have full knowledge of their use sites at compile time and can 
> be more permissive with extensions, implicit constructors, and other 
> features. Public API can be used by arbitrary unknown external code so 
> requires additional restrictions to ensure that the interface remains stable. 
> "Only usable by subclasses" is an orthogonal axis to this—if a method is only 
> usable by external subclasses, it requires all of the same restrictions as 
> public code. If a method is only usable by subclasses within the module, it 
> can behave like a private or internal method.

Ah, now I understand what you mean! Thanks for clarifying!
I agree that this has to be taken into account when defining what „protected“ 
means and how it interacts with other parts of the language.

-Thorsten


> 
> -Joe
> 
>> 
>> 
 If a method was marked private in the base class, then it is very likely 
 that the name of the method, the design of its argument list and its 
 return value did not go through the same detailed design review as if the 
 method would have been meant to be part of the class’ interface from the 
 start. So it’s rather unlikely that increasing the visibility in an 
 override is good idea and in the spirit of the original writer of the 
 private method.
>>> 
>>> The design review and whether something is a good idea is left as a 
>>> responsibility for those subclasses that choose to expose methods. The 
>>> intentions of the original class author don't override the intentions of 
>>> the subclass author.
>> 
>> Exactly.
>> 
>> -Thorsten

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


Re: [swift-evolution] Protected access level / multiple class/struct/protocol APIs

2016-03-31 Thread Joe Groff via swift-evolution

> On Mar 30, 2016, at 11:31 PM, Thorsten Seitz  wrote:
> 
> 
> 
> Am 31. März 2016 um 05:15 schrieb Andrey Tarantsov via swift-evolution 
> :
> 
>>> The problem with protected is that it provides virtually no protection at 
>>> all; you can trivially expose it in a derived class
>> 
>> +
>> 
>>> Extensions further dilute the enforceability of "protected", since anyone 
>>> would be able to use an extension to dump methods into a class's namespace 
>>> and access its supposedly-protected bits.
>> 
>> I don't understand the need to protect against exposing something 
>> deliberately. We don't have a goal of restricting other developers, we're 
>> only saving them from accidental mistakes.
> 
> Totally agree, access control is not intended to be protection against 
> hacking. If a derived class wants to expose something then that is absolutely 
> fine as long as it makes sense for the derived class.

My point is that "protected" *isn't* access control. If we added it, it would 
have to be as an independent modifier. Private/internal/public fundamentally 
affect semantics—private and internal code is only accessible within a module, 
so we have full knowledge of their use sites at compile time and can be more 
permissive with extensions, implicit constructors, and other features. Public 
API can be used by arbitrary unknown external code so requires additional 
restrictions to ensure that the interface remains stable. "Only usable by 
subclasses" is an orthogonal axis to this—if a method is only usable by 
external subclasses, it requires all of the same restrictions as public code. 
If a method is only usable by subclasses within the module, it can behave like 
a private or internal method.

-Joe

> 
> 
>>> If a method was marked private in the base class, then it is very likely 
>>> that the name of the method, the design of its argument list and its return 
>>> value did not go through the same detailed design review as if the method 
>>> would have been meant to be part of the class’ interface from the start. So 
>>> it’s rather unlikely that increasing the visibility in an override is good 
>>> idea and in the spirit of the original writer of the private method.
>> 
>> The design review and whether something is a good idea is left as a 
>> responsibility for those subclasses that choose to expose methods. The 
>> intentions of the original class author don't override the intentions of the 
>> subclass author.
> 
> Exactly.
> 
> -Thorsten

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


Re: [swift-evolution] Protected access level / multiple class/struct/protocol APIs

2016-03-31 Thread Thorsten Seitz via swift-evolution
 ___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Protected access level / multiple class/struct/protocol APIs

2016-03-30 Thread Andrey Tarantsov via swift-evolution
> The problem with protected is that it provides virtually no protection at 
> all; you can trivially expose it in a derived class

+

> Extensions further dilute the enforceability of "protected", since anyone 
> would be able to use an extension to dump methods into a class's namespace 
> and access its supposedly-protected bits.

I don't understand the need to protect against exposing something deliberately. 
We don't have a goal of restricting other developers, we're only saving them 
from accidental mistakes.


> If a method was marked private in the base class, then it is very likely that 
> the name of the method, the design of its argument list and its return value 
> did not go through the same detailed design review as if the method would 
> have been meant to be part of the class’ interface from the start. So it’s 
> rather unlikely that increasing the visibility in an override is good idea 
> and in the spirit of the original writer of the private method.

The design review and whether something is a good idea is left as a 
responsibility for those subclasses that choose to expose methods. The 
intentions of the original class author don't override the intentions of the 
subclass author.


That said, I don't necessarily believe that the protected modifier is the best 
solution for the problems we're discussing. Some methods are not intended to be 
called at all, and protected doesn't solve that.

A.

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


Re: [swift-evolution] Protected access level / multiple class/struct/protocol APIs

2016-03-30 Thread Dietmar Planitzer via swift-evolution

> On Mar 29, 2016, at 18:28, Joe Groff  wrote:
> 
> 
>> On Mar 29, 2016, at 6:18 PM, Joe Groff via swift-evolution 
>>  wrote:
>> 
>>> 
>>> On Mar 29, 2016, at 6:04 PM, Dietmar Planitzer via swift-evolution 
>>>  wrote:
>>> 
>>> Well that would be true if we assume that protected would work that way. 
>>> Considering that this:
>>> 
>>> private class A { … }
>>> 
>>> public class B : A { … }
>>> 
>>> is not allowed in Swift, I don’t see a good reason why an override of a 
>>> protected method should be allowed to upgrade the access level to public. 
>>> On the other hand this:
>>> 
>>> public class A {
>>>  private func foo() {
>>>  print("A")
>>>  }
>>> }
>>> 
>>> public class B : A {
>>>  public override func foo() {
>>>  print(“B”)
>>>  }
>>> }
>>> 
>>> happens to actually work if both A and B are defined in the same file - 
>>> which is rather unexpected. I would have expected that Swift would in 
>>> general not allow overrides to upgrade the inherited access level. Eg 
>>> exposing semantics which is embodied in a private or protected method 
>>> should require a conscisous design decision and should require the designer 
>>> to introduce a separate method name which is part of the public API. The 
>>> public method can then call through to the private or protected method as 
>>> needed.
>> 
>> That would still be a toothless restriction, since a subclass could define a 
>> new method:
>> 
>> public class B : A {
>>  public func foo_() {
>>  super.foo()
>>  }
>> }
>> 
>> From an interface perspective, there's no difference between a subclass 
>> defining a new method or overriding a method that happens to be private to 
>> the base class.
> 
> Extensions further dilute the enforceability of "protected", since anyone 
> would be able to use an extension to dump methods into a class's namespace 
> and access its supposedly-protected bits.

That is true assuming that Swift would allow an extension to call a protected 
method. But I don’t see a strict requirement that Swift would have to allow 
this.

There are two variants of extensions that are useful:

a) extension is used by the producer of a type to break up a large 
implementation into smaller pieces: in this case the implementor writes those 
extensions and in this case you can argue that an extension should allow the 
code writer to do everything that he can do in a base type. Eg allow the 
definition of stored properties and allow the calling of protected methods (and 
likely private methods too). Swift doesn’t currently really support this. 
Ideally it would be possible to put each extension into a separate file and 
things like accessing private members would still work.

b) extension is used by a consumer of a type to extend the type after the fact: 
in this case it makes sense that an extension comes with certain restrictions. 
Eg you can not add stored properties (which especially in the case of value 
types could change the nature of the value type drastically) and you can not 
call private or protected methods. This is what Swift’s extensions are today.


Regards,

Dietmar Planitzer

> -Joe

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


Re: [swift-evolution] Protected access level / multiple class/struct/protocol APIs

2016-03-30 Thread Dietmar Planitzer via swift-evolution

> On Mar 29, 2016, at 18:18, Joe Groff  wrote:
> 
> 
>> On Mar 29, 2016, at 6:04 PM, Dietmar Planitzer via swift-evolution 
>>  wrote:
>> 
>> Well that would be true if we assume that protected would work that way. 
>> Considering that this:
>> 
>> private class A { … }
>> 
>> public class B : A { … }
>> 
>> is not allowed in Swift, I don’t see a good reason why an override of a 
>> protected method should be allowed to upgrade the access level to public. On 
>> the other hand this:
>> 
>> public class A {
>>   private func foo() {
>>   print("A")
>>   }
>> }
>> 
>> public class B : A {
>>   public override func foo() {
>>   print(“B”)
>>   }
>> }
>> 
>> happens to actually work if both A and B are defined in the same file - 
>> which is rather unexpected. I would have expected that Swift would in 
>> general not allow overrides to upgrade the inherited access level. Eg 
>> exposing semantics which is embodied in a private or protected method should 
>> require a conscisous design decision and should require the designer to 
>> introduce a separate method name which is part of the public API. The public 
>> method can then call through to the private or protected method as needed.
> 
> That would still be a toothless restriction, since a subclass could define a 
> new method:
> 
> public class B : A {
>   public func foo_() {
>   super.foo()
>   }
> }
> 
> From an interface perspective, there's no difference between a subclass 
> defining a new method or overriding a method that happens to be private to 
> the base class.

If a method was marked private in the base class, then it is very likely that 
the name of the method, the design of its argument list and its return value 
did not go through the same detailed design review as if the method would have 
been meant to be part of the class’ interface from the start. So it’s rather 
unlikely that increasing the visibility in an override is good idea and in the 
spirit of the original writer of the private method. If on the other side I’m 
required to introduce a new method name if I want to make the semantics of the 
private method part of my public interface, then (a) it gives me an opportunity 
to think about what kind of interface I want to commit to and (b) it gives me 
stability because it doesn’t matter anymore what is going to happen over time 
to the name, argument list and return value of the private method since the 
name and signature of my public method is now decoupled from the ones of the 
private method.

Also, your argument would just as well apply to the scenario below since a 
class is a collection of methods when you look at it purely from an interface 
perspective:

private class A { … }

public class B : A { … }

but Swift doesn’t allow this. 


Regards,

Dietmar Planitzer


> -Joe
> 

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


Re: [swift-evolution] Protected access level / multiple class/struct/protocol APIs

2016-03-30 Thread Diego Sánchez via swift-evolution
That's the key point.

"Protected" would increase the expressivity of the language by declaring
intent and exposing cleaner public APIs.

I don't think this idea should be dropped just because conscious
hacks/decisions
can workaround it, so big +1 for it.

2016-03-30 5:51 GMT+01:00 Thorsten Seitz via swift-evolution <
swift-evolution@swift.org>:

> I have no problems with "protected" members being made accessible in
> subclasses or extensions because this requires conscious decisions and
> actions to extend the API.
> Access levels are not there to protect against hacking, they are there to
> ensure that something can only be used through its given API. They are not
> there to restrict extending that API.
>
> Having said that I'd love to have "protected".
>
> -Thorsten
>
> > Am 30.03.2016 um 03:28 schrieb Joe Groff via swift-evolution <
> swift-evolution@swift.org>:
> >
> >
> >>> On Mar 29, 2016, at 6:18 PM, Joe Groff via swift-evolution <
> swift-evolution@swift.org> wrote:
> >>>
> >>>
> >>> On Mar 29, 2016, at 6:04 PM, Dietmar Planitzer via swift-evolution <
> swift-evolution@swift.org> wrote:
> >>>
> >>> Well that would be true if we assume that protected would work that
> way. Considering that this:
> >>>
> >>> private class A { … }
> >>>
> >>> public class B : A { … }
> >>>
> >>> is not allowed in Swift, I don’t see a good reason why an override of
> a protected method should be allowed to upgrade the access level to public.
> On the other hand this:
> >>>
> >>> public class A {
> >>>  private func foo() {
> >>>  print("A")
> >>>  }
> >>> }
> >>>
> >>> public class B : A {
> >>>  public override func foo() {
> >>>  print(“B”)
> >>>  }
> >>> }
> >>>
> >>> happens to actually work if both A and B are defined in the same file
> - which is rather unexpected. I would have expected that Swift would in
> general not allow overrides to upgrade the inherited access level. Eg
> exposing semantics which is embodied in a private or protected method
> should require a conscisous design decision and should require the designer
> to introduce a separate method name which is part of the public API. The
> public method can then call through to the private or protected method as
> needed.
> >>
> >> That would still be a toothless restriction, since a subclass could
> define a new method:
> >>
> >> public class B : A {
> >>  public func foo_() {
> >>  super.foo()
> >>  }
> >> }
> >>
> >> From an interface perspective, there's no difference between a subclass
> defining a new method or overriding a method that happens to be private to
> the base class.
> >
> > Extensions further dilute the enforceability of "protected", since
> anyone would be able to use an extension to dump methods into a class's
> namespace and access its supposedly-protected bits.
> >
> > -Joe
> > ___
> > 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
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Protected access level / multiple class/struct/protocol APIs

2016-03-29 Thread Thorsten Seitz via swift-evolution
I have no problems with "protected" members being made accessible in subclasses 
or extensions because this requires conscious decisions and actions to extend 
the API.
Access levels are not there to protect against hacking, they are there to 
ensure that something can only be used through its given API. They are not 
there to restrict extending that API.

Having said that I'd love to have "protected".

-Thorsten 

> Am 30.03.2016 um 03:28 schrieb Joe Groff via swift-evolution 
> :
> 
> 
>>> On Mar 29, 2016, at 6:18 PM, Joe Groff via swift-evolution 
>>>  wrote:
>>> 
>>> 
>>> On Mar 29, 2016, at 6:04 PM, Dietmar Planitzer via swift-evolution 
>>>  wrote:
>>> 
>>> Well that would be true if we assume that protected would work that way. 
>>> Considering that this:
>>> 
>>> private class A { … }
>>> 
>>> public class B : A { … }
>>> 
>>> is not allowed in Swift, I don’t see a good reason why an override of a 
>>> protected method should be allowed to upgrade the access level to public. 
>>> On the other hand this:
>>> 
>>> public class A {
>>>  private func foo() {
>>>  print("A")
>>>  }
>>> }
>>> 
>>> public class B : A {
>>>  public override func foo() {
>>>  print(“B”)
>>>  }
>>> }
>>> 
>>> happens to actually work if both A and B are defined in the same file - 
>>> which is rather unexpected. I would have expected that Swift would in 
>>> general not allow overrides to upgrade the inherited access level. Eg 
>>> exposing semantics which is embodied in a private or protected method 
>>> should require a conscisous design decision and should require the designer 
>>> to introduce a separate method name which is part of the public API. The 
>>> public method can then call through to the private or protected method as 
>>> needed.
>> 
>> That would still be a toothless restriction, since a subclass could define a 
>> new method:
>> 
>> public class B : A {
>>  public func foo_() {
>>  super.foo()
>>  }
>> }
>> 
>> From an interface perspective, there's no difference between a subclass 
>> defining a new method or overriding a method that happens to be private to 
>> the base class.
> 
> Extensions further dilute the enforceability of "protected", since anyone 
> would be able to use an extension to dump methods into a class's namespace 
> and access its supposedly-protected bits.
> 
> -Joe
> ___
> 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


Re: [swift-evolution] Protected access level / multiple class/struct/protocol APIs

2016-03-29 Thread Joe Groff via swift-evolution

> On Mar 29, 2016, at 6:18 PM, Joe Groff via swift-evolution 
>  wrote:
> 
>> 
>> On Mar 29, 2016, at 6:04 PM, Dietmar Planitzer via swift-evolution 
>>  wrote:
>> 
>> Well that would be true if we assume that protected would work that way. 
>> Considering that this:
>> 
>> private class A { … }
>> 
>> public class B : A { … }
>> 
>> is not allowed in Swift, I don’t see a good reason why an override of a 
>> protected method should be allowed to upgrade the access level to public. On 
>> the other hand this:
>> 
>> public class A {
>>   private func foo() {
>>   print("A")
>>   }
>> }
>> 
>> public class B : A {
>>   public override func foo() {
>>   print(“B”)
>>   }
>> }
>> 
>> happens to actually work if both A and B are defined in the same file - 
>> which is rather unexpected. I would have expected that Swift would in 
>> general not allow overrides to upgrade the inherited access level. Eg 
>> exposing semantics which is embodied in a private or protected method should 
>> require a conscisous design decision and should require the designer to 
>> introduce a separate method name which is part of the public API. The public 
>> method can then call through to the private or protected method as needed.
> 
> That would still be a toothless restriction, since a subclass could define a 
> new method:
> 
> public class B : A {
>   public func foo_() {
>   super.foo()
>   }
> }
> 
> From an interface perspective, there's no difference between a subclass 
> defining a new method or overriding a method that happens to be private to 
> the base class.

Extensions further dilute the enforceability of "protected", since anyone would 
be able to use an extension to dump methods into a class's namespace and access 
its supposedly-protected bits.

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


Re: [swift-evolution] Protected access level / multiple class/struct/protocol APIs

2016-03-29 Thread Joe Groff via swift-evolution

> On Mar 29, 2016, at 6:04 PM, Dietmar Planitzer via swift-evolution 
>  wrote:
> 
> Well that would be true if we assume that protected would work that way. 
> Considering that this:
> 
> private class A { … }
> 
> public class B : A { … }
> 
> is not allowed in Swift, I don’t see a good reason why an override of a 
> protected method should be allowed to upgrade the access level to public. On 
> the other hand this:
> 
> public class A {
>private func foo() {
>print("A")
>}
> }
> 
> public class B : A {
>public override func foo() {
>print(“B”)
>}
> }
> 
> happens to actually work if both A and B are defined in the same file - which 
> is rather unexpected. I would have expected that Swift would in general not 
> allow overrides to upgrade the inherited access level. Eg exposing semantics 
> which is embodied in a private or protected method should require a 
> conscisous design decision and should require the designer to introduce a 
> separate method name which is part of the public API. The public method can 
> then call through to the private or protected method as needed.

That would still be a toothless restriction, since a subclass could define a 
new method:

public class B : A {
   public func foo_() {
   super.foo()
   }
}

From an interface perspective, there's no difference between a subclass 
defining a new method or overriding a method that happens to be private to the 
base class.

-Joe

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


Re: [swift-evolution] Protected access level / multiple class/struct/protocol APIs

2016-03-29 Thread Dietmar Planitzer via swift-evolution
Well that would be true if we assume that protected would work that way. 
Considering that this:

private class A { … }

public class B : A { … }

is not allowed in Swift, I don’t see a good reason why an override of a 
protected method should be allowed to upgrade the access level to public. On 
the other hand this:

public class A {
private func foo() {
print("A")
}
}

public class B : A {
public override func foo() {
print(“B”)
}
}

happens to actually work if both A and B are defined in the same file - which 
is rather unexpected. I would have expected that Swift would in general not 
allow overrides to upgrade the inherited access level. Eg exposing semantics 
which is embodied in a private or protected method should require a conscisous 
design decision and should require the designer to introduce a separate method 
name which is part of the public API. The public method can then call through 
to the private or protected method as needed.

Anyway, I do think that a protected access level would be a useful tool to have 
exactly because it would allow me to clearly communicated the intent of whether 
a method is only there for use by subclassers. Today I can’t do that and thus I 
have to mark the method as public and thus make it part of the overall class 
API which means that I end up making a much bigger promise than I actually 
intended to give.


Regards,

Dietmar Planitzer



> On Mar 29, 2016, at 16:56, Howard Lovatt via swift-evolution 
>  wrote:
> 
> I tend to think an intended use annotation that could also be used in Obj-C 
> would be better than protected. The problem with protected is that it 
> provides virtually no protection at all; you can trivially expose it in a 
> derived class, e.g.:
> 
> class Protected {
> protected func onlyDerived() { ... }
> }
> 
> class Derived: Protected {
> public override func onlyDerived() { super.onlyDerived() }
> }
> 
> let d = Derived()
> d.onlyDerived() // Protection lost
> 
> Therefore an annotation would be just as effective.
> 
>   -- Howard.
> 
> On 29 March 2016 at 21:54, Andrey Tarantsov via swift-evolution 
>  wrote:
> 
> > Imho it would be nice to be able to mark a method that is only there to be 
> > overridden and should never be called directly, but I don't think the 
> > compiler has to enforce this:
> > An official way to document the intent that affects autocompletion would be 
> > sufficient for me.
> 
> An interesting idea that I see reflected in another proposal (intendedusage 
> doc tag, or something like that).
> 
> Why, though? If we can express it, why not also make it a part of the 
> signature and get warnings/errors on violations?
> 
> I have an argument in favor of annotations:
> 
> + The documentation is known to lie and to get out of date, even when acting 
> on best intentions. I know mine did, and I'm writing a lot less of it now. So 
> I also see compiler-enforced annotations as “more reliable documentation”.
> 
> What are other possible arguments for and against?
> 
> > - callable (read for properties)
> > - can override, call to super enforced
> > - can override
> > - has to be overridden (abstract)
> > - properties only: Write access
> 
> You're right, perhaps this isn't so much about access as it is about intended 
> usage. (Not sure what that distinction means in practice, though.)
> 
> A.
> ___
> 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

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


Re: [swift-evolution] Protected access level / multiple class/struct/protocol APIs

2016-03-29 Thread Howard Lovatt via swift-evolution
I tend to think an intended use annotation that could also be used in Obj-C
would be better than protected. The problem with protected is that it
provides virtually no protection at all; you can trivially expose it in a
derived class, e.g.:

class Protected {

protected func onlyDerived() { ... }

}

class Derived: Protected {

public override func onlyDerived() { super.onlyDerived() }

}

let d = Derived()
d.onlyDerived() // Protection lost

Therefore an annotation would be just as effective.

  -- Howard.

On 29 March 2016 at 21:54, Andrey Tarantsov via swift-evolution <
swift-evolution@swift.org> wrote:

>
> > Imho it would be nice to be able to mark a method that is only there to
> be overridden and should never be called directly, but I don't think the
> compiler has to enforce this:
> > An official way to document the intent that affects autocompletion would
> be sufficient for me.
>
> An interesting idea that I see reflected in another proposal
> (intendedusage doc tag, or something like that).
>
> Why, though? If we can express it, why not also make it a part of the
> signature and get warnings/errors on violations?
>
> I have an argument in favor of annotations:
>
> + The documentation is known to lie and to get out of date, even when
> acting on best intentions. I know mine did, and I'm writing a lot less of
> it now. So I also see compiler-enforced annotations as “more reliable
> documentation”.
>
> What are other possible arguments for and against?
>
> > - callable (read for properties)
> > - can override, call to super enforced
> > - can override
> > - has to be overridden (abstract)
> > - properties only: Write access
>
> You're right, perhaps this isn't so much about access as it is about
> intended usage. (Not sure what that distinction means in practice, though.)
>
> A.
> ___
> 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


Re: [swift-evolution] Protected access level / multiple class/struct/protocol APIs

2016-03-29 Thread Tino Heth via swift-evolution
A more sophisticated rights system isn't necessary, but actually, we could 
build everything with nothing but "public", so it is always a compromise 
between simplicity and expressiveness…
Imho it would be nice to be able to mark a method that is only there to be 
overridden and should never be called directly, but I don't think the compiler 
has to enforce this:
An official way to document the intent that affects autocompletion would be 
sufficient for me.

Besides the question where (class/module/public…) something is visible, there 
is also the question of what can or has to be done with a method:

- callable (read for properties)
- can override, call to super enforced
- can override
- has to be overridden (abstract)
- properties only: Write access

If there is an elegant way to handle all use cases, I'd strongly support this 
direction.

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