[Proposal] Sealed classes by default


(John Holdsworth) #1

Hi folks,

I see from building the latest Swift-3.0 branch that I’m a little behind the times and this proposal has been accepted :frowning:

https://github.com/apple/swift-evolution/blob/master/proposals/0117-non-public-subclassable-by-default.md

Is there no way we can revisit this decision? 60 emails on a mail group not read by the whole community
doesn’t quite seem enough validation for such a significant change to me. Of those that expressed an
opinion on the thread many were against sealing classes outside the module.

https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160627/022364.html

I personally feel it's a huge mistake for the following reasons:

1) it “breaks open source” reducing the reusability of third party software by default.

2) Contrary to arguments about the likely performance benefits of de-virtualisation of method dispatch it is
likely to make Swift programs launch more slowly due to the dynamic linker having to slide large numbers
of function pointers for most method calls (itself an expensive operation) whether a call is even made.

On the first point it's an established technique in OOP to be able to subclass and override to adapt a class
for a role perhaps it’s author never considered. Call this “monkey-patching” if you like but it is a part of being
able to use open source libraries without having to make a fork as would be the case if sealed by default.
Are we expecting developers to remember to leave their classes (and methods?) "open”? If they do feel
that others shouldn’t subclass or override there was always “final". Distinctions about whether this is possible
inside or outside a module seem a mute point to me.

The second point is more of an engineering one. “Virtual” dispatch on Swift is not a significant overhead
compared to fully dynamic dispatch on Objective-C which even then was seldom a problem. There is a
cost however to de-virtualisation and resolving to a direct call to a method address in that the dynamic
linker has to resolve and slide the pointer on load. This type of concern is a bad argument to use in
designing a language anyway even if it is called Swift.

Well, I know the boat has left on this one and I’ll likely have to live with it but this is the proposal I
most disagree with on evolution this far. Programmers have morals and just because you shouldn’t
do something doesn’t mean the language needs to turn that into can’t by default when the need arises.
If this change does go ahead please try to get it into the next Xcode beta as it is a very incompatible one.

Cheers,

John


(Félix Cloutier) #2

There was an order of magnitude more than 60 emails about this. In my inbox, I count 452 emails that have 0117 in the title. Discussion had already started before the proposal and I'm not counting these.

Félix

···

Le 14 août 2016 à 02:17:36, John Holdsworth via swift-evolution <swift-evolution@swift.org> a écrit :

Hi folks,

I see from building the latest Swift-3.0 branch that I’m a little behind the times and this proposal has been accepted :frowning:

https://github.com/apple/swift-evolution/blob/master/proposals/0117-non-public-subclassable-by-default.md

Is there no way we can revisit this decision? 60 emails on a mail group not read by the whole community
doesn’t quite seem enough validation for such a significant change to me. Of those that expressed an
opinion on the thread many were against sealing classes outside the module.

https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160627/022364.html

I personally feel it's a huge mistake for the following reasons:

1) it “breaks open source” reducing the reusability of third party software by default.

2) Contrary to arguments about the likely performance benefits of de-virtualisation of method dispatch it is
likely to make Swift programs launch more slowly due to the dynamic linker having to slide large numbers
of function pointers for most method calls (itself an expensive operation) whether a call is even made.

On the first point it's an established technique in OOP to be able to subclass and override to adapt a class
for a role perhaps it’s author never considered. Call this “monkey-patching” if you like but it is a part of being
able to use open source libraries without having to make a fork as would be the case if sealed by default.
Are we expecting developers to remember to leave their classes (and methods?) "open”? If they do feel
that others shouldn’t subclass or override there was always “final". Distinctions about whether this is possible
inside or outside a module seem a mute point to me.

The second point is more of an engineering one. “Virtual” dispatch on Swift is not a significant overhead
compared to fully dynamic dispatch on Objective-C which even then was seldom a problem. There is a
cost however to de-virtualisation and resolving to a direct call to a method address in that the dynamic
linker has to resolve and slide the pointer on load. This type of concern is a bad argument to use in
designing a language anyway even if it is called Swift.

