Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-13 Thread Tino Heth via swift-evolution

> Publishing a library is a promise of something. It ought to only be promises 
> the library author wants to make. If “the truth” is “the implementation in 
> the current version of the library”, that’s definitely not what a library 
> author should promise. That’s true for plenty of things, not just whether or 
> not overriding is expected.
Correct, library users shouldn't have to puzzle over the authors intention, but 
I wasn't referring to source when I wrote about truth.
A good library should strive for flexibility, and don't impose restrictions 
that aren't necessary — "lack of extendability" imho is no promise an author 
should want to make.
So, what if he wants to promise extendability, but just isn't sure he will be 
able to stand by this promise? Instead of forcing him into lies, we could as 
well accept the reality of "I'm not sure", which imho would be the most 
reasonably default, as it doesn't pretend an explicit choice when there is only 
uncertainty.

Jonathan Hull outlined an alternative to 0117 
(http://article.gmane.org/gmane.comp.lang.swift.evolution/23761 
) which takes 
that into account — and imho has additional benefits:
- More power (for example, UIView.drawRect and other methods that shouldn't be 
called by clients could be modeled)
- Less confusion ("What's the point of subclassable and overridable? It has no 
effect on the ability to subclass and override in my app at all!")

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-12 Thread Jordan Rose via swift-evolution

> On Jul 12, 2016, at 13:44, Tino Heth <2...@gmx.de> wrote:
> 
> Thanks for the detailed answer — I didn't expect it.
> 
> I'll re-order the original message, since you had a genuine question (to bad 
> for me if it was just a rhetorical one :) whose answer might be more 
> interesting than the pointless remarks afterwards ;-)
> 
>> If you were writing a library, what would make you decide between 
>> “experimental” and not?
> 
> I guess I would mark everything immature/experimental/whatever on release (as 
> long as it's not to hard to do so…), and then decide step by step wether a 
> method should be public, overridable, private — or removed completely ;-)
> Of course, there wouldn't be an universal scale, but most likely each 
> developer/team would keep a reliable standard (some developers are very 
> careful, some are bolder…)
> If we are honest, a "sealed" that is only applied because it is the default 
> is actually "experimental" — and in the age of open source, I don't think 
> this should be equivalent to "you can't use this" (some conservative 
> developers consider Swift itself to be immature ;-)
> The whole concept is just a spontaneous idea, and maybe I'd come to the 
> conclusion I actually don't like it; but as we can mark stuff as deprecated 
> to notify users that they should stop using a certain method, it might as 
> well be useful to annotate something as unstable to prevent certain 
> developers start using a method (yet).

No, it was a genuine question. I don’t think I agree with your answer, but I’m 
glad to hear it.


> 
> Now for the remarks — they are pointless indeed, because I'm not expecting to 
> change the mind of anyone with a well-grounded opinion
>> The binary compatibility concerns are less important, but the ability of a 
>> library author to reason about behavior is still critical. Here’s a scenario 
>> I really don’t want to see happen:
>> 
>> 1. Client X adds a dependency on library A, via the package manager. They 
>> override a public method in library A to get the behavior they want.
>> 2. Library A ships an update which fixes many bugs and security issues, and 
>> happens to eliminate the internal calls to the public method A was using. 
>> That is, overriding Athat method no longer has any effect within library A; 
>> only clients see the difference.
>> 3. The developer for client X goes to their manager and asks for time to fix 
>> the issue. The manager tells them not to update right now, but maybe after 
>> this next release.
>> 4. Client X never gets a new version of Library A ever again.
> 
> Imho this is remarkable in two aspects:
> It is the first real example I'm aware of where I see a true problem, and it 
> "overthrows" (there might be a less dramatic word I'm not aware of) the 
> position that "sealed" primarily solves a problem for library-authors.
> 
> I agree that this problem is much less likely with sealed as default, but 
> there's another one in this scenario:
> Client X depends on the later-removed feature in Library A — but as this 
> feature isn't accessible for him, he won't ever start using Library A at all…
> None the less, I have to admit that I actually prefer the problem in the 
> sealed-scenario, as it doesn't directly effect developer T, but rather 
> pointy-haired boss Y, who just lost a potential customer ;-)
> 
> I can't resist to add another culinary comparison to Jonathan Hull's 
> excellent knife-analogy:
> As the owner of a restaurant, would you fill your menu with food that's easy 
> to cook to please your chef, or would you rather include food that tastes 
> fantastic to please your customers?
> 
>> I guess another way of saying this is that library authors avoid these 
>> miscommunications by "under-promising”, and if that “under-promising” is 
>> something that’s actually in the language instead of maybe/maybe-not being 
>> documented, then both sides are much more likely to be on the same page.
> Damn, maybe I should have put this in front… why make false promises at all, 
> when you just can tell the truth?


Publishing a library is a promise of something. It ought to only be promises 
the library author wants to make. If “the truth” is “the implementation in the 
current version of the library”, that’s definitely not what a library author 
should promise. That’s true for plenty of things, not just whether or not 
overriding is expected.

(A client might prefer that the current implementation is what’s promised, but 
in practice that’s almost never what either side actually wants.)

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-12 Thread Tino Heth via swift-evolution
Thanks for the detailed answer — I didn't expect it.

I'll re-order the original message, since you had a genuine question (to bad 
for me if it was just a rhetorical one :) whose answer might be more 
interesting than the pointless remarks afterwards ;-)

> If you were writing a library, what would make you decide between 
> “experimental” and not?

I guess I would mark everything immature/experimental/whatever on release (as 
long as it's not to hard to do so…), and then decide step by step wether a 
method should be public, overridable, private — or removed completely ;-)
Of course, there wouldn't be an universal scale, but most likely each 
developer/team would keep a reliable standard (some developers are very 
careful, some are bolder…)
If we are honest, a "sealed" that is only applied because it is the default is 
actually "experimental" — and in the age of open source, I don't think this 
should be equivalent to "you can't use this" (some conservative developers 
consider Swift itself to be immature ;-)
The whole concept is just a spontaneous idea, and maybe I'd come to the 
conclusion I actually don't like it; but as we can mark stuff as deprecated to 
notify users that they should stop using a certain method, it might as well be 
useful to annotate something as unstable to prevent certain developers start 
using a method (yet).

Now for the remarks — they are pointless indeed, because I'm not expecting to 
change the mind of anyone with a well-grounded opinion
> The binary compatibility concerns are less important, but the ability of a 
> library author to reason about behavior is still critical. Here’s a scenario 
> I really don’t want to see happen:
> 
> 1. Client X adds a dependency on library A, via the package manager. They 
> override a public method in library A to get the behavior they want.
> 2. Library A ships an update which fixes many bugs and security issues, and 
> happens to eliminate the internal calls to the public method A was using. 
> That is, overriding Athat method no longer has any effect within library A; 
> only clients see the difference.
> 3. The developer for client X goes to their manager and asks for time to fix 
> the issue. The manager tells them not to update right now, but maybe after 
> this next release.
> 4. Client X never gets a new version of Library A ever again.

Imho this is remarkable in two aspects:
It is the first real example I'm aware of where I see a true problem, and it 
"overthrows" (there might be a less dramatic word I'm not aware of) the 
position that "sealed" primarily solves a problem for library-authors.

I agree that this problem is much less likely with sealed as default, but 
there's another one in this scenario:
Client X depends on the later-removed feature in Library A — but as this 
feature isn't accessible for him, he won't ever start using Library A at all…
None the less, I have to admit that I actually prefer the problem in the 
sealed-scenario, as it doesn't directly effect developer T, but rather 
pointy-haired boss Y, who just lost a potential customer ;-)

I can't resist to add another culinary comparison to Jonathan Hull's excellent 
knife-analogy:
As the owner of a restaurant, would you fill your menu with food that's easy to 
cook to please your chef, or would you rather include food that tastes 
fantastic to please your customers?

> I guess another way of saying this is that library authors avoid these 
> miscommunications by "under-promising”, and if that “under-promising” is 
> something that’s actually in the language instead of maybe/maybe-not being 
> documented, then both sides are much more likely to be on the same page.
Damn, maybe I should have put this in front… why make false promises at all, 
when you just can tell the truth?

Best regards,
Tino
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-11 Thread Jordan Rose via swift-evolution

> On Jul 11, 2016, at 00:50, Tino Heth via swift-evolution 
>  wrote:
> 
> 
>> In the implementation of the subclass, there has to be a call to one of the 
>> superclass's initializers. If all of the superclass’s initializers are 
>> non-public, then there’s no way to write your own initializer. (This is 
>> actually true in Swift today.)
> I want to point out that this strange behavior can actually be useful:
> As of now, you cannot create a public subclass with internal ancestors — it's 
> all or nothing.
> When you keep the initializer of the base class internal, you practically 
> seal this class, but it's still possible for framework clients to access the 
> public subclasses supplied for them.

Yes. My point was that we already have something equivalent to what’s being 
proposed, but it’s ad hoc, and interacts poorly with some other features of the 
language.

Jordan

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-11 Thread Andre Elder via swift-evolution
2016/07/12 6:08、Jordan Rose via swift-evolution  
のメッセージ:

> 
>> On Jul 11, 2016, at 04:34, Tino Heth <2...@gmx.de> wrote:
>> 
>> I haven't read the whole Library Evolution document, but one important part 
>> is written right at the top:
>> 
>>> This model is largely not of interest to libraries that are bundled with 
>>> their clients (distribution via source, static library, or 
>>> embedded/sandboxed dynamic library, as used by the Swift Package Manager)
>> 
>> 
>> So there are compelling arguments to "seal" the Apple-libraries, and it's 
>> reasonable to enforce sealing on them.
>> But if sealed is the right default for those libraries, it is not 
>> automatically the right default for all other libraries out there, because 
>> those are developed in a completely different manner.
>> So, instead making sealed the default for Swift, I believe it is much more 
>> sound to just make it the default for the standard frameworks:
>> This doesn't break compatibility, it's imho more convenient for the 
>> majority, and I guess there is enough manpower to manage the annotations for 
>> Cocoa and other frameworks (which is tedious labor for single developers, 
>> but no issue for a large company). 
> 
> The binary compatibility concerns are less important, but the ability of a 
> library author to reason about behavior is still critical. Here’s a scenario 
> I really don’t want to see happen:
> 
> 1. Client X adds a dependency on library A, via the package manager. They 
> override a public method in library A to get the behavior they want.
> 2. Library A ships an update which fixes many bugs and security issues, and 
> happens to eliminate the internal calls to the public method A was using. 
> That is, overriding Athat method no longer has any effect within library A; 
> only clients see the difference.
> 3. The developer for client X goes to their manager and asks for time to fix 
> the issue. The manager tells them not to update right now, but maybe after 
> this next release.
> 4. Client X never gets a new version of Library A ever again.
> 
> This hypothetical scenario happened because the client and the library had 
> differing notions about what you could do with this particular public method. 
> From the library point of view, this shouldn’t be a source-breaking change 
> because they never expected it to do anything; from the client point of view, 
> the program does a perfectly normal thing of overriding a public API and the 
> library has capriciously broken it.
This is a very compelling argument and totally logical.

I will change my vote to +0.5 in this case... still not sure about lack of 
workaround for the off-case but I am in complete agreement with the reasoning 
of this proposal, thanks for explaining it further... 

I guess maybe the thing that bothers some people is that it's forced instead of 
being a warning/annotation that could be ignored if necessary... of course that 
definition of "necessary" would be another sticking point >_<.

> I guess another way of saying this is that library authors avoid these 
> miscommunications by "under-promising”, and if that “under-promising” is 
> something that’s actually in the language instead of maybe/maybe-not being 
> documented, then both sides are much more likely to be on the same page.
Yes, this is very good and important point.

It's very appreciated that so many people have taken the time to thoughtfully 
reply to the questions and talking points, especially Jordan and Mathew! I have 
learned a lot here...

Andre

>> 
>>> Am 11.07.2016 um 05:38 schrieb Jordan Rose via swift-evolution 
>>> :
>>> 
>>> While an overridable method may have particular preconditions and 
>>> postconditions, it’s possible that the overrider will get that wrong, which 
>>> means the library author can no longer reason about the behavior of their 
>>> program.
>> Once again a situation where we have to differentiate wether we encourage 
>> open source or not:
>> In OS, users of a library become the allies of its author ― they can put 
>> stress on his model, they can find its flaws and they can show him how to 
>> improve.
>> The ability to take a piece of code and start playing with it is a fantastic 
>> trait, and this is actively discouraged by imposing limits not because they 
>> make sense, but only because the original author didn't take the time to 
>> reason about the status.
> 
> This is completely true, but I don’t see it as having much to do with 
> subclassing. If a library is open source, most of your “playing with it” will 
> be modifying the original code, not using a subclass. This is especially true 
> given how many Swift libraries are made up of just structs, enums, and 
> protocols. Additionally, “build for testing” will also allow subclassing 
> sealed classes (though not final classes, since the ‘final’ is part of the 
> semantics rather than just controlling access).
> 
> 
>> For software 

Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-11 Thread Jordan Rose via swift-evolution

> On Jul 11, 2016, at 04:34, Tino Heth <2...@gmx.de> wrote:
> 
> I haven't read the whole Library Evolution document, but one important part 
> is written right at the top:
> 
>> This model is largely not of interest to libraries that are bundled with 
>> their clients (distribution via source, static library, or 
>> embedded/sandboxed dynamic library, as used by the Swift Package Manager 
>> )
> 
> 
> So there are compelling arguments to "seal" the Apple-libraries, and it's 
> reasonable to enforce sealing on them.
> But if sealed is the right default for those libraries, it is not 
> automatically the right default for all other libraries out there, because 
> those are developed in a completely different manner.
> So, instead making sealed the default for Swift, I believe it is much more 
> sound to just make it the default for the standard frameworks:
> This doesn't break compatibility, it's imho more convenient for the majority, 
> and I guess there is enough manpower to manage the annotations for Cocoa and 
> other frameworks (which is tedious labor for single developers, but no issue 
> for a large company). 

The binary compatibility concerns are less important, but the ability of a 
library author to reason about behavior is still critical. Here’s a scenario I 
really don’t want to see happen:

1. Client X adds a dependency on library A, via the package manager. They 
override a public method in library A to get the behavior they want.
2. Library A ships an update which fixes many bugs and security issues, and 
happens to eliminate the internal calls to the public method A was using. That 
is, overriding Athat method no longer has any effect within library A; only 
clients see the difference.
3. The developer for client X goes to their manager and asks for time to fix 
the issue. The manager tells them not to update right now, but maybe after this 
next release.
4. Client X never gets a new version of Library A ever again.

This hypothetical scenario happened because the client and the library had 
differing notions about what you could do with this particular public method. 
From the library point of view, this shouldn’t be a source-breaking change 
because they never expected it to do anything; from the client point of view, 
the program does a perfectly normal thing of overriding a public API and the 
library has capriciously broken it.

I guess another way of saying this is that library authors avoid these 
miscommunications by "under-promising”, and if that “under-promising” is 
something that’s actually in the language instead of maybe/maybe-not being 
documented, then both sides are much more likely to be on the same page.


> 
>> Am 11.07.2016 um 05:38 schrieb Jordan Rose via swift-evolution 
>> >:
>> 
>> While an overridable method may have particular preconditions and 
>> postconditions, it’s possible that the overrider will get that wrong, which 
>> means the library author can no longer reason about the behavior of their 
>> program.
> Once again a situation where we have to differentiate wether we encourage 
> open source or not:
> In OS, users of a library become the allies of its author — they can put 
> stress on his model, they can find its flaws and they can show him how to 
> improve.
> The ability to take a piece of code and start playing with it is a fantastic 
> trait, and this is actively discouraged by imposing limits not because they 
> make sense, but only because the original author didn't take the time to 
> reason about the status.

This is completely true, but I don’t see it as having much to do with 
subclassing. If a library is open source, most of your “playing with it” will 
be modifying the original code, not using a subclass. This is especially true 
given how many Swift libraries are made up of just structs, enums, and 
protocols. Additionally, “build for testing” will also allow subclassing sealed 
classes (though not final classes, since the ‘final’ is part of the semantics 
rather than just controlling access).


> For software that grows "organically", documentation is more useful than 
> simple rules...
> I like the concept of version blocks, and it could work in the other 
> direction as well: We could have a "experimental"-modifier that would give 
> the library author a way to offer hints for its clients, but leaves the final 
> decision up to them. This would be much more granular than a plain "final" 
> which not only protects those who want to stay on the safe side, but also 
> repels the bold developers who'd willingly help improving the code in 
> question.

If you were writing a library, what would make you decide between 
“experimental” and not?

Jordan

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-11 Thread Jordan Rose via swift-evolution

> On Jul 11, 2016, at 08:13, Leonardo Pessoa  wrote:
> 
> Jean, given this proposal it will be possible if the developer of the
> library intends so. You'll have to have unsealed classes to be able to
> subclass them and unsealed methods so you can override. It is possible
> to just allow subclassing without allowing overriding, just like
> final.
> 
> As for conflicts I don't think so. If you declare a new method with
> the same name as an existing one without overriding, it will become a
> new method and the base class won't even know that new method exists.
> C# allows this but uses the keyword new (instead of override) to
> clarify a new method is being introduced instead of the existing one
> but as far as I see there is no such need in Swift. I'm also not sure
> we can override a method inside an extension but if so, this provides
> a new point of extension inside a class that is not subclassable.

This is something you’d need if the client were itself a library that couldn’t 
break backwards-compatibility by renaming its conflicting method. We could 
either have a “new” or “nonoverriding” annotation or a way to rename methods 
while preserving their binary interface, but 

You cannot safely override a method inside an extension unless you also control 
the original method. See my analysis in this draft of a future proposal 
.

Jordan

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-11 Thread Jean-Daniel Dupas via swift-evolution

> Le 11 juil. 2016 à 17:43, Jordan Rose  a écrit :
> 
> 
>> On Jul 11, 2016, at 07:21, Jean-Daniel Dupas  wrote:
>> 
>> Just a though, but why sealed classes have to be completely unsubclassable ?
>> 
>> Wouldn't it be possible to allow the user to subclass sealed class, but deny 
>> overriding of any public member.
>> 
>> I see a use case where a user want to extends an existing model by adding 
>> new properties and new methods to an object but can’t use composition 
>> because doing that will prevent to pass that object to the framework that 
>> expect the base object.
>> 
>> That would let user override existing class to extends them, but should not 
>> cause any side effect in the way the class should behave, and so would not 
>> affects preconditions and postconditions, and should not prevent 
>> optimization in whole module compilation, as the methods of the base class 
>> are considered final outside of the module.
>> 
>> Of course, it will introduce some fragility in the library, as adding new 
>> methods may conflict with user subclass methods, but no more than what would 
>> append if the user write extension to add new methods to the model.
> 
> DaveA and I actually talked about this, and IIRC we decided it was completely 
> safe semantically, and only left a few optimization opportunities on the 
> table (things like knowing what a deinitializer might or might not do). 
> However, we felt it was a more complicated model that still ended up with the 
> “de facto sealed” case of all initializers being non-public, and so it wasn’t 
> worth stopping at that point in the design space.
> 
> (It was a while ago, so I might have forgotten something else relevant.)
> 
> Jordan
> 

OK,

Thanks for the explanation and the long argumentation about why sealed by 
default make sens. You made me change my stance about the proposal. I just hope 
the seal keyword will be properly explained and will not make subclassing a 
second class citizen by discouraging developer to support it.

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-11 Thread L. Mihalkovic via swift-evolution
Regards
(From mobile)

> On Jul 11, 2016, at 9:43 PM, Tony Allevato via swift-evolution 
>  wrote:
> 
>> On Tue, Jul 5, 2016 at 4:11 PM Chris Lattner  wrote:
>> Hello Swift community,
>> 
>> The review of "SE-0117: Default classes to be non-subclassable publicly" 
>> begins now and runs through July 11. The proposal is available here:
>> 
>> 
>> https://github.com/apple/swift-evolution/blob/master/proposals/0117-non-public-subclassable-by-default.md
>> 
>> Reviews are an important part of the Swift evolution process. All reviews 
>> should be sent to the swift-evolution mailing list at
>> 
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
>> or, if you would like to keep your feedback private, directly to the review 
>> manager.
>> 
>> What goes into a review?
>> 
>> The goal of the review process is to improve the proposal under review 
>> through constructive criticism and contribute to the direction of Swift. 
>> When writing your review, here are some questions you might want to answer 
>> in your review:
>> 
>> * What is your evaluation of the proposal?
> 
> +1. As a big proponent of API reviews for code that's going to end up being 
> used by others, I think sealed-by-default forces authors to think about how 
> their code might end up being used by others more so than more-permissive 
> alternatives

Believing that joe lambda devs might think about their code more because the 
compiler is going to prevent certain obscure behavior from happening seems IMHO 
like a blattant negation of what history tells us about human nature. Given 2 
choices, most of us will choose the one involving the least amount of thinking 
or work; and given 2 choices with different amount of responsibilities, most of 
use will choose the least amount of perceived individual responsibility. 
Psychology 101, demonstrated in many experimentations.

Doing it because the core team wants to do it has the merrit of recognizing 
that in the end, they hold the keyboard and should be free to write whatever 
they fancy, regardless of where the choir sings. Simple and clear.
Design by consensus is the worst form of design, and the Linux kernel would 
never have made it to where it is today if Linus had not ignored what he had to 
when he had to. Happens what must happen.. and there should be no need for the 
half baked logic that has sometimes been invoked.

> . Seeing a keyword that marks a class as unsealed is a good opportunity to 
> start a conversation in a code review.

I have honestly never seen ios devs doing that, including in large corps. Most 
devs I met were lone guys or small shops working on several things in parallel, 
with no code review and much less discussions about software design. 

> Given that Swift tries to encourage the use of value types over reference 
> types in many places, which can't be subclassed anyway, I don't think this 
> change should be a significant burden. I'm in the process of implementing a 
> fairly large library that's about 95% value types and 5% reference types. The 
> reference types are more of an implementation detail than a hierarchy of 
> types, so I would have them be final anyway. This is completely anecdotal, of 
> course, but it's a testament IMO to how differently Swift has me thinking 
> about the way I structure my APIs, and subclassing has been mostly replaced 
> by protocol extensions and composition.
> 
> I'm not compelled by the arguments that we need subclassing to fix bad APIs, 
> because that's absolutely not what subclassing is intended for. It's a hack, 
> and it's not a cure-all—it relies on being able to override the correct 
> methods and inject custom behavior in the first place. The argument shouldn't 
> be "we need open subclassing or we can't fix broken APIs"; that's a false 
> choice. It should be "we need *something* to fix broken APIs", and that 
> "something" should be proposed and the need for it should be argued in its 
> own right. The ability to fix a sealed broken API does have value, but it is 
> inherently unsafe because you might be making assumptions about 
> pre/post-conditions that the original class author didn't think about, and 
> those assumptions could become invalid in the future (or might rely on 
> internal implementation details that you cannot predict). Rather than abusing 
> a construct that is not suited for that purpose, those arguing for the need 
> for that functionality should propose something more appropriate. This would 
> be a win-win; we'd have a clean way of expressing API boundaries, and an 
> unsafe-but-acknowledged-as-such way of hooking into APIs if a trap door is 
> needed. (Of course, with Swift at such a young age, it's hard to know what 
> the needs for that are until we have some more mature libraries to present as 
> use cases.)
> 
>  
>> * Is the problem being addressed significant enough to warrant a 
>> change to Swift?
> 

Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-11 Thread Tony Allevato via swift-evolution
On Tue, Jul 5, 2016 at 4:11 PM Chris Lattner  wrote:

> Hello Swift community,
>
> The review of "SE-0117: Default classes to be non-subclassable publicly"
> begins now and runs through July 11. The proposal is available here:
>
>
> https://github.com/apple/swift-evolution/blob/master/proposals/0117-non-public-subclassable-by-default.md
>
> Reviews are an important part of the Swift evolution process. All reviews
> should be sent to the swift-evolution mailing list at
>
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> or, if you would like to keep your feedback private, directly to the
> review manager.
>
> What goes into a review?
>
> The goal of the review process is to improve the proposal under review
> through constructive criticism and contribute to the direction of Swift.
> When writing your review, here are some questions you might want to answer
> in your review:
>
> * What is your evaluation of the proposal?
>

+1. As a big proponent of API reviews for code that's going to end up being
used by others, I think sealed-by-default forces authors to think about how
their code might end up being used by others more so than more-permissive
alternatives. Seeing a keyword that marks a class as unsealed is a good
opportunity to start a conversation in a code review.

Given that Swift tries to encourage the use of value types over reference
types in many places, which can't be subclassed anyway, I don't think this
change should be a significant burden. I'm in the process of implementing a
fairly large library that's about 95% value types and 5% reference types.
The reference types are more of an implementation detail than a hierarchy
of types, so I would have them be final anyway. This is completely
anecdotal, of course, but it's a testament IMO to how differently Swift has
me thinking about the way I structure my APIs, and subclassing has been
mostly replaced by protocol extensions and composition.

I'm not compelled by the arguments that we need subclassing to fix bad
APIs, because that's absolutely not what subclassing is intended for. It's
a hack, and it's not a cure-all—it relies on being able to override the
correct methods and inject custom behavior in the first place. The argument
shouldn't be "we need open subclassing or we can't fix broken APIs"; that's
a false choice. It should be "we need *something* to fix broken APIs", and
that "something" should be proposed and the need for it should be argued in
its own right. The ability to fix a sealed broken API does have value, but
it is inherently unsafe because you might be making assumptions about
pre/post-conditions that the original class author didn't think about, and
those assumptions could become invalid in the future (or might rely on
internal implementation details that you cannot predict). Rather than
abusing a construct that is not suited for that purpose, those arguing for
the need for that functionality should propose something more appropriate.
This would be a win-win; we'd have a clean way of expressing API
boundaries, and an unsafe-but-acknowledged-as-such way of hooking into APIs
if a trap door is needed. (Of course, with Swift at such a young age, it's
hard to know what the needs for that are until we have some more mature
libraries to present as use cases.)



> * Is the problem being addressed significant enough to warrant a
> change to Swift?
>

Yes.



> * Does this proposal fit well with the feel and direction of Swift?
>

Yes. The behavior that classes are unsealed within the same module but
sealed by default outside the module aligns nicely with the way internal
visibility already works in the language. Newcomers and app developers
don't have to think about it, but those who want to release code for others
to use must; I think that's the right level of responsibility.



> * If you have used other languages or libraries with a similar
> feature, how do you feel that this proposal compares to those?

* How much effort did you put into your review? A glance, a quick
> reading, or an in-depth study?
>

Read the proposal and followed the heated discussion in the review thread.



>
> More information about the Swift evolution process is available at
>
> https://github.com/apple/swift-evolution/blob/master/process.md
>
> Thank you,
>
> -Chris Lattner
> Review Manager
>
> ___
> swift-evolution-announce mailing list
> swift-evolution-annou...@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution-announce
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-11 Thread Matthew Johnson via swift-evolution

> On Jul 11, 2016, at 1:49 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> On Mon, Jul 11, 2016 at 11:10 AM, Jordan Rose  > wrote:
>> P.S. There’s also an argument to be made for public-but-not-conformable 
>> protocols, i.e. protocols that can be used in generics and as values outside 
>> of a module, but cannot be conformed to. This is important for many of the 
>> same reasons as it is for classes, and we’ve gotten a few requests for it. 
>> (While you can get a similar effect using an enum, that’s a little less 
>> natural for code reuse via protocol extensions.)
>> 
>> Would public-but-not-conformable protocols by default be the next step, 
>> then, in Swift's evolution?
> 
> I personally think it’s a reasonable place to go next, which is why I brought 
> it up. However, I don’t think it’s critical enough to get into Swift 3 when 
> we’re already so busy, and when there are multiple non-source-breaking ways 
> to get a similar effect later: adding a “sealed” annotation (so, giving up on 
> “by default” for protocols) and allowing requirements to have more narrow 
> access than the protocol (thus making it impossible to conform).
> 
> FWIW, if we give up on "by default" for classes, "sealed" could also be a 
> post-Swift 3 matter here as well. IMO, if the core team finds the reasoning 
> here persuasive enough to have sealed-by-default for classes, I'd hope for 
> the same treatment for protocols on that time frame, because as you say much 
> of the rationale behind the change is analogous for both protocols and 
> classes.

On the topic of protocols, there are really two avenues for “sealing”’ them.  
One is conformances and the other is refinements.  There are more nuances to 
consider in a design for sealing protocols.

If we’re going to continue discussing sealing protocols we should probably 
start a new thread.  However, I think we should wait unless someone from the 
core team decides it is worth discussing during the Swift 3 timeframe.

> 
> ___
> 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] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-11 Thread Xiaodi Wu via swift-evolution
On Mon, Jul 11, 2016 at 11:10 AM, Jordan Rose  wrote:

> P.S. There’s also an argument to be made for public-but-not-conformable
>> protocols, i.e. protocols that can be used in generics and as values
>> outside of a module, but cannot be conformed to. This is important for many
>> of the same reasons as it is for classes, and we’ve gotten a few requests
>> for it. (While you can get a similar effect using an enum, that’s a little
>> less natural for code reuse via protocol extensions.)
>>
>
> Would public-but-not-conformable protocols by default be the next step,
> then, in Swift's evolution?
>
>
> I personally think it’s a reasonable place to go next, which is why I
> brought it up. However, I don’t think it’s critical enough to get into
> Swift 3 when we’re already so busy, and when there are multiple
> non-source-breaking ways to get a similar effect later: adding a “sealed”
> annotation (so, giving up on “by default” for protocols) and allowing
> requirements to have more narrow access than the protocol (thus making it
> impossible to conform).
>

FWIW, if we give up on "by default" for classes, "sealed" could also be a
post-Swift 3 matter here as well. IMO, if the core team finds the reasoning
here persuasive enough to have sealed-by-default for classes, I'd hope for
the same treatment for protocols on that time frame, because as you say
much of the rationale behind the change is analogous for both protocols and
classes.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-11 Thread Jordan Rose via swift-evolution
> P.S. There’s also an argument to be made for public-but-not-conformable 
> protocols, i.e. protocols that can be used in generics and as values outside 
> of a module, but cannot be conformed to. This is important for many of the 
> same reasons as it is for classes, and we’ve gotten a few requests for it. 
> (While you can get a similar effect using an enum, that’s a little less 
> natural for code reuse via protocol extensions.)
> 
> Would public-but-not-conformable protocols by default be the next step, then, 
> in Swift's evolution?

I personally think it’s a reasonable place to go next, which is why I brought 
it up. However, I don’t think it’s critical enough to get into Swift 3 when 
we’re already so busy, and when there are multiple non-source-breaking ways to 
get a similar effect later: adding a “sealed” annotation (so, giving up on “by 
default” for protocols) and allowing requirements to have more narrow access 
than the protocol (thus making it impossible to conform).

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-11 Thread John McCall via swift-evolution
> On Jul 8, 2016, at 8:41 PM, Jordan Rose  wrote:
>> On Jul 6, 2016, at 09:16, John McCall via swift-evolution 
>> > wrote:
>> 
>>> On Jul 5, 2016, at 10:56 PM, Chris Lattner >> > wrote:
 On Jul 5, 2016, at 6:53 PM, John McCall via swift-evolution 
 > wrote:
 
> 
> I think Kevin Lundberg is right to worry about testability, but I don't 
> think that has to prevent this change. Instead, we should permit 
> `@testable` imports to subclass/override things that are not publicly 
> subclassable/overridable, and thus a module built with "Enable 
> Testability" on can't actually assume there are no subclasses/overrides 
> of `internal` classes/members even if it doesn't see any. This will block 
> optimizations in debug builds, but not in release builds. The proposal 
> should be edited to explain this `@testable` behavior.
 
 IIUC the basic design of @testable is to treat the tests for the testable 
 thing as existing within its module, so I think this just falls out.  I 
 agree that it should be spelled out in the proposal, though.
>>> 
>>> That makes sense to me.  Please explicitly add that to the proposal, thank 
>>> you!
>> 
>> Done.
> 
> This really isn’t the model for @testable, as evidenced by the fact that 
> top-level names in the testing module still shadow names from the imported 
> module, and that you can refer to the name fully-qualified. Instead, the 
> model is that @testable makes ‘internal' things ‘public'. I think this would 
> make them ‘subclassable’/‘overridable’/‘open’ instead where relevant.

Right, sorry, I mis-spoke.  The intent of @testable is to allow tests to have 
special privileges as if they were part of the same module, but of course it 
doesn't actually make them part of the same module, and there any number of 
lookup / redeclaration differences.

Still, we're agreed on how that principle applies here:  tests should be able 
to subclass / override things arbitrarily from the things they @testably import.

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-11 Thread Jordan Rose via swift-evolution

> On Jul 11, 2016, at 07:21, Jean-Daniel Dupas  wrote:
> 
> Just a though, but why sealed classes have to be completely unsubclassable ?
> 
> Wouldn't it be possible to allow the user to subclass sealed class, but deny 
> overriding of any public member.
> 
> I see a use case where a user want to extends an existing model by adding new 
> properties and new methods to an object but can’t use composition because 
> doing that will prevent to pass that object to the framework that expect the 
> base object.
> 
> That would let user override existing class to extends them, but should not 
> cause any side effect in the way the class should behave, and so would not 
> affects preconditions and postconditions, and should not prevent optimization 
> in whole module compilation, as the methods of the base class are considered 
> final outside of the module.
> 
> Of course, it will introduce some fragility in the library, as adding new 
> methods may conflict with user subclass methods, but no more than what would 
> append if the user write extension to add new methods to the model.

DaveA and I actually talked about this, and IIRC we decided it was completely 
safe semantically, and only left a few optimization opportunities on the table 
(things like knowing what a deinitializer might or might not do). However, we 
felt it was a more complicated model that still ended up with the “de facto 
sealed” case of all initializers being non-public, and so it wasn’t worth 
stopping at that point in the design space.

(It was a while ago, so I might have forgotten something else relevant.)

Jordan

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-11 Thread Leonardo Pessoa via swift-evolution
Jean, given this proposal it will be possible if the developer of the
library intends so. You'll have to have unsealed classes to be able to
subclass them and unsealed methods so you can override. It is possible
to just allow subclassing without allowing overriding, just like
final.

As for conflicts I don't think so. If you declare a new method with
the same name as an existing one without overriding, it will become a
new method and the base class won't even know that new method exists.
C# allows this but uses the keyword new (instead of override) to
clarify a new method is being introduced instead of the existing one
but as far as I see there is no such need in Swift. I'm also not sure
we can override a method inside an extension but if so, this provides
a new point of extension inside a class that is not subclassable.

L


On 11 July 2016 at 11:21, Jean-Daniel Dupas via swift-evolution
 wrote:
> Just a though, but why sealed classes have to be completely unsubclassable ?
>
> Wouldn't it be possible to allow the user to subclass sealed class, but deny
> overriding of any public member.
>
> I see a use case where a user want to extends an existing model by adding
> new properties and new methods to an object but can’t use composition
> because doing that will prevent to pass that object to the framework that
> expect the base object.
>
> That would let user override existing class to extends them, but should not
> cause any side effect in the way the class should behave, and so would not
> affects preconditions and postconditions, and should not prevent
> optimization in whole module compilation, as the methods of the base class
> are considered final outside of the module.
>
> Of course, it will introduce some fragility in the library, as adding new
> methods may conflict with user subclass methods, but no more than what would
> append if the user write extension to add new methods to the model.
>
> Le 11 juil. 2016 à 05:38, Jordan Rose via swift-evolution
>  a écrit :
>
> [Proposal:
> https://github.com/apple/swift-evolution/blob/master/proposals/0117-non-public-subclassable-by-default.md
> ]
>
> (This is my second response to this proposal. The previous message shared a
> use case where public-but-non-subclassable made things work out much better
> with required initializers. This one has a bit more ideology in it.)
>
> As many people have said already, this proposal is quite beneficial to
> library designers attempting to reason about their code, not just now but in
> the future as well. The model laid out in the Library Evolution document
> (often referred to as “resilience”) supports Swift libraries that want to
> preserve a stable binary and source interface.
>
> In the Swift 2 model (and what’s currently described in that document), a
> public class must be final or non-final at the time it is published. It’s
> clearly not safe to add ‘final' in a later version of the library, because a
> client might already have a subclass; it’s also not safe to remove ‘final’
> because existing clients may have been compiled assuming there are no
> subclasses.
>
> (Of course, we can remove this optimization, and make ‘final’ a semantic
> contract only. I’m deliberately avoiding most discussion of performance, but
> in this parenthetical I’ll note that Swift makes it possible to write code
> that is slower than Objective-C. This is considered acceptable because the
> compiler can often optimize it for a particular call site. For those who
> want more information about the current implementation of some of Swift’s
> features, I suggest watching the “Understanding Swift Performance” talk from
> this year’s WWDC.)
>
> With this proposal, a public class can be non-publicly-subclassable or
> publicly-subclassable. Once a class is publicly-subclassable (“open”), you
> can’t go back, of course. But a class that’s not initially open could become
> open in a future release of the library. All existing clients would already
> be equipped to deal with this, because there might be subclasses inside the
> library. On the other hand, the class can also be marked ‘final’, if the
> library author later realizes there will never be any subclasses and that
> both client authors and the compiler should know this.
>
> One point that’s not covered in this proposal is whether making a class
> ‘open’ applies retroactively, i.e. if MagicLib 1.2 is the first version that
> makes the Magician class ‘open’, can clients deploy back to MagicLib 1.0 and
> expect their subclasses to work? My inclination is to say no; if it’s
> possible for a non-open method to be overridden in the future, a library
> author has to write their library as if it will be overridden now, and
> there’s no point in making it non-open in the first place. That would make
> ‘open’ a “versioned attribute” in the terminology of Library Evolution,
> whatever the syntax ends up being.
>
> ---
>
> Okay, so why is this 

Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-11 Thread Jean-Daniel Dupas via swift-evolution
Just a though, but why sealed classes have to be completely unsubclassable ?