Well, I know the boat has left on this one and I’ll likely have to live with it but this is the proposal I
most disagree with on evolution this far. Programmers have morals and just because you shouldn’t
do something doesn’t mean the language needs to turn that into can’t by default when the need arises.
If this change does go ahead please try to get it into the next Xcode beta as it is a very incompatible one.

Cheers,

John

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


(Jean-Daniel) #3

60 emails ? You’re joking. It is more 600 emails than 60 that was send about that proposal, and I’m pretty sure nobody want to see that discussion start again.

···

Le 14 août 2016 à 11:17, John Holdsworth via swift-evolution <swift-evolution@swift.org> a écrit :

Hi folks,

I see from building the latest Swift-3.0 branch that I’m a little behind the times and this proposal has been accepted :frowning:

https://github.com/apple/swift-evolution/blob/master/proposals/0117-non-public-subclassable-by-default.md

Is there no way we can revisit this decision? 60 emails on a mail group not read by the whole community
doesn’t quite seem enough validation for such a significant change to me.


(Karl) #4

It we are happy with non-open != final, I would be in favour of some kind of monkey-patching import attribute, similar to @testable, which allows you to subclass non-open classes at your own risk.

I would be doubly-happy if we were to call it "@monkey-patched import UIKit"

Karl

···

On 14 Aug 2016, at 11:17, John Holdsworth via swift-evolution <swift-evolution@swift.org> wrote:

Hi folks,

I see from building the latest Swift-3.0 branch that I’m a little behind the times and this proposal has been accepted :frowning:

https://github.com/apple/swift-evolution/blob/master/proposals/0117-non-public-subclassable-by-default.md

Is there no way we can revisit this decision? 60 emails on a mail group not read by the whole community
doesn’t quite seem enough validation for such a significant change to me. Of those that expressed an
opinion on the thread many were against sealing classes outside the module.

https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160627/022364.html

I personally feel it's a huge mistake for the following reasons:

1) it “breaks open source” reducing the reusability of third party software by default.

2) Contrary to arguments about the likely performance benefits of de-virtualisation of method dispatch it is
likely to make Swift programs launch more slowly due to the dynamic linker having to slide large numbers
of function pointers for most method calls (itself an expensive operation) whether a call is even made.

On the first point it's an established technique in OOP to be able to subclass and override to adapt a class
for a role perhaps it’s author never considered. Call this “monkey-patching” if you like but it is a part of being
able to use open source libraries without having to make a fork as would be the case if sealed by default.
Are we expecting developers to remember to leave their classes (and methods?) "open”? If they do feel
that others shouldn’t subclass or override there was always “final". Distinctions about whether this is possible
inside or outside a module seem a mute point to me.

The second point is more of an engineering one. “Virtual” dispatch on Swift is not a significant overhead
compared to fully dynamic dispatch on Objective-C which even then was seldom a problem. There is a
cost however to de-virtualisation and resolving to a direct call to a method address in that the dynamic
linker has to resolve and slide the pointer on load. This type of concern is a bad argument to use in
designing a language anyway even if it is called Swift.

Well, I know the boat has left on this one and I’ll likely have to live with it but this is the proposal I
most disagree with on evolution this far. Programmers have morals and just because you shouldn’t
do something doesn’t mean the language needs to turn that into can’t by default when the need arises.
If this change does go ahead please try to get it into the next Xcode beta as it is a very incompatible one.

Cheers,

John

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


(Slava Pestov) #5

The proposal is independent of any specific implementation strategy or ABI. If vtable dispatch is faster across module boundaries than function calls, we can continue using vtable dispatch.

We need to have a separate discussion about the implementation of open, public and final classes for ABI and resilience reasons anyway.

Slava

···

On Aug 14, 2016, at 2:17 AM, John Holdsworth via swift-evolution <swift-evolution@swift.org> wrote:

2) Contrary to arguments about the likely performance benefits of de-virtualisation of method dispatch it is
likely to make Swift programs launch more slowly due to the dynamic linker having to slide large numbers
of function pointers for most method calls (itself an expensive operation) whether a call is even made.


(Goffredo Marocchi) #6

You are not familiar with us Italians and our love for (hopefully reasonable) arguing I see ;). I commit to and accept the decision taken, but it remains a decision I disagree with and something that will probably birth a painful fork once say Android and/or other big corporations moved to Swift and decided for example that they wanted a new set of rules.

···

Sent from my iPhone

On 14 Aug 2016, at 11:14, Jean-Daniel Dupas via swift-evolution <swift-evolution@swift.org> wrote:

Le 14 août 2016 à 11:17, John Holdsworth via swift-evolution <swift-evolution@swift.org> a écrit :

Hi folks,

I see from building the latest Swift-3.0 branch that I’m a little behind the times and this proposal has been accepted :frowning:

https://github.com/apple/swift-evolution/blob/master/proposals/0117-non-public-subclassable-by-default.md

Is there no way we can revisit this decision? 60 emails on a mail group not read by the whole community
doesn’t quite seem enough validation for such a significant change to me.

60 emails ? You’re joking. It is more 600 emails than 60 that was send about that proposal, and I’m pretty sure nobody want to see that discussion start again.

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


(Jean-Daniel) #7

The non subclassable across module boundary is not just a compiler enforced limitation. Once you compile a module with classes that are ‘final’ in the module, the compiler may devirtualize all call sites in the module, or even inlining some calls, making subclassing unpredictable and pointless.

···

Le 14 août 2016 à 20:43, Karl via swift-evolution <swift-evolution@swift.org> a écrit :

On 14 Aug 2016, at 11:17, John Holdsworth via swift-evolution <swift-evolution@swift.org> wrote:

Hi folks,

I see from building the latest Swift-3.0 branch that I’m a little behind the times and this proposal has been accepted :frowning:

https://github.com/apple/swift-evolution/blob/master/proposals/0117-non-public-subclassable-by-default.md

Is there no way we can revisit this decision? 60 emails on a mail group not read by the whole community
doesn’t quite seem enough validation for such a significant change to me. Of those that expressed an
opinion on the thread many were against sealing classes outside the module.

https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160627/022364.html

I personally feel it's a huge mistake for the following reasons:

1) it “breaks open source” reducing the reusability of third party software by default.

2) Contrary to arguments about the likely performance benefits of de-virtualisation of method dispatch it is
likely to make Swift programs launch more slowly due to the dynamic linker having to slide large numbers
of function pointers for most method calls (itself an expensive operation) whether a call is even made.

On the first point it's an established technique in OOP to be able to subclass and override to adapt a class
for a role perhaps it’s author never considered. Call this “monkey-patching” if you like but it is a part of being
able to use open source libraries without having to make a fork as would be the case if sealed by default.
Are we expecting developers to remember to leave their classes (and methods?) "open”? If they do feel
that others shouldn’t subclass or override there was always “final". Distinctions about whether this is possible
inside or outside a module seem a mute point to me.

The second point is more of an engineering one. “Virtual” dispatch on Swift is not a significant overhead
compared to fully dynamic dispatch on Objective-C which even then was seldom a problem. There is a
cost however to de-virtualisation and resolving to a direct call to a method address in that the dynamic
linker has to resolve and slide the pointer on load. This type of concern is a bad argument to use in
designing a language anyway even if it is called Swift.

Well, I know the boat has left on this one and I’ll likely have to live with it but this is the proposal I
most disagree with on evolution this far. Programmers have morals and just because you shouldn’t
do something doesn’t mean the language needs to turn that into can’t by default when the need arises.
If this change does go ahead please try to get it into the next Xcode beta as it is a very incompatible one.

Cheers,

John

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

It we are happy with non-open != final, I would be in favour of some kind of monkey-patching import attribute, similar to @testable, which allows you to subclass non-open classes at your own risk.


(Jean-Denis Muys) #8