Wouldn't it be possible to allow the user to subclass sealed class, but deny 
overriding of any public member.

I see a use case where a user want to extends an existing model by adding new 
properties and new methods to an object but can’t use composition because doing 
that will prevent to pass that object to the framework that expect the base 
object.

That would let user override existing class to extends them, but should not 
cause any side effect in the way the class should behave, and so would not 
affects preconditions and postconditions, and should not prevent optimization 
in whole module compilation, as the methods of the base class are considered 
final outside of the module.

Of course, it will introduce some fragility in the library, as adding new 
methods may conflict with user subclass methods, but no more than what would 
append if the user write extension to add new methods to the model.

> Le 11 juil. 2016 à 05:38, Jordan Rose via swift-evolution 
>  a écrit :
> 
> [Proposal: 
> https://github.com/apple/swift-evolution/blob/master/proposals/0117-non-public-subclassable-by-default.md
>  
> 
>  ]
> 
> (This is my second response to this proposal. The previous message shared a 
> use case where public-but-non-subclassable made things work out much better 
> with required initializers. This one has a bit more ideology in it.)
> 
> As many people have said already, this proposal is quite beneficial to 
> library designers attempting to reason about their code, not just now but in 
> the future as well. The model laid out in the Library Evolution document 
>  (often referred to as 
> “resilience”) supports Swift libraries that want to preserve a stable binary 
> and source interface.
> 
> In the Swift 2 model (and what’s currently described in that document), a 
> public class must be final or non-final at the time it is published. It’s 
> clearly not safe to add ‘final' in a later version of the library, because a 
> client might already have a subclass; it’s also not safe to remove ‘final’ 
> because existing clients may have been compiled assuming there are no 
> subclasses.
> 
> (Of course, we can remove this optimization, and make ‘final’ a semantic 
> contract only. I’m deliberately avoiding most discussion of performance, but 
> in this parenthetical I’ll note that Swift makes it possible to write code 
> that is slower than Objective-C. This is considered acceptable because the 
> compiler can often optimize it for a particular call site. For those who want 
> more information about the current implementation of some of Swift’s 
> features, I suggest watching the “Understanding Swift Performance 
> ” talk from this 
> year’s WWDC.)
> 
> With this proposal, a public class can be non-publicly-subclassable or 
> publicly-subclassable. Once a class is publicly-subclassable (“open”), you 
> can’t go back, of course. But a class that’s not initially open could become 
> open in a future release of the library. All existing clients would already 
> be equipped to deal with this, because there might be subclasses inside the 
> library. On the other hand, the class can also be marked ‘final’, if the 
> library author later realizes there will never be any subclasses and that 
> both client authors and the compiler should know this.
> 
> One point that’s not covered in this proposal is whether making a class 
> ‘open’ applies retroactively, i.e. if MagicLib 1.2 is the first version that 
> makes the Magician class ‘open’, can clients deploy back to MagicLib 1.0 and 
> expect their subclasses to work? My inclination is to say no; if it’s 
> possible for a non-open method to be overridden in the future, a library 
> author has to write their library as if it will be overridden now, and 
> there’s no point in making it non-open in the first place. That would make 
> ‘open’ a “versioned attribute 
> ”
>  in the terminology of Library Evolution, whatever the syntax ends up being.
> 
> ---
> 
> Okay, so why is this important?
> 
> It all comes down to reasoning about your program’s behavior. When you use a 
> class, you’re relying on the documented behavior of that class. More 
> concretely, the methods on the class have preconditions 
> (“performSegue(withIdentifier:sender:) should not be called on a view 
> controller that didn’t come from a storyboard”) and postconditions (“after 
> calling loadViewIfNeeded(), the view controller’s view will be loaded”). When 
> you call a method, you’re responsible for satisfying its preconditions so it 
> can deliver on the postconditions.
> 
> I used UIViewController 

Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-11 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jul 10, 2016, at 10:38 PM, Jordan Rose via swift-evolution 
>  wrote:
> 
> [Proposal: 
> https://github.com/apple/swift-evolution/blob/master/proposals/0117-non-public-subclassable-by-default.md
>  ]
> 
> (This is my second response to this proposal. The previous message shared a 
> use case where public-but-non-subclassable made things work out much better 
> with required initializers. This one has a bit more ideology in it.)
> 
> As many people have said already, this proposal is quite beneficial to 
> library designers attempting to reason about their code, not just now but in 
> the future as well. The model laid out in the Library Evolution document 
> (often referred to as “resilience”) supports Swift libraries that want to 
> preserve a stable binary and source interface.
> 
> In the Swift 2 model (and what’s currently described in that document), a 
> public class must be final or non-final at the time it is published. It’s 
> clearly not safe to add ‘final' in a later version of the library, because a 
> client might already have a subclass; it’s also not safe to remove ‘final’ 
> because existing clients may have been compiled assuming there are no 
> subclasses.
> 
> (Of course, we can remove this optimization, and make ‘final’ a semantic 
> contract only. I’m deliberately avoiding most discussion of performance, but 
> in this parenthetical I’ll note that Swift makes it possible to write code 
> that is slower than Objective-C. This is considered acceptable because the 
> compiler can often optimize it for a particular call site. For those who want 
> more information about the current implementation of some of Swift’s 
> features, I suggest watching the “Understanding Swift Performance” talk from 
> this year’s WWDC.)
> 
> With this proposal, a public class can be non-publicly-subclassable or 
> publicly-subclassable. Once a class is publicly-subclassable (“open”), you 
> can’t go back, of course. But a class that’s not initially open could become 
> open in a future release of the library. All existing clients would already 
> be equipped to deal with this, because there might be subclasses inside the 
> library. On the other hand, the class can also be marked ‘final’, if the 
> library author later realizes there will never be any subclasses and that 
> both client authors and the compiler should know this.
> 
> One point that’s not covered in this proposal is whether making a class 
> ‘open’ applies retroactively, i.e. if MagicLib 1.2 is the first version that 
> makes the Magician class ‘open’, can clients deploy back to MagicLib 1.0 and 
> expect their subclasses to work? My inclination is to say no; if it’s 
> possible for a non-open method to be overridden in the future, a library 
> author has to write their library as if it will be overridden now, and 
> there’s no point in making it non-open in the first place. That would make 
> ‘open’ a “versioned attribute” in the terminology of Library Evolution, 
> whatever the syntax ends up being.
> 
> ---
> 
> Okay, so why is this important?
> 
> It all comes down to reasoning about your program’s behavior. When you use a 
> class, you’re relying on the documented behavior of that class. More 
> concretely, the methods on the class have preconditions 
> (“performSegue(withIdentifier:sender:) should not be called on a view 
> controller that didn’t come from a storyboard”) and postconditions (“after 
> calling loadViewIfNeeded(), the view controller’s view will be loaded”). When 
> you call a method, you’re responsible for satisfying its preconditions so it 
> can deliver on the postconditions.
> 
> I used UIViewController as an example, but it applies just as much to your 
> own methods. When you call a method in your own module—maybe written by you, 
> maybe by a coworker, maybe by an open source contributor—you’re expecting 
> some particular behavior and output given the inputs and the current state of 
> the program. That is, you just need to satisfy its preconditions so it can 
> deliver on the postconditions. If it’s a method in your module, though, you 
> might not have taken the trouble to formalize the preconditions and 
> postconditions, since you can just go look at the implementation. Even if 
> your expectations are violated, you’ll probably notice, because the conflict 
> of understanding is within your own module.
> 
> Public overriding changes all this. While an overridable method may have 
> particular preconditions and postconditions, it’s possible that the overrider 
> will get that wrong, which means the library author can no longer reason 
> about the behavior of their program. If they do a poor job documenting the 
> preconditions and postconditions, the client and the library will almost 
> certainly disagree about the expected behavior of a particular method, and 
> the program won’t work correctly.
> 
> "Doesn’t a library author have to figure out the 

Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-11 Thread Tino Heth via swift-evolution
I haven't read the whole Library Evolution document, but one important part is 
written right at the top:

> This model is largely not of interest to libraries that are bundled with 
> their clients (distribution via source, static library, or embedded/sandboxed 
> dynamic library, as used by the Swift Package Manager 
> )


So there are compelling arguments to "seal" the Apple-libraries, and it's 
reasonable to enforce sealing on them.
But if sealed is the right default for those libraries, it is not automatically 
the right default for all other libraries out there, because those are 
developed in a completely different manner.
So, instead making sealed the default for Swift, I believe it is much more 
sound to just make it the default for the standard frameworks:
This doesn't break compatibility, it's imho more convenient for the majority, 
and I guess there is enough manpower to manage the annotations for Cocoa and 
other frameworks (which is tedious labor for single developers, but no issue 
for a large company). 

> Am 11.07.2016 um 05:38 schrieb Jordan Rose via swift-evolution 
> :
> 
> While an overridable method may have particular preconditions and 
> postconditions, it’s possible that the overrider will get that wrong, which 
> means the library author can no longer reason about the behavior of their 
> program.
Once again a situation where we have to differentiate wether we encourage open 
source or not:
In OS, users of a library become the allies of its author — they can put stress 
on his model, they can find its flaws and they can show him how to improve.
The ability to take a piece of code and start playing with it is a fantastic 
trait, and this is actively discouraged by imposing limits not because they 
make sense, but only because the original author didn't take the time to reason 
about the status.

For software that grows "organically", documentation is more useful than simple 
rules...
I like the concept of version blocks, and it could work in the other direction 
as well: We could have a "experimental"-modifier that would give the library 
author a way to offer hints for its clients, but leaves the final decision up 
to them. This would be much more granular than a plain "final" which not only 
protects those who want to stay on the safe side, but also repels the bold 
developers who'd willingly help improving the code in question.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-11 Thread Tino Heth via swift-evolution

> In the implementation of the subclass, there has to be a call to one of the 
> superclass's initializers. If all of the superclass’s initializers are 
> non-public, then there’s no way to write your own initializer. (This is 
> actually true in Swift today.)
I want to point out that this strange behavior can actually be useful:
As of now, you cannot create a public subclass with internal ancestors — it's 
all or nothing.
When you keep the initializer of the base class internal, you practically seal 
this class, but it's still possible for framework clients to access the public 
subclasses supplied for them.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-10 Thread Xiaodi Wu via swift-evolution
On Sun, Jul 10, 2016 at 10:38 PM, Jordan Rose via swift-evolution <
swift-evolution@swift.org> wrote:

> [Proposal:
> https://github.com/apple/swift-evolution/blob/master/proposals/0117-non-public-subclassable-by-default.md
> ]
>
> (This is my second response to this proposal. The previous message shared
> a use case where public-but-non-subclassable made things work out much
> better with required initializers. This one has a bit more ideology in it.)
>
> As many people have said already, this proposal is quite beneficial to
> library designers attempting to reason about their code, not just now but
> in the future as well. The model laid out in the Library Evolution
> document  (often
> referred to as “resilience”) supports Swift libraries that want to preserve
> a stable binary and source interface.
>
> In the Swift 2 model (and what’s currently described in that document), a
> public class must be final or non-final at the time it is published. It’s
> clearly not safe to *add* ‘final' in a later version of the library,
> because a client might already have a subclass; it’s also not safe to
> *remove* ‘final’ because existing clients may have been compiled assuming
> there are no subclasses.
>
> (Of course, we can remove this optimization, and make ‘final’ a semantic
> contract only. I’m deliberately avoiding most discussion of performance,
> but in this parenthetical I’ll note that Swift makes it possible to write
> code that is *slower* than Objective-C. This is considered acceptable
> because the compiler can often optimize it for a particular call site. For
> those who want more information about the current implementation of some of
> Swift’s features, I suggest watching the “Understanding Swift Performance
> ” talk from this
> year’s WWDC.)
>
> With this proposal, a public class can be non-publicly-subclassable or
> publicly-subclassable. Once a class is publicly-subclassable (“open”), you
> can’t go back, of course. But a class that’s not initially open could
> *become* open in a future release of the library. All existing clients
> would already be equipped to deal with this, because there might be
> subclasses *inside* the library. On the other hand, the class can *also* be
> marked ‘final’, if the library author later realizes there will never be
> any subclasses and that both client authors and the compiler should know
> this.
>
> One point that’s not covered in this proposal is whether making a class
> ‘open’ applies retroactively, i.e. if MagicLib 1.2 is the first version
> that makes the Magician class ‘open’, can clients deploy back to MagicLib
> 1.0 and expect their subclasses to work? My inclination is to say no; if
> it’s possible for a non-open method to be overridden in the future, a
> library author has to write their library as if it will be overridden now,
> and there’s no point in making it non-open in the first place. That would
> make ‘open’ a “versioned attribute
> ”
> in the terminology of Library Evolution, whatever the syntax ends up being.
>
> ---
>
> Okay, so why is this important?
>
> It all comes down to reasoning about your program’s behavior. When you use
> a class, you’re relying on the documented behavior of that class. More
> concretely, the methods on the class have preconditions
> (“performSegue(withIdentifier:sender:) should not be called on a view
> controller that didn’t come from a storyboard”) and postconditions (“after
> calling loadViewIfNeeded(), the view controller’s view will be loaded”).
> When you call a method, you’re responsible for satisfying its preconditions
> so it can deliver on the postconditions.
>
> I used UIViewController as an example, but it applies just as much to your
> own methods. When you call a method in your own module—maybe written by
> you, maybe by a coworker, maybe by an open source contributor—you’re
> expecting some particular behavior and output given the inputs and the
> current state of the program. That is, you just need to satisfy its
> preconditions so it can deliver on the postconditions. If it’s a method in
> your module, though, you might not have taken the trouble to formalize the
> preconditions and postconditions, since you can just go look at the
> implementation. Even if your expectations are violated, you’ll probably
> notice, because the conflict of understanding is within your own module.
>
> Public overriding changes all this. While an overridable method may have
> particular preconditions and postconditions, it’s possible that the
> overrider will get that wrong, which means the library author can no longer
> reason about the behavior of their program. If they do a poor job
> documenting the preconditions and postconditions, the client and the
> library will almost certainly disagree about the expected behavior of a
> 

Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-10 Thread Jordan Rose via swift-evolution
[Proposal: 
https://github.com/apple/swift-evolution/blob/master/proposals/0117-non-public-subclassable-by-default.md
 ]

(This is my second response to this proposal. The previous message shared a use 
case where public-but-non-subclassable made things work out much better with 
required initializers. This one has a bit more ideology in it.)

As many people have said already, this proposal is quite beneficial to library 
designers attempting to reason about their code, not just now but in the future 
as well. The model laid out in the Library Evolution document 
 (often referred to as 
“resilience”) supports Swift libraries that want to preserve a stable binary 
and source interface.

In the Swift 2 model (and what’s currently described in that document), a 
public class must be final or non-final at the time it is published. It’s 
clearly not safe to add ‘final' in a later version of the library, because a 
client might already have a subclass; it’s also not safe to remove ‘final’ 
because existing clients may have been compiled assuming there are no 
subclasses.

(Of course, we can remove this optimization, and make ‘final’ a semantic 
contract only. I’m deliberately avoiding most discussion of performance, but in 
this parenthetical I’ll note that Swift makes it possible to write code that is 
slower than Objective-C. This is considered acceptable because the compiler can 
often optimize it for a particular call site. For those who want more 
information about the current implementation of some of Swift’s features, I 
suggest watching the “Understanding Swift Performance 
” talk from this year’s 
WWDC.)

With this proposal, a public class can be non-publicly-subclassable or 
publicly-subclassable. Once a class is publicly-subclassable (“open”), you 
can’t go back, of course. But a class that’s not initially open could become 
open in a future release of the library. All existing clients would already be 
equipped to deal with this, because there might be subclasses inside the 
library. On the other hand, the class can also be marked ‘final’, if the 
library author later realizes there will never be any subclasses and that both 
client authors and the compiler should know this.

One point that’s not covered in this proposal is whether making a class ‘open’ 
applies retroactively, i.e. if MagicLib 1.2 is the first version that makes the 
Magician class ‘open’, can clients deploy back to MagicLib 1.0 and expect their 
subclasses to work? My inclination is to say no; if it’s possible for a 
non-open method to be overridden in the future, a library author has to write 
their library as if it will be overridden now, and there’s no point in making 
it non-open in the first place. That would make ‘open’ a “versioned attribute 
”
 in the terminology of Library Evolution, whatever the syntax ends up being.

---

Okay, so why is this important?

It all comes down to reasoning about your program’s behavior. When you use a 
class, you’re relying on the documented behavior of that class. More 
concretely, the methods on the class have preconditions 
(“performSegue(withIdentifier:sender:) should not be called on a view 
controller that didn’t come from a storyboard”) and postconditions (“after 
calling loadViewIfNeeded(), the view controller’s view will be loaded”). When 
you call a method, you’re responsible for satisfying its preconditions so it 
can deliver on the postconditions.

I used UIViewController as an example, but it applies just as much to your own 
methods. When you call a method in your own module—maybe written by you, maybe 
by a coworker, maybe by an open source contributor—you’re expecting some 
particular behavior and output given the inputs and the current state of the 
program. That is, you just need to satisfy its preconditions so it can deliver 
on the postconditions. If it’s a method in your module, though, you might not 
have taken the trouble to formalize the preconditions and postconditions, since 
you can just go look at the implementation. Even if your expectations are 
violated, you’ll probably notice, because the conflict of understanding is 
within your own module.

Public overriding changes all this. While an overridable method may have 
particular preconditions and postconditions, it’s possible that the overrider 
will get that wrong, which means the library author can no longer reason about 
the behavior of their program. If they do a poor job documenting the 
preconditions and postconditions, the client and the library will almost 
certainly disagree about the expected behavior of a particular method, and the 
program won’t work correctly.

"Doesn’t a library author have to figure out the preconditions and 
postconditions for a method anyway when making it public?" Well, not to the 
same 

Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-10 Thread Daniel Steinberg via swift-evolution
To highlight your comment below - I would favor “sealed” being available, I’m 
not sure I would favor it being the default.

Would it help to perhaps split this into two proposals. First, decide on the 
issue of sealable being available first and syntax for it. If this passes then 
a second proposal that examines whether it should be the default?

Best,

Daniel

> On Jul 10, 2016, at 8:49 PM, Jordan Rose via swift-evolution 
>  wrote:
> 
> 
>> On Jul 9, 2016, at 01:44, Goffredo Marocchi > > wrote:
>> 
>> 
>> Sent from my iPhone
>> 
>>> On 9 Jul 2016, at 05:39, Jordan Rose via swift-evolution 
>>> > wrote:
>>> 
>>> Of course, Swift doesn’t allow this. If someone outside of the module 
>>> subclasses ModelBase, there’s no way for them to provide the 
>>> dynamically-dispatched 'init(context:)’, because they don’t have access to 
>>> the internal ModelContext.
>> 
>> Shouldn't Swift allow this? Wouldn't it be better if we found a different 
>> way to handle this than a brute force "you shall only subclass if I think 
>> you should"? Is that really an impossible cause that is worth us going 
>> completely the opposite direction of most programming languages?
> 
> There is no way to implement the required initializer from outside the 
> module, because it uses an internal type, so what we’re looking for is that 
> any subclasses from outside the module will never have the required 
> initializer invoked on them. I suppose it would still be safe to allow a 
> subclass from outside the module that did not provide any of its own 
> initializers, but that seems like an even more complicated rule.
> 
> (It’s not sufficient to say that the dynamic initializers would just trap at 
> run-time, because it’s possible that the base class has no public 
> initializers.)
> 
>> 
>> Can you tell me why the onus should not be on you, on library authors, to 
>> use final or an equivalent keyword to indicate no subclassing is allowed and 
>> thus make this intentional?
>> 
>> I am really not sold on why classes should not be subclassable by default. 
>> Not all classes suffer of the problem you mention and for those cases you 
>> should be able to express your intention explicitly. I am quite against this 
>> being a compiler default.
> 
> I admit that this use case says nothing about whether “sealed” should be the 
> default or just available.
> 
>> I think that security by ignorance, which is what automagically enforced 
>> rules tend to produce over time, does have some side effects.
> 
> This isn’t really a security issue; it’s a compiler-aided correctness issue. 
> I’ll go more into that in my other email.
> 
> Jordan
> 
> ___
> 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] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-10 Thread Jordan Rose via swift-evolution

> On Jul 9, 2016, at 16:37, Károly Lőrentey via swift-evolution 
>  wrote:
> 
> On 2016-07-09 04:39:01 +, Jordan Rose via swift-evolution said:
> 
>> I wanted to share a concrete use case that Daniel Dunbar relayed to me. He 
>> was working on a closed class hierarchy like the ones discussed here, where 
>> all of the subclasses are within a single module, but they are all public. 
>> The class also has a required initializer for dynamic construction, so that 
>> they could write something like this:
>> internal struct ModelContext { /*…*/ }
>> public class ModelBase {
>>   internal required init(context: ModelContext) { /*…*/ }
>>   // …
>> }
>> public class SimpleModel: ModelBase {
>>   internal required init(context: ModelContext) { /*…*/ }
>> }
>> public class MoreComplicatedModel: ModelBase { /*…*/ }
>> // (within some other type)
>> public func instantiateModelObject(_ type: Model) -> Model 
>> {
>>   return type.init(context: self.context)
>> }
>> That is, a public entry point calls a required initializer with an internal 
>> argument type. This is the only way to instantiate Model objects, and the 
>> internal context type doesn’t leak out into the public API.
>> Of course, Swift doesn’t allow this. If someone outside of the module 
>> subclasses ModelBase, there’s no way for them to provide the 
>> dynamically-dispatched 'init(context:)’, because they don’t have access to 
>> the internal ModelContext. The author of the library has to make the 
>> required initializers public, and either set the ModelContext separately or 
>> make it public as well. Even though no one outside the module should be 
>> using these APIs.
> 
> Can you remind us why does Swift need required initializers to have the same 
> access as the containing class?
> 
> Having only package-internal constructors in the public base class is the 
> usual pattern for exporting a sealed class hierarchy in some other languages, 
> like Java.

Sure. A required initializer is one that will be invoked on an unknown subclass 
of the type, as in the instantiateModelObject method above. That means that it 
must be present on all subclasses, because it’s generally impossible to prove 
that a particular subclass will not be passed to instantiateModelObject.

Swift currently doesn’t allow this at all, but we could imagine making it a 
run-time error instead of a compile-time error, i.e. if instantiateModelObject 
is called on a class that doesn’t provide its own implementation of 
init(context:), the program would trap. That’d be giving up some 
compiler-provided safety for run-time flexibility, which can certainly be 
desirable.

However, this is just the tip of the iceberg. In the implementation of the 
subclass, there has to be a call to one of the superclass's initializers. If 
all of the superclass’s initializers are non-public, then there’s no way to 
write your own initializer. (This is actually true in Swift today.) This isn’t 
quite the same as sealed-by-default because the subclass could just inherit the 
superclass’s initializers, but it’s very close: the only way to instantiate 
such a class would be through a required initializer, which you couldn’t 
customize.

In that sense, Swift already has something very similar to sealed-by-default, 
which just doesn’t work very well in the particular use case where you also 
need to use dynamic initialization.

Jordan

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-10 Thread Jordan Rose via swift-evolution

> On Jul 9, 2016, at 01:44, Goffredo Marocchi  wrote:
> 
> 
> Sent from my iPhone
> 
>> On 9 Jul 2016, at 05:39, Jordan Rose via swift-evolution 
>>  wrote:
>> 
>> Of course, Swift doesn’t allow this. If someone outside of the module 
>> subclasses ModelBase, there’s no way for them to provide the 
>> dynamically-dispatched 'init(context:)’, because they don’t have access to 
>> the internal ModelContext.
> 
> Shouldn't Swift allow this? Wouldn't it be better if we found a different way 
> to handle this than a brute force "you shall only subclass if I think you 
> should"? Is that really an impossible cause that is worth us going completely 
> the opposite direction of most programming languages?

There is no way to implement the required initializer from outside the module, 
because it uses an internal type, so what we’re looking for is that any 
subclasses from outside the module will never have the required initializer 
invoked on them. I suppose it would still be safe to allow a subclass from 
outside the module that did not provide any of its own initializers, but that 
seems like an even more complicated rule.

(It’s not sufficient to say that the dynamic initializers would just trap at 
run-time, because it’s possible that the base class has no public initializers.)

> 
> Can you tell me why the onus should not be on you, on library authors, to use 
> final or an equivalent keyword to indicate no subclassing is allowed and thus 
> make this intentional?
> 
> I am really not sold on why classes should not be subclassable by default. 
> Not all classes suffer of the problem you mention and for those cases you 
> should be able to express your intention explicitly. I am quite against this 
> being a compiler default.

I admit that this use case says nothing about whether “sealed” should be the 
default or just available.

> I think that security by ignorance, which is what automagically enforced 
> rules tend to produce over time, does have some side effects.

This isn’t really a security issue; it’s a compiler-aided correctness issue. 
I’ll go more into that in my other email.

Jordan

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-10 Thread Jordan Rose via swift-evolution

> On Jul 8, 2016, at 23:47, L. Mihalkovic  wrote:
> 
> 
> 
> Regards
> (From mobile)
> 
> On Jul 9, 2016, at 6:39 AM, Jordan Rose via swift-evolution 
> > wrote:
> 
>> [Proposal: 
>> https://github.com/apple/swift-evolution/blob/master/proposals/0117-non-public-subclassable-by-default.md
>>  
>> 
>>  ]
>> 
>> John has done a tremendous job supporting this proposal; the position he’s 
>> articulated very closely matches mine. Thank you to both John and Javier. 
>> 
>> I wanted to share a concrete use case that Daniel Dunbar relayed to me. He 
>> was working on a closed class hierarchy like the ones discussed here, where 
>> all of the subclasses are within a single module, but they are all public. 
>> The class also has a required initializer for dynamic construction, so that 
>> they could write something like this:
>> 
>> internal struct ModelContext { /*…*/ }
>> 
>> public class ModelBase {
>>   internal required init(context: ModelContext) { /*…*/ }
>>   // …
>> }
>> public class SimpleModel: ModelBase {
>>   internal required init(context: ModelContext) { /*…*/ }
>> }
>> public class MoreComplicatedModel: ModelBase { /*…*/ }
>> 
>> // (within some other type)
>> public func instantiateModelObject(_ type: Model) -> Model 
>> {
>>   return type.init(context: self.context)
>> }
>> 
>> That is, a public entry point calls a required initializer with an internal 
>> argument type. This is the only way to instantiate Model objects, and the 
>> internal context type doesn’t leak out into the public API.
> 
> Then could it be that in the end it is the entire scaffolding that is poorly 
> structured and in need of fixing, rather than altering the language to make 
> the scaffolding work?

I’m afraid it isn’t my codebase, so I can’t speak to this directly, but I don’t 
see anything wrong with this pattern. Dynamic initialization is useful, and 
internal, component-specific context is hardly uncommon; if the library used 
either of these alone we would likely have no problem with it. Two features not 
composing well does sometimes indicate a flaw in the design.

Jordan

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-10 Thread Charlie Monroe via swift-evolution

> On Jul 10, 2016, at 1:37 AM, Károly Lőrentey via swift-evolution 
>  wrote:
> 
> On 2016-07-09 04:39:01 +, Jordan Rose via swift-evolution said:
> 
>> I wanted to share a concrete use case that Daniel Dunbar relayed to me. He 
>> was working on a closed class hierarchy like the ones discussed here, where 
>> all of the subclasses are within a single module, but they are all public. 
>> The class also has a required initializer for dynamic construction, so that 
>> they could write something like this:
>> internal struct ModelContext { /*…*/ }
>> public class ModelBase {
>>   internal required init(context: ModelContext) { /*…*/ }
>>   // …
>> }
>> public class SimpleModel: ModelBase {
>>   internal required init(context: ModelContext) { /*…*/ }
>> }
>> public class MoreComplicatedModel: ModelBase { /*…*/ }
>> // (within some other type)
>> public func instantiateModelObject(_ type: Model) -> Model 
>> {
>>   return type.init(context: self.context)
>> }
>> That is, a public entry point calls a required initializer with an internal 
>> argument type. This is the only way to instantiate Model objects, and the 
>> internal context type doesn’t leak out into the public API.
>> Of course, Swift doesn’t allow this. If someone outside of the module 
>> subclasses ModelBase, there’s no way for them to provide the 
>> dynamically-dispatched 'init(context:)’, because they don’t have access to 
>> the internal ModelContext. The author of the library has to make the 
>> required initializers public, and either set the ModelContext separately or 
>> make it public as well. Even though no one outside the module should be 
>> using these APIs.
> 
> Can you remind us why does Swift need required initializers to have the same 
> access as the containing class?

Because without required initializers you can't do something like:

let cl: MyClass.Type = ...
let instance = cl.init(value: 0)

where MyClass has a required init(value: Int).

The issue here is that in order to be able to do this, subclasses that 
implement another initializer must implement this one as well - so it must be 
visible outside of the module if it is public.

> 
> Having only package-internal constructors in the public base class is the 
> usual pattern for exporting a sealed class hierarchy in some other languages, 
> like Java.
> 
> -- 
> Károly
> @lorentey
> 
> 
> ___
> 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] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-09 Thread Károly Lőrentey via swift-evolution

On 2016-07-09 04:39:01 +, Jordan Rose via swift-evolution said:

I wanted to share a concrete use case that Daniel Dunbar relayed to me. 
He was working on a closed class hierarchy like the ones discussed 
here, where all of the subclasses are within a single module, but they 
are all public. The class also has a required initializer for dynamic 
construction, so that they could write something like this:


internal struct ModelContext { /*…*/ }

public class ModelBase {
  internal required init(context: ModelContext) { /*…*/ }
  // …
}
public class SimpleModel: ModelBase {
  internal required init(context: ModelContext) { /*…*/ }
}
public class MoreComplicatedModel: ModelBase { /*…*/ }

// (within some other type)
public func instantiateModelObject(_ type: Model) -> Model {
  return type.init(context: self.context)
}

That is, a public entry point calls a required initializer with an 
internal argument type. This is the only way to instantiate Model 
objects, and the internal context type doesn’t leak out into the public 
API.


Of course, Swift doesn’t allow this. If someone outside of the module 
subclasses ModelBase, there’s no way for them to provide the 
dynamically-dispatched 'init(context:)’, because they don’t have access 
to the internal ModelContext. The author of the library has to make the 
required initializers public, and either set the ModelContext 
separately or make it public as well. Even though no one outside the 
module should be using these APIs.


Can you remind us why does Swift need required initializers to have the 
same access as the containing class?


Having only package-internal constructors in the public base class is 
the usual pattern for exporting a sealed class hierarchy in some other 
languages, like Java.


--
Károly
@lorentey


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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-09 Thread Kevin Ballard via swift-evolution
On Tue, Jul 5, 2016, at 04:11 PM, Chris Lattner wrote:
>   * What is your evaluation of the proposal?

Mixed bag.

I'm a big fan of sealed-by-default for classes. But I want a keyword (e.g. 
`sealed`) for this so I can be explicit about it too. Just as I sometimes mark 
methods as `internal` to make it clear to the reader that I didn't simply 
forget the access modifier, I would want to mark certain classes as `sealed` to 
make it obvious that I made a deliberate choice.

On the flip side, I'm very against sealed-by-default for functions. My general 
feeling is that, if my class is subclassable, marking certain public methods as 
non-overridable is the exception rather than the norm. Anecdotally, in the 
Postmates app, most of our Swift classes are explicitly marked as `final` 
(which supports sealed-by-default for classes), but for the subclassable 
classes, I'm pretty sure that _none_ of our methods are marked `final`.

Also, I think the keyword `subclassable` is kind of cumbersome. I'm much more 
in favor of `open`, or possibly `public(open)` since this keyword only applies 
to public classes (or public methods, if I'm overriding a sealed method from my 
parent).

And finally, I think we need to make the Swift migrator automatically mark 
public non-final declarations as `open`, otherwise we have a *huge* backwards 
compatibility hazard for all third-party Swift frameworks.

>   * Is the problem being addressed significant enough to warrant a change 
> to Swift?

Yes.

>   * Does this proposal fit well with the feel and direction of Swift?

Yes. It's making things safer by default, and matches the default internal 
access level.

>   * If you have used other languages or libraries with a similar feature, 
> how do you feel that this proposal compares to those?
>   * How much effort did you put into your review? A glance, a quick 
> reading, or an in-depth study?

A quick reading of the proposal, then reading part of this massive review 
thread and skimming the rest.

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-09 Thread Goffredo Marocchi via swift-evolution

Sent from my iPhone

> On 9 Jul 2016, at 05:39, Jordan Rose via swift-evolution 
>  wrote:
> 
> Of course, Swift doesn’t allow this. If someone outside of the module 
> subclasses ModelBase, there’s no way for them to provide the 
> dynamically-dispatched 'init(context:)’, because they don’t have access to 
> the internal ModelContext.

Shouldn't Swift allow this? Wouldn't it be better if we found a different way 
to handle this than a brute force "you shall only subclass if I think you 
should"? Is that really an impossible cause that is worth us going completely 
the opposite direction of most programming languages?

Can you tell me why the onus should not be on you, on library authors, to use 
final or an equivalent keyword to indicate no subclassing is allowed and thus 
make this intentional?

I am really not sold on why classes should not be subclassable by default. Not 
all classes suffer of the problem you mention and for those cases you should be 
able to express your intention explicitly. I am quite against this being a 
compiler default.

I think that security by ignorance, which is what automagically enforced rules 
tend to produce over time, does have some side effects.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-09 Thread L. Mihalkovic via swift-evolution


Regards
(From mobile)

> On Jul 9, 2016, at 6:39 AM, Jordan Rose via swift-evolution 
>  wrote:
> 
> [Proposal: 
> https://github.com/apple/swift-evolution/blob/master/proposals/0117-non-public-subclassable-by-default.md
>  ]
> 
> John has done a tremendous job supporting this proposal; the position he’s 
> articulated very closely matches mine. Thank you to both John and Javier. 
> 
> I wanted to share a concrete use case that Daniel Dunbar relayed to me. He 
> was working on a closed class hierarchy like the ones discussed here, where 
> all of the subclasses are within a single module, but they are all public. 
> The class also has a required initializer for dynamic construction, so that 
> they could write something like this:
> 
> internal struct ModelContext { /*…*/ }
> 
> public class ModelBase {
>   internal required init(context: ModelContext) { /*…*/ }
>   // …
> }
> public class SimpleModel: ModelBase {
>   internal required init(context: ModelContext) { /*…*/ }
> }
> public class MoreComplicatedModel: ModelBase { /*…*/ }
> 
> // (within some other type)
> public func instantiateModelObject(_ type: Model) -> Model {
>   return type.init(context: self.context)
> }
> 
> That is, a public entry point calls a required initializer with an internal 
> argument type. This is the only way to instantiate Model objects, and the 
> internal context type doesn’t leak out into the public API.

Then could it be that in the end it is the entire scaffolding that is poorly 
structured and in need of fixing, rather than altering the language to make the 
scaffolding work?


> 
> Of course, Swift doesn’t allow this. If someone outside of the module 
> subclasses ModelBase, there’s no way for them to provide the 
> dynamically-dispatched 'init(context:)’, because they don’t have access to 
> the internal ModelContext. The author of the library has to make the required 
> initializers public, and either set the ModelContext separately or make it 
> public as well. Even though no one outside the module should be using these 
> APIs.
> 
> If ModelBase were public-but-not-subclassable, however, the code is perfectly 
> fine. The initializer and the helper type don’t need to be public, and 
> clients of the library see only what they need.
> 
> This is just one use case. I don’t want to say it’s a general model for 
> everyone’s code. However, it does point to a desire for 
> public-and-not-subclassable classes; any other solution would either require 
> the library author making more things public, or the compiler making it 
> possible to accidentally call an unimplemented initializer.
> 
> I’ll send a separate message with my thoughts as the primary author of the 
> Library Evolution model, to keep those discussions distinct. That one will 
> have a bit more ideology in it. :-)
> 
> Jordan
> 
> P.S. “Why not use protocols?” When a protocol has an initializer requirement, 
> it still forces all subclasses of a conforming class to provide an 
> implementation, i.e. the conforming class’s initializer still needs to be 
> declared ‘required’. That means it’s subject to the same restriction: a 
> required initializer must have as much access as the containing class.
> ___
> 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] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-09 Thread Paul Norton via swift-evolution

>   * What is your evaluation of the proposal?
-1 