I for one would very much like this discussion to start again.

Yes it was discussed. Unfortunately, it was discussed in a summer time when in my country at least, many of us are off the grid for vacation. This is not a criticism of the process of course, just an indication that not everyone may have had the chance to voice their concerns.

As I expressed it already, even after reading all the arguments for the decision, I stand convinced that this decision is a tragic mistake. Note that I agree with many of the given rationales. I just think that the decision doesn't follow.

I will not rehash everything, but I will make a couple of points that may not have been expressed stridently enough:

- many many many people expressed contrary voices, and where shut up by the core team's expressing their opinion in favor of preventing subclassability by default. See a small sample at http://mjtsai.com/blog/2016/07/17/swift-classes-to-be-non-publicly-subclassable-by-default/

- One reason I (and others) gave is that I would not trust any programmer (least of which myself) to have the double sight ability to foresee every use of their classes/libraries. One disingenuous answer to that was "if you don't trust the programmer, why do you use their code to begin with?". Well, I don't trust my spouse's ability to forecast the time it takes to drive from place A to place B. Yet I will not break up over that. Time and time again, I have heard Apple executives praise us developers for the use of Apple's technology that they would never have foreseen. This decision goes totally contrary to those praises.

This decision is bad, not because it makes the default for classes to be unsubclassable, but because it puts the power of final decision into the wrong hands: the library author's.

As a result, guidelines everywhere will eventually mandate for library authors to make everything "open", exactly as the guidelines for public C++ classes is often to make methods virtual. This will nullify much of the benefits of the decision.

The final programmer, the client programmer who uses the class should have the final say. The class author is entitled to express "beware, you will likely shoot yourself in the foot". But the final programmer should have the power to answer "thanks for saying. Now give me that gun."

My hope is that we can give back the final say to the final programmer through an additive Swift evolution proposal down the line, which would explicitly allow her to "force open" a closed class. I believe that such an addition would right the wrong while still keeping he benefits of the decision.

I don't think that such a proposal would affect the ABI, so it seems to me this is not yet the time to come up with such a proposal. I may be wrong on that though: I am quite unclear on what does or does not affect the ABI.

To conclude let me give you an anecdote: I was writing this in-house iPhone app for a client, that used the common UITabViewController UI model. We had 5 tabs and 5 icons and all was good. Then the client asked for a new feature into a new 6th tab and wanted a 6th icon to be squeezed in the tab bar. The Apple's UI guidelines the, and the UITabViewController class precluded that (it may have changed since, I haven't developed for iOS in quite a while). However user testing showed that it was quite OK to put 6 icons there. I was able to subclass UITabViewController to accommodate for that, despite the fact the it was not only not designed for that, but also actively designed to prevent that.

Now there are many reasons why it could be claimed that what I did was wrong. And I would agree with those I suspect. However, that I could do it (pondering all factors) was actually the difference between "yes but" and "no way". As a result, my customer was another happy Apple user.

With Swift and that decision, this would not have happened, and we would all have been the poorer for it.

I hope I that this additive proposal I mentioned above can see the light of day in due time.

Best regards,

Jean-Denis

···

On Aug 14, 2016, at 14:26, Goffredo Marocchi via swift-evolution <swift-evolution@swift.org> wrote:

You are not familiar with us Italians and our love for (hopefully reasonable) arguing I see ;). I commit to and accept the decision taken, but it remains a decision I disagree with and something that will probably birth a painful fork once say Android and/or other big corporations moved to Swift and decided for example that they wanted a new set of rules.

Sent from my iPhone

On 14 Aug 2016, at 11:14, Jean-Daniel Dupas via swift-evolution <swift-evolution@swift.org> wrote:

Le 14 août 2016 à 11:17, John Holdsworth via swift-evolution <swift-evolution@swift.org> a écrit :

Hi folks,

I see from building the latest Swift-3.0 branch that I’m a little behind the times and this proposal has been accepted :frowning:

https://github.com/apple/swift-evolution/blob/master/proposals/0117-non-public-subclassable-by-default.md