Once, for an extended portion of my career, I worked in a 'developer support' 
type role for a large C++ API. I had daily contact with developers who were 
consuming that API.
Because of that experience, I am fully convinced that library authors will 
never imagine all the ways developers will use a library's API.
Of course there's more to it, but I really think the reasons why this is the 
wrong direction have been well expressed by others.

>   * Is the problem being addressed significant enough to warrant a change 
> to Swift?

No, I don't believe so. I also think it would eventually force a second change; 
some sort of override to the default, at which point we've extended the 
language further to get closer to where we started.

>   * Does this proposal fit well with the feel and direction of Swift?

I don't believe it does. 

>   * If you have used other languages or libraries with a similar feature, 
> how do you feel that this proposal compares to those?

N/A

>   * How much effort did you put into your review? A glance, a quick 
> reading, or an in-depth study?

I have read the proposal, followed this discussion here but none of the 
previous discussion 

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-08 Thread Jordan Rose via swift-evolution
[Proposal: 
https://github.com/apple/swift-evolution/blob/master/proposals/0117-non-public-subclassable-by-default.md
 ]

John has done a tremendous job supporting this proposal; the position he’s 
articulated very closely matches mine. Thank you to both John and Javier. 

I wanted to share a concrete use case that Daniel Dunbar relayed to me. He was 
working on a closed class hierarchy like the ones discussed here, where all of 
the subclasses are within a single module, but they are all public. The class 
also has a required initializer for dynamic construction, so that they could 
write something like this:

internal struct ModelContext { /*…*/ }

public class ModelBase {
  internal required init(context: ModelContext) { /*…*/ }
  // …
}
public class SimpleModel: ModelBase {
  internal required init(context: ModelContext) { /*…*/ }
}
public class MoreComplicatedModel: ModelBase { /*…*/ }

// (within some other type)
public func instantiateModelObject(_ type: Model) -> Model {
  return type.init(context: self.context)
}

That is, a public entry point calls a required initializer with an internal 
argument type. This is the only way to instantiate Model objects, and the 
internal context type doesn’t leak out into the public API.

Of course, Swift doesn’t allow this. If someone outside of the module 
subclasses ModelBase, there’s no way for them to provide the 
dynamically-dispatched 'init(context:)’, because they don’t have access to the 
internal ModelContext. The author of the library has to make the required 
initializers public, and either set the ModelContext separately or make it 
public as well. Even though no one outside the module should be using these 
APIs.

If ModelBase were public-but-not-subclassable, however, the code is perfectly 
fine. The initializer and the helper type don’t need to be public, and clients 
of the library see only what they need.

This is just one use case. I don’t want to say it’s a general model for 
everyone’s code. However, it does point to a desire for 
public-and-not-subclassable classes; any other solution would either require 
the library author making more things public, or the compiler making it 
possible to accidentally call an unimplemented initializer.

I’ll send a separate message with my thoughts as the primary author of the 
Library Evolution model, to keep those discussions distinct. That one will have 
a bit more ideology in it. :-)

Jordan

P.S. “Why not use protocols?” When a protocol has an initializer requirement, 
it still forces all subclasses of a conforming class to provide an 
implementation, i.e. the conforming class’s initializer still needs to be 
declared ‘required’. That means it’s subject to the same restriction: a 
required initializer must have as much access as the containing class.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-08 Thread Jordan Rose via swift-evolution

> On Jul 6, 2016, at 09:16, John McCall via swift-evolution 
>  wrote:
> 
>> On Jul 5, 2016, at 10:56 PM, Chris Lattner  wrote:
>>> On Jul 5, 2016, at 6:53 PM, John McCall via swift-evolution 
>>>  wrote:
>>> 
 
 I think Kevin Lundberg is right to worry about testability, but I don't 
 think that has to prevent this change. Instead, we should permit 
 `@testable` imports to subclass/override things that are not publicly 
 subclassable/overridable, and thus a module built with "Enable 
 Testability" on can't actually assume there are no subclasses/overrides of 
 `internal` classes/members even if it doesn't see any. This will block 
 optimizations in debug builds, but not in release builds. The proposal 
 should be edited to explain this `@testable` behavior.
>>> 
>>> IIUC the basic design of @testable is to treat the tests for the testable 
>>> thing as existing within its module, so I think this just falls out.  I 
>>> agree that it should be spelled out in the proposal, though.
>> 
>> That makes sense to me.  Please explicitly add that to the proposal, thank 
>> you!
> 
> Done.

This really isn’t the model for @testable, as evidenced by the fact that 
top-level names in the testing module still shadow names from the imported 
module, and that you can refer to the name fully-qualified. Instead, the model 
is that @testable makes ‘internal' things ‘public'. I think this would make 
them ‘subclassable’/‘overridable’/‘open’ instead where relevant.

Jordan

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-07 Thread Tino Heth via swift-evolution

>  In an open source world, “closed by default” makes a lot more sense.
That sounds Orwellian to me: 
War is Peace, Freedom is Slavery, Ignorance is Strength — and sealed is open?___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-06 Thread Charlie Monroe via swift-evolution

> On Jul 7, 2016, at 1:10 AM, Ricardo Parada via swift-evolution 
>  wrote:
> 
> In the motivation section performance is also mentioned as driving this 
> proposal. However I don't see any study that supports that. I would like to 
> see that. This should not be taken lightly. 

There kind of was a discussion on this.

John McCall (http://article.gmane.org/gmane.comp.lang.swift.evolution/22111 
)

> Finally, the specific form of devirtualization in question here, where a 
> method is proven to never be overridden (again, very common for accessors!), 
> can have a significant impact separate from any calls because the method 
> essentially no longer needs to be virtual.  That is, it can be removed from 
> the virtual method tables completely, and we may be able to completely avoid 
> emitting it.  That shrinks the size of global memory (and the binary), 
> decrease the amount of work that has to be done at load-time, and improves 
> locality within the virtual table.


I remember that he's mentioned some benchmark final vs. non-final where the 
difference was in some cases staggering. In general, when you enable 
whole-module optimization, the compiler can treat all classes within the module 
as final and optimize mainly accessing properties since they are then known to 
be final...



> 
> Let's imagine that performance is important for a library that is heavily 
> used and that the classes are not the type that you usually override. 
> Wouldn't we be better served  by being able to seal the class, i.e. "public 
> sealed class Foo"  and then for the methods / properties that are clear 
> extension points should be flagged overridable.  I would prefer something 
> like that. And I think it would be more intuitive. 
> 
> 
>>* Is the problem being addressed significant enough to warrant a change 
>> to Swift?
> 
> No. 
> 
>>* Does this proposal fit well with the feel and direction of Swift?
> 
> I think it is counter-intuitive. I don't think that reading "public class 
> Foo" would make anyone think that Foo is non-subclassable. 
> 
> On the other hand, reading "public class sealed Foo" would suggest to the 
> reader that the class can be overridden but only the methods that are flagged 
> as overridable. 
> 
> If we wanted to prohibit overriding then we could use "public final class 
> Foo" without any extension points. Then nobody would be able to subclass and 
> it would be an error to try to flag a method / property as overridable.  
> 
> 
>>* If you have used other languages or libraries with a similar feature, 
>> how do you feel that this proposal compares to those?
> 
> I don't recall having seen this behavior in the languages that I have worked 
> with. 
> 
>>* How much effort did you put into your review? A glance, a quick 
>> reading, or an in-depth study?
> 
> I read the whole proposal and have been thinking about the implications for a 
> few hours. 
> 
>> More information about the Swift evolution process is available at
>> 
>>https://github.com/apple/swift-evolution/blob/master/process.md 
>> 
>> 
>> Thank you,
>> 
>> -Chris Lattner
>> Review Manager
>> 
>> ___
>> swift-evolution-announce mailing list
>> swift-evolution-annou...@swift.org 
>> 
>> https://lists.swift.org/mailman/listinfo/swift-evolution-announce 
>> 
> ___
> 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] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-06 Thread Brad Hilton via swift-evolution
I completely agree with rparada and give a strong, strong, strong -1 to this 
proposal. To make classes non-subclassable by default is only going to lead to 
unanticipated pain and frustration. Also agree with other comments that 
subclassable and overridable conflate access control with class behavior. If we 
want to make it possible to define a class as non-subclassable to external 
users, I’d agree to something more consistent with existing swift access 
control like public(final) as has been proposed by other commenters. However, I 
agree that making classes final by default is a bad idea that will create a 
larger problem that it solves.

Also, just a more general complaint, I sometimes feel that the evolution list 
is being dominated by safety enthusiasts at the expense of usability advocates. 
Safety is a premier feature of Swift, but so is usability. We should be trying 
to find solutions that advance both objectives, as well as performance and 
power.

> On Jul 5, 2016, at 7:11 PM, Chris 
> Lattnerwrote:
> 
> > Hello Swift community,
> > 
> > The review of "SE-0117: Default classes to be non-subclassable publicly" 
> > begins now and runs through July 11. The proposal is available here:
> > 
> > https://github.com/apple/swift-evolution/blob/master/proposals/0117-non-public-subclassable-by-default.md
> > 
> > * What is your evaluation of the proposal?
> -1
> 
> Perhaps because this is so different from what I have seen in other languages 
> and used for so many years. I have not worked with a language that uses 
> non-subclassable/ non-overridable as the default.
> 
> I think that by default classes should be subclassable, not the other way 
> around. I am afraid that developers will not take the time to specify which 
> methods are overridable resulting in libraries that are difficult to patch, 
> extend.
> 
> In my 26+ years of object-oriented design and programming (other languages, 
> Objective-C since 1990 and Java since 2001) I have worked with object 
> oriented libraries and subclassed methods that the authors probably never 
> anticipated. I have been able to fix problems, enhance classes by creating 
> subclasses with fixes and enhanced behavior.
> 
> In java for example I have seen that sometimes I would have been able to fix 
> bugs or enhance the existing classes had the author not chosen a method to be 
> protected or private. Sometimes they had a good reason but sometimes they 
> didn't.Is have been able to survive using an awesome library that was 
> discontinued and end-of-lifed thanks to subclassing that has allowed me to 
> fix problems and enhance over the years as the Java language kept evolving.
> 
> In general I like to design classes with methods that have a very well 
> defined purpose / logic. Such methods are potentially overridable. I find 
> that making a method private or final can be selfish / restrictive at times 
> and I choose it carefully for implementation details that are better served 
> by going through the public methods.
> 
> I think that making a class not subclassable by default is restrictive / 
> limiting / selfish.
> 
> Sometimes the extension points are clear.
> I also think that every other method with a well defined purpose / logic is 
> also potentially an extension point.
> 
> In my experience we should allow the developer to override by default.That is 
> how I design my classes and every method / property.
> 
> I use private for the stuff that is obvious that should not be exposed.
> 
> In the motivation sectionperformanceis also mentioned as driving this 
> proposal. However I don't see any study that supports that. I would like to 
> see that. This should not be taken lightly.
> 
> Let's imagine that performance is important for a library that is heavily 
> used and that the classes are not the type that you usually override. 
> Wouldn't we be better servedby being able to seal the class, i.e. "public 
> sealed class Foo"and then for the methods / properties that are clear 
> extension points should be flaggedoverridable.I would prefer something like 
> that. And I think it would be more intuitive.
> 
> 
> > * Is the problem being addressed significant enough to warrant a change to 
> > Swift?
> No.
> 
> > * Does this proposal fit well with the feel and direction of Swift?
> I think it is counter-intuitive.I don't think that reading "public class Foo" 
> would make anyone think that Foo is non-subclassable.
> 
> On the other hand, reading "public class sealed Foo" would suggest to the 
> reader that the class can be overridden but only the methods that are flagged 
> asoverridable.
> 
> If we wanted to prohibit overriding then we could use "public final class 
> Foo" without any extension points. Then nobody would be able to subclass and 
> it would be an error to try to flag a method / property as overridable.
> 
> 
> > * If you have used other languages or libraries with a similar feature, how 

Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-06 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jul 6, 2016, at 6:47 PM, Scott James Remnant  wrote:
> 
> 
>>> On Jul 6, 2016, at 4:34 PM, Matthew Johnson  wrote:
>>> 
>>> To give you an example of the confusion, here is code made perfectly legal 
>>> by SE-0025:
>>> 
>>>   public final class Example {
>>> 
>>> overridable func foo() {}
>>> 
>>>   }
>> 
>> I have no idea how you think this is related to SE-0025 (scoped access 
>> control).  I also don’t understand why you think an `overridable` method in 
>> a `final` class would be legal under any proposal.  That is nonsense and 
>> clearly in error.
> 
> SE-0117, which we are reviewing here, in its introduction introduces the new 
> `subclassable` and `overridable` modifiers in a discussion about `public`, 
> and indicates that they are used instead of that keyword. This to me strongly 
> implies that these are in the same family as the access control modifiers.
> 
> SE-0025 removes the error when the access of a member within a type is less 
> restrictive, thus removes the error that would otherwise occur with the above 
> code.

SE-0025 says nothing about final though.  I really don't think we would allow 
overridable in a final class in any case.

I do think it's fair to point out that details like is are not fully specified 
in the proposal and  should be (in order to avoid another round of cleanup 
similar to what was necessary for SE-0025).

> 
> 
> Consider this another strong argument for keeping access and inheritability 
> separate, the following code would be obviously an error/warning since `open` 
> makes no sense within a `final` class:
> 
>   public final class Example {
> 
> public open func foo() {}
> 
>   }
> 
> Clarity is always a goal for Swift. This to me has more of it than replacing 
> `public`.
> 
> Scott
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-06 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jul 6, 2016, at 6:39 PM, Scott James Remnant  wrote:
> 
> 
>> On Jul 6, 2016, at 4:34 PM, Matthew Johnson  wrote:
>> 
>> Many of us believe “final” is too blunt a tool.  There are many cases where 
>> final cannot be used but you still don’t want external users subclassing or 
>> overriding.  
>> 
>> We would like a more precise tool for these circumstances and believe if it 
>> is going to exist in Swift it should be the default.  Its behavior follows 
>> the principle of requiring programmers to explicitly make decisions about 
>> what behavior is exposed outside of a module.  You may not like that 
>> principle, but it is one that has been embraced by the language.
> 
> I am all for these things, and would be in favor of a proposal that does this 
> cleanly(*)… the proposal text I reviewed does not.
> 
> * e.g. the final/sealed/open keywords you suggest, with sealed being the new 
> default, makes a huge amount of sense to me and feels clean, since it keeps 
> access and finality separate, and as you say, explicitly make decisions in a 
> manner otherwise consistent with the language.

Great!  I agree with you that the specific details of the proposal can be 
improved.  The core team is free to "accept with revision" and that's what I 
hope they do in this case.

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-06 Thread Scott James Remnant via swift-evolution

> On Jul 6, 2016, at 4:34 PM, Matthew Johnson  wrote:
>> 
>> To give you an example of the confusion, here is code made perfectly legal 
>> by SE-0025:
>> 
>>   public final class Example {
>> 
>> overridable func foo() {}
>> 
>>   }
> 
> I have no idea how you think this is related to SE-0025 (scoped access 
> control).  I also don’t understand why you think an `overridable` method in a 
> `final` class would be legal under any proposal.  That is nonsense and 
> clearly in error.
> 

SE-0117, which we are reviewing here, in its introduction introduces the new 
`subclassable` and `overridable` modifiers in a discussion about `public`, and 
indicates that they are used instead of that keyword. This to me strongly 
implies that these are in the same family as the access control modifiers.

SE-0025 removes the error when the access of a member within a type is less 
restrictive, thus removes the error that would otherwise occur with the above 
code.


Consider this another strong argument for keeping access and inheritability 
separate, the following code would be obviously an error/warning since `open` 
makes no sense within a `final` class:

  public final class Example {

public open func foo() {}

  }

Clarity is always a goal for Swift. This to me has more of it than replacing 
`public`.

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-06 Thread Scott James Remnant via swift-evolution

> On Jul 6, 2016, at 4:34 PM, Matthew Johnson  wrote:
> 
> Many of us believe “final” is too blunt a tool.  There are many cases where 
> final cannot be used but you still don’t want external users subclassing or 
> overriding.  
> 
> We would like a more precise tool for these circumstances and believe if it 
> is going to exist in Swift it should be the default.  Its behavior follows 
> the principle of requiring programmers to explicitly make decisions about 
> what behavior is exposed outside of a module.  You may not like that 
> principle, but it is one that has been embraced by the language.
> 

I am all for these things, and would be in favor of a proposal that does this 
cleanly(*)… the proposal text I reviewed does not.

* e.g. the final/sealed/open keywords you suggest, with sealed being the new 
default, makes a huge amount of sense to me and feels clean, since it keeps 
access and finality separate, and as you say, explicitly make decisions in a 
manner otherwise consistent with the language.

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-06 Thread Matthew Johnson via swift-evolution

> On Jul 6, 2016, at 5:13 PM, Scott James Remnant  wrote:
> 
> 
>> On Jul 6, 2016, at 2:47 PM, Matthew Johnson > > wrote:
>> 
>> This is not true.  Public classes will *not* be “final by default”.  It 
>> *will* be possible to subclass them within their declaring module.  If they 
>> need to be final they will still need to be marked as such.  
>> 
>> With that in mind, the your “can override” column (do you really mean “can 
>> subclass” here?) is also not correct.  The correct answer is “yes, within 
>> the module”.  The fundamental difference for this row is that there are some 
>> scopes which can *see* the type without the ability to subclass it.  There 
>> is no problem with this, it is *exactly* what we want.  
> 
> So would this be more accurate?
> 
>   access  | can access| can subclass/  | final
>   |   | override where |
>  -+---++---
>   open| all scopes| all scopes | Error
>   public  | all scopes| within module  | final
>   internal| within module | within module  | final
>   fileprivate | within file   | within file| final
>   private | within scope  | within scope   | final

If you want to view “open” as an access modifier, then yes.

> 
>> The purpose of this proposal is precisely to give library authors the 
>> ability to have more fine grained control over what capabilities their 
>> library exposes to users.
>> 
> 
> I don’t have an issue with the purpose, I have an issue with doing it by 
> conflating access control and finality, and making the language confusing as 
> a result.

It’s not conflating access control and finality.

It is also possible to view “open” and “sealed" as part of an “inheritability" 
hierarchy rather than the access control hierarchy. 

final- never subclassable / overridable
sealed (default)  - subclassable / overridable *within* the declaring module
open   - always subclassable / overridable

In some sense, “open” intersects access control and inheritability:  it only 
makes sense on a public declarations and therefore implies public (whether we 
allow public to be inferred or not).