Is there no way we can revisit this decision? 60 emails on a mail group not read by the whole community
doesn’t quite seem enough validation for such a significant change to me.

60 emails ? You’re joking. It is more 600 emails than 60 that was send about that proposal, and I’m pretty sure nobody want to see that discussion start again.

_______________________________________________
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


(Jean-Denis Muys) #9

This is a detail of implementation and doesn't have to be. You might even imagine the compiler emitting two versions of the code, one assuming the class will not be subclassed, the other not assuming that, and a smart linker linking the right version depending on the case.

So for me, in the long run, this argument is not an argument at all.

Even then, is it really appropriate to sacrifice expressivity on the altar of (marginally) better performance?

Jean-Denis

···

On 15 Aug 2016, at 09:50, Jean-Daniel Dupas via swift-evolution <swift-evolution@swift.org> wrote:

The non subclassable across module boundary is not just a compiler enforced limitation. Once you compile a module with classes that are ‘final’ in the module, the compiler may devirtualize all call sites in the module, or even inlining some calls, making subclassing unpredictable and pointless.

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


(Karl) #10

Yeah I know - that's why I said it would only work if we are okay with saying non-open != final, as a long-term decision. So the compiler won't devirtualize those calls.
  
As I understand it, that is how it works today - calls to non-open, non-final classes are still dynamically dispatched. There was a suggestion to make non-open == final, but that was expressly rejected.
  
Karl

···

Sent from my new Email (https://itunes.apple.com/app/apple-store/id922793622?pt=814382&mt=8&ct=my_new_email)
  

On Aug 15, 2016 at 9:50 am, <Jean-Daniel Dupas (mailto:mailing@xenonium.com)> wrote:
  
> Le 14 août 2016 à 20:43, Karl via swift-evolution <swift-evolution@swift.org (mailto:swift-evolution@swift.org)> a écrit :
>
>
>> On 14 Aug 2016, at 11:17, John Holdsworth via swift-evolution <swift-evolution@swift.org (mailto:swift-evolution@swift.org)> wrote:
>>
>> Hi folks,
>>
>> I see from building the latest Swift-3.0 branch that I’m a little behind the times and this proposal has been accepted :frowning:
>>
>> https://github.com/apple/swift-evolution/blob/master/proposals/0117-non-public-subclassable-by-default.md
>>
>> Is there no way we can revisit this decision? 60 emails on a mail group not read by the whole community
>> doesn’t quite seem enough validation for such a significant change to me. Of those that expressed an
>> opinion on the thread many were against sealing classes outside the module.
>>
>> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160627/022364.html
>>
>> I personally feel it's a huge mistake for the following reasons:
>>
>> 1) it “breaks open source” reducing the reusability of third party software by default.
>>
>> 2) Contrary to arguments about the likely performance benefits of de-virtualisation of method dispatch it is
>> likely to make Swift programs launch more slowly due to the dynamic linker having to slide large numbers
>> of function pointers for most method calls (itself an expensive operation) whether a call is even made.
>>
>> On the first point it's an established technique in OOP to be able to subclass and override to adapt a class
>> for a role perhaps it’s author never considered. Call this “monkey-patching” if you like but it is a part of being
>> able to use open source libraries without having to make a fork as would be the case if sealed by default.
>> Are we expecting developers to remember to leave their classes (and methods?) "open”? If they do feel
>> that others shouldn’t subclass or override there was always “final". Distinctions about whether this is possible
>> inside or outside a module seem a mute point to me.
>>
>> The second point is more of an engineering one. “Virtual” dispatch on Swift is not a significant overhead
>> compared to fully dynamic dispatch on Objective-C which even then was seldom a problem. There is a
>> cost however to de-virtualisation and resolving to a direct call to a method address in that the dynamic
>> linker has to resolve and slide the pointer on load. This type of concern is a bad argument to use in
>> designing a language anyway even if it is called Swift.
>>
>> Well, I know the boat has left on this one and I’ll likely have to live with it but this is the proposal I
>> most disagree with on evolution this far. Programmers have morals and just because you shouldn’t
>> do something doesn’t mean the language needs to turn that into can’t by default when the need arises.
>> If this change does go ahead please try to get it into the next Xcode beta as it is a very incompatible one.
>>
>> Cheers,
>>
>> John
>>
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org (mailto:swift-evolution@swift.org)
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> It we are happy with non-open != final, I would be in favour of some kind of monkey-patching import attribute, similar to @testable, which allows you to subclass non-open classes at your own risk.
>

The non subclassable across module boundary is not just a compiler enforced limitation. Once you compile a module with classes that are ‘final’ in the module, the compiler may devirtualize all call sites in the module, or even inlining some calls, making subclassing unpredictable and pointless.


(Chris Lattner) #11

To set expectations here, we are beyond the end of source breaking changes for Swift 3, so they cannot be changed for Swift 3. We plan to have ways to take limited source breaking changes in Swift 4, but don't know the scope of them because we haven’t designed the mechanism, and don’t know what scope it will allow.

This is all a way of saying that we *cannot* change this right now, and that discussing it is pointless.

From another perspective, I will point out that this was a carefully considered decision with much active debate, so unless there is *new* information that comes to light, it won’t be reopened.

-Chris

···

On Aug 14, 2016, at 5:59 AM, Jean-Denis Muys via swift-evolution <swift-evolution@swift.org> wrote:

I for one would very much like this discussion to start again.


(Tino) #12

Seems that the prediction of the grief caused by SE-0117 in the long run was right :wink: — but be careful, the title doesn't reflect reality anymore:
As far as I understand, the default won't be changed at all.
It has been internal, and it will be internal.
The change is that changing the default to "public" will only make a class/method visible outside the current module, without the right to subclass/override.
So, basically, "public" is renamed to "open".
Imho this is still causing unnecessary trouble, as it breaks most libraries out there (more precisely: Third party code that relies on the old behavior), but in the future, you can just use "open" instead of "public", and little else will change — except that users of your framework may assume that "open" is an extension of "public", whereas you may follow the notion that "public" is an restriction of "open".

In the end, imho the whole topic has been decided in a very Solomonic way that disappoints both parties ;-), so I don't think it will be a reason for someone to fork Swift.

···

Am 14.08.2016 um 14:59 schrieb Jean-Denis Muys via swift-evolution <swift-evolution@swift.org>:

This decision is bad, not because it makes the default for classes to be unsubclassable


(Shawn Erickson) #13