> 
> Assuming the above table matches your expectation, compare it with the same 
> matrix for the language as it is today:
> 
>   access  | can access| can subclass/  | final
>   |   | override where |
>  -+---++---
>   public  | all scopes| all scopes | final
>   internal| within module | within module  | final
>   fileprivate | within file   | within file| final
>   private | within scope  | within scope   | final
> 
> The existing table is clean, it’s easy to understand; the two concepts are 
> entirely separate from each other. The access control keyword defines where a 
> class, method, property, or subscript can be accessed from; the `final` 
> keyword defines whether or not it can be subclassed or overridden.

Many of us believe “final” is too blunt a tool.  There are many cases where 
final cannot be used but you still don’t want external users subclassing or 
overriding.  

We would like a more precise tool for these circumstances and believe if it is 
going to exist in Swift it should be the default.  Its behavior follows the 
principle of requiring programmers to explicitly make decisions about what 
behavior is exposed outside of a module.  You may not like that principle, but 
it is one that has been embraced by the language.

> 
> 
> To give you an example of the confusion, here is code made perfectly legal by 
> SE-0025:
> 
>   public final class Example {
> 
> overridable func foo() {}
> 
>   }

I have no idea how you think this is related to SE-0025 (scoped access 
control).  I also don’t understand why you think an `overridable` method in a 
`final` class would be legal under any proposal.  That is nonsense and clearly 
in error.

-Matthew

> 
> Scott

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-06 Thread Ricardo Parada via swift-evolution

> On Jul 5, 2016, at 7:11 PM, Chris Lattner  wrote:
> 
> Hello Swift community,
> 
> The review of "SE-0117: Default classes to be non-subclassable publicly" 
> begins now and runs through July 11. The proposal is available here:
> 
>
> https://github.com/apple/swift-evolution/blob/master/proposals/0117-non-public-subclassable-by-default.md
> 
>* What is your evaluation of the proposal?

-1

Perhaps because this is so different from what I have seen in other languages 
and used for so many years. I have not worked with a language that uses 
non-subclassable/ non-overridable as the default. 

I think that by default classes should be subclassable, not the other way 
around. I am afraid that developers will not take the time to specify which 
methods are overridable resulting in libraries that are difficult to patch, 
extend. 

In my 26+ years of object-oriented design and programming (other languages, 
Objective-C since 1990 and Java since 2001) I have worked with object oriented 
libraries and subclassed methods that the authors probably never anticipated. I 
have been able to fix problems, enhance classes by creating subclasses with 
fixes and enhanced behavior. 

In java for example I have seen that sometimes I would have been able to fix 
bugs or enhance the existing classes had the author not chosen a method to be 
protected or private. Sometimes they had a good reason but sometimes they 
didn't.  Is have been able to survive using an awesome library that was 
discontinued and end-of-lifed thanks to subclassing that has allowed me to fix 
problems and enhance over the years as the Java language kept evolving. 

In general I like to design classes with methods that have a very well defined 
purpose / logic. Such methods are potentially overridable. I find that making a 
method private or final can be selfish / restrictive at times and I choose it 
carefully for implementation details that are better served by going through 
the public methods. 

I think that making a class not subclassable by default is restrictive / 
limiting / selfish. 

Sometimes the extension points are clear. 
I also think that every other method with a well defined purpose / logic is 
also potentially an extension point. 

In my experience we should allow the developer to override by default.  That is 
how I design my classes and every method / property. 

I use private for the stuff that is obvious that should not be exposed. 

In the motivation section performance is also mentioned as driving this 
proposal. However I don't see any study that supports that. I would like to see 
that. This should not be taken lightly. 

Let's imagine that performance is important for a library that is heavily used 
and that the classes are not the type that you usually override. Wouldn't we be 
better served  by being able to seal the class, i.e. "public sealed class Foo"  
and then for the methods / properties that are clear extension points should be 
flagged overridable.  I would prefer something like that. And I think it would 
be more intuitive. 


>* Is the problem being addressed significant enough to warrant a change to 
> Swift?

No. 

>* Does this proposal fit well with the feel and direction of Swift?

I think it is counter-intuitive. I don't think that reading "public class Foo" 
would make anyone think that Foo is non-subclassable. 

On the other hand, reading "public class sealed Foo" would suggest to the 
reader that the class can be overridden but only the methods that are flagged 
as overridable. 

If we wanted to prohibit overriding then we could use "public final class Foo" 
without any extension points. Then nobody would be able to subclass and it 
would be an error to try to flag a method / property as overridable.  


>* If you have used other languages or libraries with a similar feature, 
> how do you feel that this proposal compares to those?

I don't recall having seen this behavior in the languages that I have worked 
with. 

>* How much effort did you put into your review? A glance, a quick reading, 
> or an in-depth study?

I read the whole proposal and have been thinking about the implications for a 
few hours. 

> More information about the Swift evolution process is available at
> 
>https://github.com/apple/swift-evolution/blob/master/process.md
> 
> Thank you,
> 
> -Chris Lattner
> Review Manager
> 
> ___
> swift-evolution-announce mailing list
> swift-evolution-annou...@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution-announce
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-06 Thread Scott James Remnant via swift-evolution

> On Jul 6, 2016, at 2:47 PM, Matthew Johnson  wrote:
> 
> This is not true.  Public classes will *not* be “final by default”.  It 
> *will* be possible to subclass them within their declaring module.  If they 
> need to be final they will still need to be marked as such.  
> 
> With that in mind, the your “can override” column (do you really mean “can 
> subclass” here?) is also not correct.  The correct answer is “yes, within the 
> module”.  The fundamental difference for this row is that there are some 
> scopes which can *see* the type without the ability to subclass it.  There is 
> no problem with this, it is *exactly* what we want.  

So would this be more accurate?

  access  | can access| can subclass/  | final
  |   | override where |
 -+---++---
  open| all scopes| all scopes | Error
  public  | all scopes| within module  | final
  internal| within module | within module  | final
  fileprivate | within file   | within file| final
  private | within scope  | within scope   | final

> The purpose of this proposal is precisely to give library authors the ability 
> to have more fine grained control over what capabilities their library 
> exposes to users.
> 

I don’t have an issue with the purpose, I have an issue with doing it by 
conflating access control and finality, and making the language confusing as a 
result.

Assuming the above table matches your expectation, compare it with the same 
matrix for the language as it is today:

  access  | can access| can subclass/  | final
  |   | override where |
 -+---++---
  public  | all scopes| all scopes | final
  internal| within module | within module  | final
  fileprivate | within file   | within file| final
  private | within scope  | within scope   | final

The existing table is clean, it’s easy to understand; the two concepts are 
entirely separate from each other. The access control keyword defines where a 
class, method, property, or subscript can be accessed from; the `final` keyword 
defines whether or not it can be subclassed or overridden.


To give you an example of the confusion, here is code made perfectly legal by 
SE-0025:

  public final class Example {

overridable func foo() {}

  }

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-06 Thread Matthew Johnson via swift-evolution

> On Jul 6, 2016, at 4:36 PM, Scott James Remnant via swift-evolution 
>  wrote:
> 
> 
>> On Jul 6, 2016, at 2:13 PM, Leonardo Pessoa > > wrote:
>> 
>> You can also try and simplify your outlines reducing X.c and X.d to a
>> single entry as it is the same rule applied to two different elements
>> of the language. Using one single keyword (such as in 'open') would
>> make it clearer and that is why I prefer to have only one keyword.
>> 
> 
> I didn’t simply the outlines precisely because the proposal suggests two 
> keywords.
> 
> One keyword does solve this problem, but not the problem of conflation of 
> finality and access control.
> You end up with this matrix:
> 
>   access  | can override | final
>  -+--+---
>   open| yes  | Error - “class cannot be open and final”

Of course this produces a compile error.  Open means “can subclass” which 
directly contradicts final.

>   public  | no   | Error - “public class is already final by 
> default”

This is not true.  Public classes will *not* be “final by default”.  It *will* 
be possible to subclass them within their declaring module.  If they need to be 
final they will still need to be marked as such.  

With that in mind, the your “can override” column (do you really mean “can 
subclass” here?) is also not correct.  The correct answer is “yes, within the 
module”.  The fundamental difference for this row is that there are some scopes 
which can *see* the type without the ability to subclass it.  There is no 
problem with this, it is *exactly* what we want. 

The purpose of this proposal is precisely to give library authors the ability 
to have more fine grained control over what capabilities their library exposes 
to users.

>   internal| yes  | final
>   fileprivate | yes  | final
>   private | yes  | final
> 
> This is way more confusing than the current language:
> 
>   access  | can override | final
>  -+--+---
>   public  | yes  | final
>   internal| yes  | final
>   fileprivate | yes  | final
>   private | yes  | final
> 
> I strongly favor a programming language that doesn’t introduce compiler 
> errors to solve problems that could be solved by cleaner syntax.
> 
> Since it’s already necessary to place the `public` keyword in front of every 
> class, method, property, or subscript that you intend to make public, the 
> developer is already thinking about the public API. Typing `public final` 
> instead of `public` is an extra keyword, it’s not an extra cognitive burden 
> since that cognition is already taking place.

As you can see from the points above, `public final` is something very 
different than both `public` and `public subclass able` (or `open`) under the 
current proposal.  It is not a question of cleaner syntax.  It is a question of 
whether we want to give library authors more fine grained control.

-Matthew