Yeah I am fairly sure at this point in time "open" is purely about a
statement of API contract (defaulted such to favor being explicit) which
IMHO is a very good tool to have in the toolbox for module/framework
developers. If it proves out to work well then I believe compiler
optimizations could start to leverage it but I don't think any of those are
in place currently. By that same token if "monkey" patch is seen to be
important that could be proposed in the future as well. (on the later the
core team – and myself included (not a core member) – don't favor the
monkey patching view of things, especially in the face of all of the other
Swift things aren't sub-classible).

-Shawn

···

On Mon, Aug 15, 2016 at 9:09 AM Karl Wagner via swift-evolution < swift-evolution@swift.org> wrote:

Yeah I know - that's why I said it would only work if we are okay with
saying non-open != final, as a long-term decision. So the compiler won't
devirtualize those calls.

As I understand it, that is how it works today - calls to non-open,
non-final classes are still dynamically dispatched. There was a suggestion
to make non-open == final, but that was expressly rejected.

Karl

Sent from my new Email
<https://itunes.apple.com/app/apple-store/id922793622?pt=814382&mt=8&ct=my_new_email>

On Aug 15, 2016 at 9:50 am, <Jean-Daniel Dupas <mailing@xenonium.com>> > wrote:

> Le 14 août 2016 à 20:43, Karl via swift-evolution <swift-evolution@swift.org> a écrit :
>
>
>> On 14 Aug 2016, at 11:17, John Holdsworth via swift-evolution <swift-evolution@swift.org> wrote:
>>
>> Hi folks,
>>
>> I see from building the latest Swift-3.0 branch that I’m a little behind the times and this proposal has been accepted :frowning:
>>
>> https://github.com/apple/swift-evolution/blob/master/proposals/0117-non-public-subclassable-by-default.md
>>
>> Is there no way we can revisit this decision? 60 emails on a mail group not read by the whole community
>> doesn’t quite seem enough validation for such a significant change to me. Of those that expressed an
>> opinion on the thread many were against sealing classes outside the module.
>>
>> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160627/022364.html
>>
>> I personally feel it's a huge mistake for the following reasons:
>>
>> 1) it “breaks open source” reducing the reusability of third party software by default.
>>
>> 2) Contrary to arguments about the likely performance benefits of de-virtualisation of method dispatch it is
>> likely to make Swift programs launch more slowly due to the dynamic linker having to slide large numbers
>> of function pointers for most method calls (itself an expensive operation) whether a call is even made.
>>
>> On the first point it's an established technique in OOP to be able to subclass and override to adapt a class
>> for a role perhaps it’s author never considered. Call this “monkey-patching” if you like but it is a part of being
>> able to use open source libraries without having to make a fork as would be the case if sealed by default.
>> Are we expecting developers to remember to leave their classes (and methods?) "open”? If they do feel
>> that others shouldn’t subclass or override there was always “final". Distinctions about whether this is possible
>> inside or outside a module seem a mute point to me.
>>
>> The second point is more of an engineering one. “Virtual” dispatch on Swift is not a significant overhead
>> compared to fully dynamic dispatch on Objective-C which even then was seldom a problem. There is a
>> cost however to de-virtualisation and resolving to a direct call to a method address in that the dynamic
>> linker has to resolve and slide the pointer on load. This type of concern is a bad argument to use in
>> designing a language anyway even if it is called Swift.
>>
>> Well, I know the boat has left on this one and I’ll likely have to live with it but this is the proposal I
>> most disagree with on evolution this far. Programmers have morals and just because you shouldn’t
>> do something doesn’t mean the language needs to turn that into can’t by default when the need arises.
>> If this change does go ahead please try to get it into the next Xcode beta as it is a very incompatible one.
>>
>> Cheers,
>>
>> John
>>
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> It we are happy with non-open != final, I would be in favour of some kind of monkey-patching import attribute, similar to @testable, which allows you to subclass non-open classes at your own risk.
>

The non subclassable across module boundary is not just a compiler enforced limitation. Once you compile a module with classes that are ‘final’ in the module, the compiler may devirtualize all call sites in the module, or even inlining some calls, making subclassing unpredictable and pointless.

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


(John Holdsworth) #14

Well, I walked into that one :frowning: Sorry to trawl all that up on a Sunday.

I get it now. “open” is the new “public”, “public, the new “final” at
least as far as classes outside the module are concerned.

John

···

On 15 Aug 2016, at 10:51, Tino Heth <2th@gmx.de> wrote:

Am 14.08.2016 um 14:59 schrieb Jean-Denis Muys via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>>:

This decision is bad, not because it makes the default for classes to be unsubclassable

Seems that the prediction of the grief caused by SE-0117 in the long run was right :wink: — but be careful, the title doesn't reflect reality anymore:
As far as I understand, the default won't be changed at all.
It has been internal, and it will be internal.
The change is that changing the default to "public" will only make a class/method visible outside the current module, without the right to subclass/override.
So, basically, "public" is renamed to "open".
Imho this is still causing unnecessary trouble, as it breaks most libraries out there (more precisely: Third party code that relies on the old behavior), but in the future, you can just use "open" instead of "public", and little else will change — except that users of your framework may assume that "open" is an extension of "public", whereas you may follow the notion that "public" is an restriction of "open".

In the end, imho the whole topic has been decided in a very Solomonic way that disappoints both parties ;-), so I don't think it will be a reason for someone to fork Swift.