> 
> Scott
> 
> ___
> 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] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-06 Thread Leonardo Pessoa via swift-evolution
I don't disagree with you on 'fileprivate' and 'private' being
unnecessary and we may stick to the proposal at hand and leave the
'final' issue to another proposal, should anyone else care (I myself
don't mind if it sticks around - just have to not use it).

As for the conflict, I don't see it. Can you declare a 'public private
class'? I think it is just the same with 'open' and 'final'. And there
is no need to introduce an error for being redundant with 'public
final' either.

L

On 6 July 2016 at 18:36, Scott James Remnant  wrote:
>
> On Jul 6, 2016, at 2:13 PM, Leonardo Pessoa  wrote:
>
> You can also try and simplify your outlines reducing X.c and X.d to a
> single entry as it is the same rule applied to two different elements
> of the language. Using one single keyword (such as in 'open') would
> make it clearer and that is why I prefer to have only one keyword.
>
>
> I didn’t simply the outlines precisely because the proposal suggests two
> keywords.
>
> One keyword does solve this problem, but not the problem of conflation of
> finality and access control.
> You end up with this matrix:
>
>   access  | can override | final
>  -+--+---
>   open| yes  | Error - “class cannot be open and final"
>   public  | no   | Error - “public class is already final by
> default"
>   internal| yes  | final
>   fileprivate | yes  | final
>   private | yes  | final
>
> This is way more confusing than the current language:
>
>   access  | can override | final
>  -+--+---
>   public  | yes  | final
>   internal| yes  | final
>   fileprivate | yes  | final
>   private | yes  | final
>
> I strongly favor a programming language that doesn’t introduce compiler
> errors to solve problems that could be solved by cleaner syntax.
>
> Since it’s already necessary to place the `public` keyword in front of every
> class, method, property, or subscript that you intend to make public, the
> developer is already thinking about the public API. Typing `public final`
> instead of `public` is an extra keyword, it’s not an extra cognitive burden
> since that cognition is already taking place.
>
> Scott
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-06 Thread John McCall via swift-evolution
> On Jul 6, 2016, at 1:41 PM, Goffredo Marocchi via swift-evolution 
>  wrote:
> Sent from my iPhone
> 
>> On 6 Jul 2016, at 21:22, Paul Cantrell via swift-evolution 
>>  wrote:
>> 
>> In the era of increased open sourcing, easy forking, and more 
>> community-driven development, this concern is less severe than it used to 
>> be. I rarely use any closed-sourced libraries for iOS development. If I need 
>> to tweak some library and non-subclassibility is getting in the way, then I 
>> can fork it — and perhaps even contribute my changes back to improve the 
>> upstream project. In an open source world, “closed by default” makes a lot 
>> more sense.
> 
> Maintaining a fork, realistically often without hope of upstream merging, 
> your changes is feels like a very business unfriendly idea and less scalable 
> than it sounds in many environments.
> 
> I see closed by default as part of the movement some people seem to be 
> embracing of opt-out model in which freedom and versatility is forcefully 
> restrained, making the language more complex and exotic/breaking conventions 
> for the sake of protecting people from themselves, instead of opt-in models 
> which require programmers to be diligent and know when to constrain 
> themselves while enjoying more flexible defaults.
> I am not asking for JavaScript, but I do not want this language to go the 
> complete polar opposite, more dogmatic than C++ or Java.

This proposal is specifically targeting library interfaces.  It's not a 
slippery slope towards locking things down at a sub-library level because (1) 
we've already considered and rejected the analogous sub-library-level proposal 
(as "final by default") and (2) almost all of the justifications are tied to 
the specific problems that arise with library interfaces.

In general, Swift already treats library interfaces as a special point at which 
a lot of considerations change.  The most prominent example of that is access 
control, but there are a lot of other examples that will become more apparent 
as we complete the resilience model, solidify the ABI, and start really 
supporting binary distribution of libraries.  The basic idea is that library 
designers face a set of language problems that other programmers don't, and the 
language ought to understand that and provide a different set of features and 
defaults.  This is a language design that's made possible by Swift's relatively 
strong commitment to defining and enforcing library boundaries, as opposed to 
the languages you list.  To me, this is a great way to only get dogmatism when 
it's actually useful and necessary.

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-06 Thread Scott James Remnant via swift-evolution

> On Jul 6, 2016, at 2:13 PM, Leonardo Pessoa  wrote:
> 
> You can also try and simplify your outlines reducing X.c and X.d to a
> single entry as it is the same rule applied to two different elements
> of the language. Using one single keyword (such as in 'open') would
> make it clearer and that is why I prefer to have only one keyword.
> 

I didn’t simply the outlines precisely because the proposal suggests two 
keywords.

One keyword does solve this problem, but not the problem of conflation of 
finality and access control.
You end up with this matrix:

  access  | can override | final
 -+--+---
  open| yes  | Error - “class cannot be open and final"
  public  | no   | Error - “public class is already final by 
default"
  internal| yes  | final
  fileprivate | yes  | final
  private | yes  | final

This is way more confusing than the current language:

  access  | can override | final
 -+--+---
  public  | yes  | final
  internal| yes  | final
  fileprivate | yes  | final
  private | yes  | final

I strongly favor a programming language that doesn’t introduce compiler errors 
to solve problems that could be solved by cleaner syntax.

Since it’s already necessary to place the `public` keyword in front of every 
class, method, property, or subscript that you intend to make public, the 
developer is already thinking about the public API. Typing `public final` 
instead of `public` is an extra keyword, it’s not an extra cognitive burden 
since that cognition is already taking place.

Scott

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-06 Thread Scott James Remnant via swift-evolution

> On Jul 6, 2016, at 2:13 PM, Leonardo Pessoa  wrote:
> 
> So I did get what you meant right. Now tell me: if a class or method
> is internal to your module (and you know internal means only you,
> throught your source code, inside your app or library can extend it),
> do you really need to mark anything as final for any reason? Final on
> any non-publics is a restriction you put on yourself, you will always
> have the power to lift that at any time (as long as you still own the
> code, of course) so you are always in control of your subclasses and
> overrides. All the time. It's up to you to subclass/override or not.
> This is different from what you make public: you either have no
> control or you have to fine grain control making everything final. You
> regain that control over your publics with this proposal.
> 

The same argument could be applied to why we have `fileprivate` and `private`, 
if a class or method is internal to my module, why do I need to mark anything 
as further private for any reason?

There are a whole bunch of answers; perhaps the module is maintained by a team 
of twenty people, and the class is intended to be sub-classed within the team, 
so it’s a level of “internal public.” It doesn’t even have to be a team, maybe 
I’m writing a utility class that I know I’ll use for years, and I know I’ll 
forget my rationale later down the line and make the mistake of overriding 
something I shouldn’t.

Removing `final` is a whole proposal unto itself that I would also -1, it’s not 
covered by this one, so at this point this is a rabbit hole.

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-06 Thread Paul Cantrell via swift-evolution

> On Jul 6, 2016, at 3:41 PM, Goffredo Marocchi  wrote:
> 
>> On 6 Jul 2016, at 21:22, Paul Cantrell via swift-evolution 
>>  wrote:
>> 
>> In the era of increased open sourcing, easy forking, and more 
>> community-driven development, this concern is less severe than it used to 
>> be. I rarely use any closed-sourced libraries for iOS development. If I need 
>> to tweak some library and non-subclassibility is getting in the way, then I 
>> can fork it — and perhaps even contribute my changes back to improve the 
>> upstream project. In an open source world, “closed by default” makes a lot 
>> more sense.
> 
> Maintaining a fork, realistically often without hope of upstream merging, 
> your changes is feels like a very business unfriendly idea and less scalable 
> than it sounds in many environments.

It certainly has its problems, but in practice it’s no worse than brittle 
workarounds such as unintended subclassing.

In the case of forking, upgrading a library comes with the cost of merging 
changes. In the case of brittle subclassing, upgrading a library comes with the 
cost of your patches suddenly breaking. In either case, you have a body of code 
which is tightly coupled to an external library in ways that the library's 
author isn’t monitoring for breakage.

In my experience, forking is usually the less costly route because it gives 
more control. Modern version control makes maintaining a fork over time much 
easier than it used to be — and the ever-improving social dynamics of pull 
requests make forks less likely to live on forever.

Cheers,

Paul

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-06 Thread Leonardo Pessoa via swift-evolution
So I did get what you meant right. Now tell me: if a class or method
is internal to your module (and you know internal means only you,
throught your source code, inside your app or library can extend it),
do you really need to mark anything as final for any reason? Final on
any non-publics is a restriction you put on yourself, you will always
have the power to lift that at any time (as long as you still own the
code, of course) so you are always in control of your subclasses and
overrides. All the time. It's up to you to subclass/override or not.
This is different from what you make public: you either have no
control or you have to fine grain control making everything final. You
regain that control over your publics with this proposal.

You can also try and simplify your outlines reducing X.c and X.d to a
single entry as it is the same rule applied to two different elements
of the language. Using one single keyword (such as in 'open') would
make it clearer and that is why I prefer to have only one keyword.

So, AFAICS, number 3 is how it should be with this proposal. As for
keeping the final keyword (sticking with number 2), I think it is up
to the community. I myself don't see any reason/need for it should
this proposal pass.

L

On 6 July 2016 at 17:32, Scott James Remnant  wrote:
>>
>> On Jul 6, 2016, at 1:16 PM, Leonardo Pessoa  wrote:
>>
>> Scott, I think your writing got a bit confuse but, if I got your
>> intention right, since you are the owner of the class, you may choose
>> to subclass it or not internally, no questions asked.
>
> No.
>
> This is how the language exists today:
>
> 1a. Default access control is `internal`, and may be modified by adding the 
> `public`, `fileprivate`, or `private` keyword, as appropriate.
>
> 1b. All classes may be subclassed, and all methods, properties, and 
> subscripts overridden. This can be prevented by adding the `final` keyword.
>
> The two concepts are very separate, and I think this is a good thing.
>
>
> What this proposal suggests, whether or not `final` is kept or removed, is 
> that the two concepts become conflated:
>
> 2a. Default access control is `internal`, and may be modified by adding the 
> `public`, `fileprivate`, or `private` keyword, as appropriate.
>
> 2b. Non-`public` classes may be subclassed, and non-`public` methods, 
> properties, and subscripts overridden. This can be prevented by adding the 
> `final` keyword.
>
> 2c. `public` classes may not be subclassed. To allow this replace the 
> `public` keyword with `subclassable`
>
> 2d. `public` methods, properties, and subscripts may not be overridden. To 
> allow this replace the `public` keyword with `overiddable`.
>
>
> Removing the `final` keyword means a change to 2b above. The first option is 
> simply to throw it away, in which case you end up with:
>
> 3a. Default access control is `internal`, and may be modified by adding the 
> `public`, `fileprivate`, or `private` keyword, as appropriate.
>
> 3b. Non-`public` classes may be subclassed, and non-`public` methods, 
> properties, and subscripts overridden. This can be never be prevented.
>
> 3c. `public` classes may not be subclassed. To allow this replace the 
> `public` keyword with `subclassable`
>
> 3d. `public` methods, properties, and subscripts may not be overridden. To 
> allow this replace the `public` keyword with `overiddable`.
>
>
> The second option is to throw it away, and adjust the default behavior so it 
> truly is `final` as removing the keyword would imply. Then you end up with:
>
> 4a. Default access control is `internal`, and may be modified by adding the 
> `public`, `fileprivate`, or `private` keyword, as appropriate.
>
> 4b. Non-`public` classes may not be subclassed, and non-`public` methods, 
> properties, and subscripts may not be overridden. This can never be allowed.
>
> 4c. `public` classes may not be subclassed. To allow this replace the 
> `public` keyword with `subclassable`
>
> 4d. `public` methods, properties, and subscripts may not be overridden. To 
> allow this replace the `public` keyword with `overiddable`.
>
>
> To me all of these options take a clean, easy-to-understand, language design 
> (1) and turn it into various states of mess. Removing the `final` keyword not 
> only makes it a mess, but removes functionality—the ability to have a mix of 
> final and non-final classes, methods, properties, and subscripts, accessible 
> only within your own module.
>
> Scott
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-06 Thread Goffredo Marocchi via swift-evolution


Sent from my iPhone

> On 6 Jul 2016, at 21:22, Paul Cantrell via swift-evolution 
>  wrote:
> 
> In the era of increased open sourcing, easy forking, and more 
> community-driven development, this concern is less severe than it used to be. 
> I rarely use any closed-sourced libraries for iOS development. If I need to 
> tweak some library and non-subclassibility is getting in the way, then I can 
> fork it — and perhaps even contribute my changes back to improve the upstream 
> project. In an open source world, “closed by default” makes a lot more sense.

Maintaining a fork, realistically often without hope of upstream merging, your 
changes is feels like a very business unfriendly idea and less scalable than it 
sounds in many environments.

I see closed by default as part of the movement some people seem to be 
embracing of opt-out model in which freedom and versatility is forcefully 
restrained, making the language more complex and exotic/breaking conventions 
for the sake of protecting people from themselves, instead of opt-in models 
which require programmers to be diligent and know when to constrain themselves 
while enjoying more flexible defaults.
I am not asking for JavaScript, but I do not want this language to go the 
complete polar opposite, more dogmatic than C++ or Java.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-06 Thread Scott James Remnant via swift-evolution
> 
> On Jul 6, 2016, at 1:16 PM, Leonardo Pessoa  wrote:
> 
> Scott, I think your writing got a bit confuse but, if I got your
> intention right, since you are the owner of the class, you may choose
> to subclass it or not internally, no questions asked.

No.

This is how the language exists today:

1a. Default access control is `internal`, and may be modified by adding the 
`public`, `fileprivate`, or `private` keyword, as appropriate.

1b. All classes may be subclassed, and all methods, properties, and subscripts 
overridden. This can be prevented by adding the `final` keyword.

The two concepts are very separate, and I think this is a good thing.


What this proposal suggests, whether or not `final` is kept or removed, is that 
the two concepts become conflated:

2a. Default access control is `internal`, and may be modified by adding the 
`public`, `fileprivate`, or `private` keyword, as appropriate.

2b. Non-`public` classes may be subclassed, and non-`public` methods, 
properties, and subscripts overridden. This can be prevented by adding the 
`final` keyword.

2c. `public` classes may not be subclassed. To allow this replace the `public` 
keyword with `subclassable`

2d. `public` methods, properties, and subscripts may not be overridden. To 
allow this replace the `public` keyword with `overiddable`.


Removing the `final` keyword means a change to 2b above. The first option is 
simply to throw it away, in which case you end up with:

3a. Default access control is `internal`, and may be modified by adding the 
`public`, `fileprivate`, or `private` keyword, as appropriate.

3b. Non-`public` classes may be subclassed, and non-`public` methods, 
properties, and subscripts overridden. This can be never be prevented.

3c. `public` classes may not be subclassed. To allow this replace the `public` 
keyword with `subclassable`

3d. `public` methods, properties, and subscripts may not be overridden. To 
allow this replace the `public` keyword with `overiddable`.


The second option is to throw it away, and adjust the default behavior so it 
truly is `final` as removing the keyword would imply. Then you end up with:

4a. Default access control is `internal`, and may be modified by adding the 
`public`, `fileprivate`, or `private` keyword, as appropriate.

4b. Non-`public` classes may not be subclassed, and non-`public` methods, 
properties, and subscripts may not be overridden. This can never be allowed.

4c. `public` classes may not be subclassed. To allow this replace the `public` 
keyword with `subclassable`

4d. `public` methods, properties, and subscripts may not be overridden. To 
allow this replace the `public` keyword with `overiddable`.


To me all of these options take a clean, easy-to-understand, language design 
(1) and turn it into various states of mess. Removing the `final` keyword not 
only makes it a mess, but removes functionality—the ability to have a mix of 
final and non-final classes, methods, properties, and subscripts, accessible 
only within your own module.

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-06 Thread Paul Cantrell via swift-evolution

> * What is your evaluation of the proposal?

+1, with bikeshedding.

To me, “subclassable” does not imply “public.” If I hadn’t read this proposal, 
I would be likely to declare an internal class subclassable, and then be 
shocked when it was exposed as public!

If it’s part of my public API, I want to see the word “public” on it. That 
should not be implicit under any circumstances. I strongly prefer any one of 
these to the standalone “subclassable:”

• public(subclassable)
• public(open)
• public(extensible)

The extra verbosity is tolerable because subclassability by design is (should 
be!) the exception, not the rule.

> * Does this proposal fit well with the feel and direction of Swift?

Yes, it fits two patterns of Swift’s general design:

if one choice is the default, it is the safer one; and
consequential design decisions are explicit. Implicitness is reserved for 
obvious / redundant information that becomes noise and interferes with 
readability.

To that end…

> * Is the problem being addressed significant enough to warrant a change to 
> Swift?

…open public classes run against general precedent in the language, so yes.

As programmers grow used to Swift, they will increasingly lean on the compiler 
to prompt them when there is an important type design issue to consider, or 
when they are doing something that compromises type safety. The absence of a 
compiler warning becomes important information.

This means that making open classes the default is not just aesthetically 
suboptimal; it is actively misleading.

> * If you have used other languages or libraries with a similar feature, how 
> do you feel that this proposal compares to those?

No. In all the OO languages I’ve used, classes are open by default. That raises 
a question: is this really a good idea? Aren’t we ignoring established 
precedent? What about all the unauthorized subclassing we’ve done in the past?

I’m sympathetic to those accustomed to Objective-C, Ruby, Javascript, Python, 
and other languages with more fungible type systems who argue that it’s 
unreasonable to expect us all to use classes only as library authors intend. 
Monkey patching has saved many a day, they’d say. And it’s true, it has! I rely 
on it.

My counterargument: the ecosystem is changing.

In the era of increased open sourcing, easy forking, and more community-driven 
development, this concern is less severe than it used to be. I rarely use any 
closed-sourced libraries for iOS development. If I need to tweak some library 
and non-subclassibility is getting in the way, then I can fork it — and perhaps 
even contribute my changes back to improve the upstream project. In an open 
source world, “closed by default” makes a lot more sense.

The big exception to this is Apple itself, and the direction of this proposal 
implies a large cultural shift in how Apple deals with its developer community. 
Having the Swift language so aggressively prevent the dubious, brittle, 
bad-idea-but-it-gets-the-job-done workarounds that the Obj-C runtime allowed 
means that Apple’s platforms are going to have to be more consciously 
extensible, more transparent in their design decisions, and more responsive to 
unanticipated needs. This community right here is an exemplar.

Here’s thing: this big shift goes far, far beyond this proposal. Swift already 
rules out most any form of messing with a library’s assumptions about its own 
design. With or without the proposal, Apple is already getting on board with 
the new regime of stricter typing and more hermetically sealed libraries. 
They’re already going to have to make API design decisions about how and where 
extensibility is allowed with unprecedented caution.

This proposal hardly alters that tipping balance; it just removes a design 
inconsistency.

> * How much effort did you put into your review? A glance, a quick reading, or 
> an in-depth study?

I read the proposal carefully, the discussion thread not at all.

Cheers,

Paul

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-06 Thread Leonardo Pessoa via swift-evolution
Scott, I think your writing got a bit confuse but, if I got your
intention right, since you are the owner of the class, you may choose
to subclass it or not internally, no questions asked. I need no finals
in my apps and I only subclass if I intend to. If you are in control
of your own code, why would you need to ensure there would be no
subclassing/overriding? I'm not opposed to keeping the keyword if it
is important to anyone to be sure of that for internals. As for what
is public you will gain better control of what other people do to your
classes and methods.

L

On 6 July 2016 at 16:56, Scott James Remnant  wrote:
>
>> On Jul 6, 2016, at 12:50 PM, Leonardo Pessoa  wrote:
>>
>> Scott, you really got a point here: should this proposal pass, I
>> believe the final keyword should be removed as it would be already the
>> default behaviour and thus unnecessary. I don't think this is on the
>> proposal.
>>
>
> Removing the `final` keyword would mean there would be no way to have a class 
> of `internal` (default) scope that subclasses and another class of `internal` 
> (default) scope and overrides a method of `internal` (default) scope.
>
> Scott
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-06 Thread Scott James Remnant via swift-evolution

> On Jul 6, 2016, at 12:50 PM, Leonardo Pessoa  wrote:
> 
> Scott, you really got a point here: should this proposal pass, I
> believe the final keyword should be removed as it would be already the
> default behaviour and thus unnecessary. I don't think this is on the
> proposal.
> 

Removing the `final` keyword would mean there would be no way to have a class 
of `internal` (default) scope that subclasses and another class of `internal` 
(default) scope and overrides a method of `internal` (default) scope.

Scott

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-06 Thread Leonardo Pessoa via swift-evolution
Scott, you really got a point here: should this proposal pass, I
believe the final keyword should be removed as it would be already the
default behaviour and thus unnecessary. I don't think this is on the
proposal.

L

On 6 July 2016 at 16:47, Scott James Remnant via swift-evolution
 wrote:
> -1
>
> This proposal makes Swift a more confusing language.
>
>
> Swift already has a mechanism for creating public subclassable classes and
> non-subclassable classes:
>
>   public class SubclassableParentClass { }
>
>   public final class NonSubclassableParentClass { }
>
> This mechanism also applies to methods, properties, and subscripts:
>
>   public func bar() {}
>
>   public final func foo() {}
>
> The proposal makes no effort to remove this existing syntax.
>
> The very fact that this would be legitimate syntax as a result is a bad omen
> to me:
>
>   subclassable final class ConfusedParentClass {
>
> overridable final func quuz() {}
>
>   }
>
> The proposal doesn’t even address what that would do, the obvious answer is
> “compiler error,” but a better answer would be a language design that didn’t
> allow for this kind of ambiguity.
>
>
> Conflating access control and finality is confusing. The proposal actually
> even goes as far to argue that—“conflates” is a word I took from the
> proposal—but it’s solution *is* a conflation in of its right, because the
> only way to explain the results is in terms of both:
>
> classes, methods, properties, and subscripts with access control of
> `internal`, `file private`, and `private` are overridable by code that can
> access them, to prevent this add the `final` keyword.
> classes with access control of `public` are not overridable by code that can
> access them, to allow this replace the `public` keyword with the
> `subclassable` keyword.
> methods, properties, and subscripts with access control of `public` are not
> overridable by code that can access them, to allow this replace the `public`
> keyword with the `overridable` keyword.
>
>
> Not only is this complicated, and confusing, it isn’t even consistent: to
> deny overriding or subclassing you add the same keyword; but to allow
> overriding or subclassing you replace one keyword with two different ones,
> depending on which you’re doing.
>
>
> I agree that the alternative of flipping the default, and replacing `final`
> with `nonfinal` is also undesirable. One of the nicer features of the Swift
> language design is that the language is easiest for app developers working
> within a single module, where it can be assumed that “everyone is an adult.”
> Breaking this to support the less common case of Public API Designers would
> be a step backwards; their case is important, but it shouldn’t come at a
> penalty.
>
> Scott
>
> ___
> 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] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-06 Thread Scott James Remnant via swift-evolution
-1

This proposal makes Swift a more confusing language.


Swift already has a mechanism for creating public subclassable classes and 
non-subclassable classes:

  public class SubclassableParentClass { }

  public final class NonSubclassableParentClass { }

This mechanism also applies to methods, properties, and subscripts:

  public func bar() {}

  public final func foo() {}

The proposal makes no effort to remove this existing syntax.

The very fact that this would be legitimate syntax as a result is a bad omen to 
me:

  subclassable final class ConfusedParentClass {

overridable final func quuz() {}

  }

The proposal doesn’t even address what that would do, the obvious answer is 
“compiler error,” but a better answer would be a language design that didn’t 
allow for this kind of ambiguity.


Conflating access control and finality is confusing. The proposal actually even 
goes as far to argue that—“conflates” is a word I took from the proposal—but 
it’s solution *is* a conflation in of its right, because the only way to 
explain the results is in terms of both:

classes, methods, properties, and subscripts with access control of `internal`, 
`file private`, and `private` are overridable by code that can access them, to 
prevent this add the `final` keyword.
classes with access control of `public` are not overridable by code that can 
access them, to allow this replace the `public` keyword with the `subclassable` 
keyword.
methods, properties, and subscripts with access control of `public` are not 
overridable by code that can access them, to allow this replace the `public` 
keyword with the `overridable` keyword.

Not only is this complicated, and confusing, it isn’t even consistent: to deny 
overriding or subclassing you add the same keyword; but to allow overriding or 
subclassing you replace one keyword with two different ones, depending on which 
you’re doing.


I agree that the alternative of flipping the default, and replacing `final` 
with `nonfinal` is also undesirable. One of the nicer features of the Swift 
language design is that the language is easiest for app developers working 
within a single module, where it can be assumed that “everyone is an adult.” 
Breaking this to support the less common case of Public API Designers would be 
a step backwards; their case is important, but it shouldn’t come at a penalty.

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-06 Thread John McCall via swift-evolution
> On Jul 5, 2016, at 9:11 PM, Kevin Lundberg  wrote:
> 
> I hadn't considered @testable, and it may be one way to mitigate the
> trouble this could cause in tests, so thank you both for bringing it up
> as the proposal should definitely account for it. I'm curious though how
> this would solve the case of trying to subclass a module's class in a
> test where you don't have the source? If you don't have control over the
> source, you can't rebuild it to enable testability, and it might even be
> desirable for someone to refuse to distribute a binary with testability
> enabled if doing so might reveal proprietary information or lead to a
> possible security problem with their library.

Our testing design is only intended to allow first-party tests to break the
normal access restrictions.  It seems to me that other tests should be
treating their external dependencies as black boxes and use their normal API.

John.

> 
> 
> On 7/5/2016 9:53 PM, John McCall via swift-evolution wrote:
>>> On Jul 5, 2016, at 6:45 PM, Brent Royal-Gordon via swift-evolution 
>>>  wrote:
>>> 
* What is your evaluation of the proposal?
>>> I think it's ultimately a good idea. Being noncommittal about 
>>> subclassability/overridability—and thus forbidding it in public scope, but 
>>> not making any promises about what the module does internally—is the 
>>> alternative that preserves the most freedom for the module, and therefore 
>>> the most appropriate default.
>>> 
>>> However, I don't like the `subclassable` and `overridable` keywords. They 
>>> read like opposites of `final` with no implications for access level; I 
>>> could easily imagine somebody marking an internal class `subclassable` 
>>> assuming that it merely means it can be subclassed internally, and being 
>>> very surprised (or even not noticing!) that the class has been made public. 
>>> They're also long and cumbersome; that might be seen as a positive, but I 
>>> think it will increase the inevitable backlash against this change.
>>> 
>>> I prefer the keyword `open`, which sounds like it could be a statement 
>>> about the item's accessibility—and even sounds like it ought to be "more 
>>> public than public"—and is short enough that it ought to be difficult to 
>>> grumble about the change. It also means that both classes and members use 
>>> the same keyword, and gives us a keyword that we can later use to "open" 
>>> other things in the language, such as allowing you to extend enums with new 
>>> cases.
>> Agreed; I also prefer "open" to having two different long keywords that 
>> don't (at least to my ear) imply "public".
>> 
>>> I think Kevin Lundberg is right to worry about testability, but I don't 
>>> think that has to prevent this change. Instead, we should permit 
>>> `@testable` imports to subclass/override things that are not publicly 
>>> subclassable/overridable, and thus a module built with "Enable Testability" 
>>> on can't actually assume there are no subclasses/overrides of `internal` 
>>> classes/members even if it doesn't see any. This will block optimizations 
>>> in debug builds, but not in release builds. The proposal should be edited 
>>> to explain this `@testable` behavior.
>> IIUC the basic design of @testable is to treat the tests for the testable 
>> thing as existing within its module, so I think this just falls out.  I 
>> agree that it should be spelled out in the proposal, though.
>> 
>> John.
>> ___
>> 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] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-06 Thread John McCall via swift-evolution
> On Jul 5, 2016, at 10:56 PM, Chris Lattner  wrote:
>> On Jul 5, 2016, at 6:53 PM, John McCall via swift-evolution 
>>  wrote:
>> 
>>> 
>>> I think Kevin Lundberg is right to worry about testability, but I don't 
>>> think that has to prevent this change. Instead, we should permit 
>>> `@testable` imports to subclass/override things that are not publicly 
>>> subclassable/overridable, and thus a module built with "Enable Testability" 
>>> on can't actually assume there are no subclasses/overrides of `internal` 
>>> classes/members even if it doesn't see any. This will block optimizations 
>>> in debug builds, but not in release builds. The proposal should be edited 
>>> to explain this `@testable` behavior.
>> 
>> IIUC the basic design of @testable is to treat the tests for the testable 
>> thing as existing within its module, so I think this just falls out.  I 
>> agree that it should be spelled out in the proposal, though.
> 
> That makes sense to me.  Please explicitly add that to the proposal, thank 
> you!

Done.

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-05 Thread Chris Lattner via swift-evolution

> On Jul 5, 2016, at 6:53 PM, John McCall via swift-evolution 
>  wrote:
> 
>> 
>> I think Kevin Lundberg is right to worry about testability, but I don't 
>> think that has to prevent this change. Instead, we should permit `@testable` 
>> imports to subclass/override things that are not publicly 
>> subclassable/overridable, and thus a module built with "Enable Testability" 
>> on can't actually assume there are no subclasses/overrides of `internal` 
>> classes/members even if it doesn't see any. This will block optimizations in 
>> debug builds, but not in release builds. The proposal should be edited to 
>> explain this `@testable` behavior.
> 
> IIUC the basic design of @testable is to treat the tests for the testable 
> thing as existing within its module, so I think this just falls out.  I agree 
> that it should be spelled out in the proposal, though.

That makes sense to me.  Please explicitly add that to the proposal, thank you!

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-05 Thread Kevin Lundberg via swift-evolution
I hadn't considered @testable, and it may be one way to mitigate the
trouble this could cause in tests, so thank you both for bringing it up
as the proposal should definitely account for it. I'm curious though how
this would solve the case of trying to subclass a module's class in a
test where you don't have the source? If you don't have control over the
source, you can't rebuild it to enable testability, and it might even be
desirable for someone to refuse to distribute a binary with testability
enabled if doing so might reveal proprietary information or lead to a
possible security problem with their library.


On 7/5/2016 9:53 PM, John McCall via swift-evolution wrote:
>> On Jul 5, 2016, at 6:45 PM, Brent Royal-Gordon via swift-evolution 
>>  wrote:
>>
>>> * What is your evaluation of the proposal?
>> I think it's ultimately a good idea. Being noncommittal about 
>> subclassability/overridability—and thus forbidding it in public scope, but 
>> not making any promises about what the module does internally—is the 
>> alternative that preserves the most freedom for the module, and therefore 
>> the most appropriate default.
>>
>> However, I don't like the `subclassable` and `overridable` keywords. They 
>> read like opposites of `final` with no implications for access level; I 
>> could easily imagine somebody marking an internal class `subclassable` 
>> assuming that it merely means it can be subclassed internally, and being 
>> very surprised (or even not noticing!) that the class has been made public. 
>> They're also long and cumbersome; that might be seen as a positive, but I 
>> think it will increase the inevitable backlash against this change.
>>
>> I prefer the keyword `open`, which sounds like it could be a statement about 
>> the item's accessibility—and even sounds like it ought to be "more public 
>> than public"—and is short enough that it ought to be difficult to grumble 
>> about the change. It also means that both classes and members use the same 
>> keyword, and gives us a keyword that we can later use to "open" other things 
>> in the language, such as allowing you to extend enums with new cases.
> Agreed; I also prefer "open" to having two different long keywords that don't 
> (at least to my ear) imply "public".
>
>> I think Kevin Lundberg is right to worry about testability, but I don't 
>> think that has to prevent this change. Instead, we should permit `@testable` 
>> imports to subclass/override things that are not publicly 
>> subclassable/overridable, and thus a module built with "Enable Testability" 
>> on can't actually assume there are no subclasses/overrides of `internal` 
>> classes/members even if it doesn't see any. This will block optimizations in 
>> debug builds, but not in release builds. The proposal should be edited to 
>> explain this `@testable` behavior.
> IIUC the basic design of @testable is to treat the tests for the testable 
> thing as existing within its module, so I think this just falls out.  I agree 
> that it should be spelled out in the proposal, though.
>
> John.
> ___
> 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] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-05 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jul 5, 2016, at 8:53 PM, John McCall via swift-evolution 
>  wrote:
> 
> 
>>> On Jul 5, 2016, at 6:45 PM, Brent Royal-Gordon via swift-evolution 
>>>  wrote:
>>> 
>>>* What is your evaluation of the proposal?
>> 
>> I think it's ultimately a good idea. Being noncommittal about 
>> subclassability/overridability—and thus forbidding it in public scope, but 
>> not making any promises about what the module does internally—is the 
>> alternative that preserves the most freedom for the module, and therefore 
>> the most appropriate default.
>> 
>> However, I don't like the `subclassable` and `overridable` keywords. They 
>> read like opposites of `final` with no implications for access level; I 
>> could easily imagine somebody marking an internal class `subclassable` 
>> assuming that it merely means it can be subclassed internally, and being 
>> very surprised (or even not noticing!) that the class has been made public. 
>> They're also long and cumbersome; that might be seen as a positive, but I 
>> think it will increase the inevitable backlash against this change.
>> 
>> I prefer the keyword `open`, which sounds like it could be a statement about 
>> the item's accessibility—and even sounds like it ought to be "more public 
>> than public"—and is short enough that it ought to be difficult to grumble 
>> about the change. It also means that both classes and members use the same 
>> keyword, and gives us a keyword that we can later use to "open" other things 
>> in the language, such as allowing you to extend enums with new cases.
> 
> Agreed; I also prefer "open" to having two different long keywords that don't 
> (at least to my ear) imply "public".

+1.  I agree that the keywords in the proposal don't feel like they imply 
public and do feel like they might be required even internally, a really 
unfortunate combination.

> 
>> I think Kevin Lundberg is right to worry about testability, but I don't 
>> think that has to prevent this change. Instead, we should permit `@testable` 
>> imports to subclass/override things that are not publicly 
>> subclassable/overridable, and thus a module built with "Enable Testability" 
>> on can't actually assume there are no subclasses/overrides of `internal` 
>> classes/members even if it doesn't see any. This will block optimizations in 
>> debug builds, but not in release builds. The proposal should be edited to 
>> explain this `@testable` behavior.
> 
> IIUC the basic design of @testable is to treat the tests for the testable 
> thing as existing within its module, so I think this just falls out.  I agree 
> that it should be spelled out in the proposal, though.
> 
> John.
> ___
> 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] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-05 Thread John McCall via swift-evolution

> On Jul 5, 2016, at 6:45 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
>>  * What is your evaluation of the proposal?
> 
> I think it's ultimately a good idea. Being noncommittal about 
> subclassability/overridability—and thus forbidding it in public scope, but 
> not making any promises about what the module does internally—is the 
> alternative that preserves the most freedom for the module, and therefore the 
> most appropriate default.
> 
> However, I don't like the `subclassable` and `overridable` keywords. They 
> read like opposites of `final` with no implications for access level; I could 
> easily imagine somebody marking an internal class `subclassable` assuming 
> that it merely means it can be subclassed internally, and being very 
> surprised (or even not noticing!) that the class has been made public. 
> They're also long and cumbersome; that might be seen as a positive, but I 
> think it will increase the inevitable backlash against this change.
> 
> I prefer the keyword `open`, which sounds like it could be a statement about 
> the item's accessibility—and even sounds like it ought to be "more public 
> than public"—and is short enough that it ought to be difficult to grumble 
> about the change. It also means that both classes and members use the same 
> keyword, and gives us a keyword that we can later use to "open" other things 
> in the language, such as allowing you to extend enums with new cases.

Agreed; I also prefer "open" to having two different long keywords that don't 
(at least to my ear) imply "public".

> I think Kevin Lundberg is right to worry about testability, but I don't think 
> that has to prevent this change. Instead, we should permit `@testable` 
> imports to subclass/override things that are not publicly 
> subclassable/overridable, and thus a module built with "Enable Testability" 
> on can't actually assume there are no subclasses/overrides of `internal` 
> classes/members even if it doesn't see any. This will block optimizations in 
> debug builds, but not in release builds. The proposal should be edited to 
> explain this `@testable` behavior.

IIUC the basic design of @testable is to treat the tests for the testable thing 
as existing within its module, so I think this just falls out.  I agree that it 
should be spelled out in the proposal, though.

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-05 Thread Brent Royal-Gordon via swift-evolution
>   * What is your evaluation of the proposal?

I think it's ultimately a good idea. Being noncommittal about 
subclassability/overridability—and thus forbidding it in public scope, but not 
making any promises about what the module does internally—is the alternative 
that preserves the most freedom for the module, and therefore the most 
appropriate default.

However, I don't like the `subclassable` and `overridable` keywords. They read 
like opposites of `final` with no implications for access level; I could easily 
imagine somebody marking an internal class `subclassable` assuming that it 
merely means it can be subclassed internally, and being very surprised (or even 
not noticing!) that the class has been made public. They're also long and 
cumbersome; that might be seen as a positive, but I think it will increase the 
inevitable backlash against this change.

I prefer the keyword `open`, which sounds like it could be a statement about 
the item's accessibility—and even sounds like it ought to be "more public than 
public"—and is short enough that it ought to be difficult to grumble about the 
change. It also means that both classes and members use the same keyword, and 
gives us a keyword that we can later use to "open" other things in the 
language, such as allowing you to extend enums with new cases.

I think Kevin Lundberg is right to worry about testability, but I don't think 
that has to prevent this change. Instead, we should permit `@testable` imports 
to subclass/override things that are not publicly subclassable/overridable, and 
thus a module built with "Enable Testability" on can't actually assume there 
are no subclasses/overrides of `internal` classes/members even if it doesn't 
see any. This will block optimizations in debug builds, but not in release 
builds. The proposal should be edited to explain this `@testable` behavior.

>   * Is the problem being addressed significant enough to warrant a change 
> to Swift?

Yes.

>   * Does this proposal fit well with the feel and direction of Swift?

Yes.

>   * If you have used other languages or libraries with a similar feature, 
> how do you feel that this proposal compares to those?

I don't think I have.

>   * How much effort did you put into your review? A glance, a quick 
> reading, or an in-depth study?

Quick reading of the final proposal, but I also contributed to previous 
discussion.

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-05 Thread Matthew Johnson via swift-evolution
Extremely strong +1 from me on this proposal.  It is the best default for many, 
many reasons (stated in the proposal and in Austin's review).  It improves 
safety, facilitates and encourages reasoning about code, and will result in an 
ecosystem of overall higher quality.

Sent from my iPad

> On Jul 5, 2016, at 6:49 PM, Austin Zheng via swift-evolution 
>  wrote:
> 
> I'll bite.
> 
>> On Tue, Jul 5, 2016 at 4:11 PM, Chris Lattner  wrote:
>> 
>> * What is your evaluation of the proposal?
> 
> Strong +1. I like this proposal because it forces programmers vending a 
> public API to think about their extension points, and it also provides 
> guarantees to consumers of library and framework APIs as to whether the 
> framework developer intended for a particular class or member to serve as an 
> extension point. More controversially, I like it because it trades off 
> short-term subclass-based hacks in favor of a library ecosystem years down 
> the line that will be significantly higher in quality than it would otherwise 
> be - both because it'll be harder to write misbehaving code, and because 
> it'll support an emerging culture in which API design merits more careful 
> consideration than it would otherwise get.
> 
> I am largely unmoved by arguments involving Cocoa or misdesigned libraries: 
> Apple framework engineers will annotate their frameworks however they want no 
> matter what default we choose; the possibility of badly written code would 
> argue against things like access control, static typing, 'noescape' by 
> default, the lack of swizzling, or any of a huge number of features that 
> could conceivably be used to patch misbehaving code. Developers working in 
> the Apple ecosystem can always fall back to Objective-C as an escape hatch if 
> they really need to monkey-patch Apple framework classes.
> 
> I have a question: one of the alternative syntaxes ("public(subclassable)") 
> is listed as a potential candidate for expansion when resilience is 
> implemented. Is there a description of a potential resilience syntax for the 
> primary proposal?
>  
>> * Is the problem being addressed significant enough to warrant a 
>> change to Swift?
> 
> Yes.
>  
>> * Does this proposal fit well with the feel and direction of Swift?
> 
> Most definitely. For example, making closures non-escaping by default fits 
> into the same model: expose only the most limited guarantees by default, with 
> easy discoverability of more powerful guarantees should a framework author 
> wish to use them. Another example is the raw pointer API proposal currently 
> in the works. In this context, "limited" is not a liability, it is an asset: 
> the more narrow the default semantics are, the easier it is for users to 
> reason about the correctness of their code, and the more aggressively the 
> compiler can optimize.
> 
> Indirectly, this proposal may also encourage framework authors to more 
> carefully consider whether classes or protocols are better suited as 
> extension points for their particular applications. 
>  
>> * If you have used other languages or libraries with a similar 
>> feature, how do you feel that this proposal compares to those?
> 
> n/a
>  
>> * How much effort did you put into your review? A glance, a quick 
>> reading, or an in-depth study?
> 
> I read through the proposal carefully, and have read/participated in most of 
> the threads on the topic over the past few months.
>  
>> 
>> More information about the Swift evolution process is available at
>> 
>> https://github.com/apple/swift-evolution/blob/master/process.md
>> 
>> Thank you,
>> 
>> -Chris Lattner
>> Review Manager
>> 
>> ___
>> swift-evolution-announce mailing list
>> swift-evolution-annou...@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution-announce
> 
> ___
> 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] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-05 Thread Nikita Leonov via swift-evolution
+1 with modifications. In my team we write “final class” a lot. We also do have 
a lot of internal frameworks and an ability to guide external frameworks uses 
is important for us. We have a lot of candidates in our frameworks that should 
be inheritable internally, but we do not recommend to extend them outside of 
framework.

My biggest worry with this proposal is already highlighted in a section 
"Modifier spelling alternatives”. Proposal introduces a set of new keywords to 
express relatively similar concept as current `final` keyword. We currently 
have already an ability to limit inheritance by use `final`, but we can not 
define a scope. However we also have keywords to define an accessibility scope:
* public — accessible everywhere
* internal — accessible within a module
* private — accessible within a file

For example, by leveraging existing keywords we can write code like following:
final(internal) class Foo {
  final(private) func bar() {
  }
} 
So the class `Foo` is inheritable within a module, but method bar is 
overridable only within same file. 
There is also optional `final(public)` that literally means no limitations on 
inheritance that can be used to indicate that class or method is 
`final(public)` on purpose by design. We use the similar approach in our code 
base with `internal`, while it is default keyword for classes and functions we 
still write it to show that it is internal by design and no public / private 
keyword missing.

Also with suggestion above we can default `final` to `final(private)`to keep 
backwards compatibility. 

Best,
Nikita Leonov

> On Jul 5, 2016, at 4:11 PM, Chris Lattner  wrote:
> 
> Hello Swift community,
> 
> The review of "SE-0117: Default classes to be non-subclassable publicly" 
> begins now and runs through July 11. The proposal is available here:
> 
>   
> https://github.com/apple/swift-evolution/blob/master/proposals/0117-non-public-subclassable-by-default.md
> 
> Reviews are an important part of the Swift evolution process. All reviews 
> should be sent to the swift-evolution mailing list at
> 
>   https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> or, if you would like to keep your feedback private, directly to the review 
> manager.
> 
> What goes into a review?
> 
> The goal of the review process is to improve the proposal under review 
> through constructive criticism and contribute to the direction of Swift. When 
> writing your review, here are some questions you might want to answer in your 
> review:
> 
>   * What is your evaluation of the proposal?
>   * Is the problem being addressed significant enough to warrant a change 
> to Swift?
>   * Does this proposal fit well with the feel and direction of Swift?
>   * If you have used other languages or libraries with a similar feature, 
> how do you feel that this proposal compares to those?
>   * How much effort did you put into your review? A glance, a quick 
> reading, or an in-depth study?
> 
> More information about the Swift evolution process is available at
> 
>   https://github.com/apple/swift-evolution/blob/master/process.md
> 
> Thank you,
> 
> -Chris Lattner
> Review Manager
> 
> ___
> swift-evolution-announce mailing list
> swift-evolution-annou...@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution-announce

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-05 Thread Austin Zheng via swift-evolution
I'll bite.

On Tue, Jul 5, 2016 at 4:11 PM, Chris Lattner  wrote:
>
>
> * What is your evaluation of the proposal?
>

Strong +1. I like this proposal because it forces programmers vending a
public API to think about their extension points, and it also provides
guarantees to consumers of library and framework APIs as to whether the
framework developer intended for a particular class or member to serve as
an extension point. More controversially, I like it because it trades off
short-term subclass-based hacks in favor of a library ecosystem years down
the line that will be significantly higher in quality than it would
otherwise be - both because it'll be harder to write misbehaving code, and
because it'll support an emerging culture in which API design merits more
careful consideration than it would otherwise get.

I am largely unmoved by arguments involving Cocoa or misdesigned libraries:
Apple framework engineers will annotate their frameworks however they want
no matter what default we choose; the possibility of badly written code
would argue against things like access control, static typing, 'noescape'
by default, the lack of swizzling, or any of a huge number of features that
could conceivably be used to patch misbehaving code. Developers working in
the Apple ecosystem can always fall back to Objective-C as an escape hatch
if they really need to monkey-patch Apple framework classes.

I have a question: one of the alternative syntaxes ("public(subclassable)")
is listed as a potential candidate for expansion when resilience is
implemented. Is there a description of a potential resilience syntax for
the primary proposal?


> * Is the problem being addressed significant enough to warrant a
> change to Swift?
>

Yes.


> * Does this proposal fit well with the feel and direction of Swift?
>

Most definitely. For example, making closures non-escaping by default fits
into the same model: expose only the most limited guarantees by default,
with easy discoverability of more powerful guarantees should a framework
author wish to use them. Another example is the raw pointer API proposal
currently in the works. In this context, "limited" is not a liability, it
is an asset: the more narrow the default semantics are, the easier it is
for users to reason about the correctness of their code, and the more
aggressively the compiler can optimize.

Indirectly, this proposal may also encourage framework authors to more
carefully consider whether classes or protocols are better suited as
extension points for their particular applications.


> * If you have used other languages or libraries with a similar
> feature, how do you feel that this proposal compares to those?
>

n/a


> * How much effort did you put into your review? A glance, a quick
> reading, or an in-depth study?
>

I read through the proposal carefully, and have read/participated in most
of the threads on the topic over the past few months.


>
> More information about the Swift evolution process is available at
>
> https://github.com/apple/swift-evolution/blob/master/process.md
>
> Thank you,
>
> -Chris Lattner
> Review Manager
>
> ___
> swift-evolution-announce mailing list
> swift-evolution-annou...@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution-announce
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution