Re: [swift-evolution] [Proposal] Sealed classes by default

2016-08-15 Thread Karl Wagner via swift-evolution
  
  
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=8=my_new_email)
  
  
  
  

  
  
>   
> On Aug 15, 2016 at 9:50 am,   (mailto:mail...@xenonium.com)>  wrote:
>   
>   
>   
>   
> >  Le 14 août 2016 à 20:43, Karl via swift-evolution  
> >   a écrit :  
> >   
> >   
> >>  On 14 Aug 2016, at 11:17, John Holdsworth via swift-evolution  
> >>   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 :(  
> >>   
> >>   
> >> 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.  
>
>
>  ___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-08-15 Thread John Holdsworth via swift-evolution
Well, I walked into that one :( 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 <2...@gmx.de> wrote:
> 
> 
>> Am 14.08.2016 um 14:59 schrieb Jean-Denis Muys via swift-evolution 
>> >:
>> 
>> 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 ;-) — 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.

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


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-08-15 Thread Jean-Denis Muys via swift-evolution
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 
>  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
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-08-15 Thread Jean-Daniel Dupas via swift-evolution

> Le 14 août 2016 à 20:43, Karl via swift-evolution  
> a écrit :
> 
> 
>> On 14 Aug 2016, at 11:17, John Holdsworth via swift-evolution 
>>  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 :(
>> 
>> 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


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-08-14 Thread Karl via swift-evolution

> On 14 Aug 2016, at 11:17, John Holdsworth via swift-evolution 
>  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 :(
> 
> 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.

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

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


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-08-14 Thread Félix Cloutier via swift-evolution
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 
>  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 :(
> 
> 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

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


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-08-14 Thread Chris Lattner via swift-evolution

> On Aug 14, 2016, at 5:59 AM, Jean-Denis Muys via swift-evolution 
>  wrote:
> 
> I for one would very much like this discussion to start again.

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

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


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-08-14 Thread Jean-Denis Muys via swift-evolution
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 
>  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 
>>  wrote:
>> 
>> 
>>> Le 14 août 2016 à 11:17, John Holdsworth via swift-evolution 
>>>  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 :(

Re: [swift-evolution] [Proposal] Sealed classes by default

2016-08-14 Thread Goffredo Marocchi via swift-evolution
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 
>  wrote:
> 
> 
>> Le 14 août 2016 à 11:17, John Holdsworth via swift-evolution 
>>  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 :(
>> 
>> 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


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-08-14 Thread Jean-Daniel Dupas via swift-evolution

> Le 14 août 2016 à 11:17, John Holdsworth via swift-evolution 
>  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 :(
> 
> 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


Re: [swift-evolution] [Proposal] Sealed classes by default

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

> On Jul 2, 2016, at 10:58 AM, L. Mihalkovic  
> wrote:
> 
> 
> Regards
> LM
> (From mobile)
> 
> On Jun 30, 2016, at 9:12 AM, John McCall  > wrote:
> 
>>> On Jun 29, 2016, at 10:27 PM, L. Mihalkovic  
>>> wrote:
>>> 
>>> On Jun 29, 2016, at 9:54 PM, John McCall via swift-evolution 
>>>  wrote:
>>> 
> On Jun 29, 2016, at 12:05 PM, Michael Peternell 
>  wrote:
> I'm still unhappy about this "sealed by default" proposal. That really 
> looks like premature optimization to me. Instead there should be some 
> `sealed` keyword. Maybe it should be called `applepublic` :-p Everyone 
> will understand!
> 
> `sealed` classes should be a special optimization used by optimizing 
> developers who ask for it. Don't make it an unwanted and un-asked-for 
> default optimization. The people who care for optimization much will 
> learn about `sealed` and be able to apply the concept in both cases. The 
> people who don't care about performance will just be disappointed by the 
> "implicitly sealed" behavior. And with this proposal, when I read 
> `unsealed` I can never know: "did this developer intend me to be able to 
> subclass this class? or did he just not want to restrict me 
> unnecessarily?" The documenting aspect of `unsealed` is so small.
> 
> And `sealed` is just an optimization; IMHO the magic of static dispatch 
> lies in final classes or final methods. Sealing everything by default 
> just marks many classes and methods as implicitly final (because it can 
> be proven that they are not subclassed). I just don't think that all 
> these theoretical performance improvements are really worth the trouble 
> in practice.
 
 I'm confused about why you think this is so much of a problem.  Do you 
 really anticipate writing so many Swift libraries with public classes?
>>> 
>>> Look at some of the public libs on github for server side swift.. one 
>>> recently claimed 50 modules and counting... I think swift is missing a 
>>> level of containment below modules, and people are starting to make up for 
>>> it by creating a flury of (1class+1protocol) modules, especially now that 
>>> package manager makes it so trivial to create them. I think this is only 
>>> the begining... and nodejs is there to show how insane it could become:  
>>> remember the recent "trimleft" nightmare (1 module with 15 LOC including 
>>> brackets used pervasively that suddenly disapears).
>> 
>> I'm not arguing that there aren't going to be a lot of libraries.  We're all 
>> excited about the number of libraries.  Libraries are great.  
> 
> The issue is that according to this year's very interesting talk on perf is 
> that an app's startup time can get thrown over the limit by having to perform 
> too much relocation during dylib loading. I doubt too many will actually pay 
> attention (i just started a nodejs app a couple days ago and before it did 
> anything, bringing in angular and a few other dependencies downloaded 168M in 
> over 60 modules)

I'm referring to libraries as a tool for code organization.  Right now, some of 
the build tooling around Swift assumes that libraries have to be built as a 
separate dynamic library, and I agree that that's really unfortunate.

>> I'm trying to understand whether the objections here — which only matter on 
>> library boundaries — are motivated by any concrete experience writing such 
>> libraries in Swift.
>> 
>> Michael's argument was that sealed-by-default will be a major problem for 
>> those libraries and their users.  Let's suppose that there's a library with 
>> a public class, and it's sealed by default.  We can conclude that the author 
>> has never once tried to subclass this class outside of their library, 
>> because if they had, they would have gotten a compiler error.  Therefore, at 
>> best, if I hack the library to allow subclasses, I'm going to be doing 
>> something that has never once been tested and certainly was not considered 
>> when the class was written.  It's pretty clear that this is not the 
>> developer's intent.
> 
> I think that you r considering an already sophisticated developer to whom you 
> attribute the thought of 'whats it gonna be to use my code'. compared to the 
> real life i know. That said I spent some time thinking about your arguments 
> and I guess i can live with sealed (

Okay.  I think this has been a really productive conversation, and it's 
definitely made the proposal better, thank you.

John.

> 
>> Likewise, it's not true that "the documenting aspect of `unsealed` is so 
>> small".  Under sealed-by-default, the developer has to make a conscious, 
>> deliberate step to allow subclasses outside of their library.  They clearly 
>> do intend for you to be able to subclass this class.  It's 

Re: [swift-evolution] [Proposal] Sealed classes by default

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

Regards
LM
(From mobile)

On Jun 30, 2016, at 9:12 AM, John McCall  wrote:

>> On Jun 29, 2016, at 10:27 PM, L. Mihalkovic  
>> wrote:
>> 
>> On Jun 29, 2016, at 9:54 PM, John McCall via swift-evolution 
>>  wrote:
>> 
 On Jun 29, 2016, at 12:05 PM, Michael Peternell  
 wrote:
 I'm still unhappy about this "sealed by default" proposal. That really 
 looks like premature optimization to me. Instead there should be some 
 `sealed` keyword. Maybe it should be called `applepublic` :-p Everyone 
 will understand!
 
 `sealed` classes should be a special optimization used by optimizing 
 developers who ask for it. Don't make it an unwanted and un-asked-for 
 default optimization. The people who care for optimization much will learn 
 about `sealed` and be able to apply the concept in both cases. The people 
 who don't care about performance will just be disappointed by the 
 "implicitly sealed" behavior. And with this proposal, when I read 
 `unsealed` I can never know: "did this developer intend me to be able to 
 subclass this class? or did he just not want to restrict me 
 unnecessarily?" The documenting aspect of `unsealed` is so small.
 
 And `sealed` is just an optimization; IMHO the magic of static dispatch 
 lies in final classes or final methods. Sealing everything by default just 
 marks many classes and methods as implicitly final (because it can be 
 proven that they are not subclassed). I just don't think that all these 
 theoretical performance improvements are really worth the trouble in 
 practice.
>>> 
>>> I'm confused about why you think this is so much of a problem.  Do you 
>>> really anticipate writing so many Swift libraries with public classes?
>> 
>> Look at some of the public libs on github for server side swift.. one 
>> recently claimed 50 modules and counting... I think swift is missing a level 
>> of containment below modules, and people are starting to make up for it by 
>> creating a flury of (1class+1protocol) modules, especially now that package 
>> manager makes it so trivial to create them. I think this is only the 
>> begining... and nodejs is there to show how insane it could become:  
>> remember the recent "trimleft" nightmare (1 module with 15 LOC including 
>> brackets used pervasively that suddenly disapears).
> 
> I'm not arguing that there aren't going to be a lot of libraries.  We're all 
> excited about the number of libraries.  Libraries are great.  

The issue is that according to this year's very interesting talk on perf is 
that an app's startup time can get thrown over the limit by having to perform 
too much relocation during dylib loading. I doubt too many will actually pay 
attention (i just started a nodejs app a couple days ago and before it did 
anything, bringing in angular and a few other dependencies downloaded 168M in 
over 60 modules)

> I'm trying to understand whether the objections here — which only matter on 
> library boundaries — are motivated by any concrete experience writing such 
> libraries in Swift.
> 
> Michael's argument was that sealed-by-default will be a major problem for 
> those libraries and their users.  Let's suppose that there's a library with a 
> public class, and it's sealed by default.  We can conclude that the author 
> has never once tried to subclass this class outside of their library, because 
> if they had, they would have gotten a compiler error.  Therefore, at best, if 
> I hack the library to allow subclasses, I'm going to be doing something that 
> has never once been tested and certainly was not considered when the class 
> was written.  It's pretty clear that this is not the developer's intent.

I think that you r considering an already sophisticated developer to whom you 
attribute the thought of 'whats it gonna be to use my code'. compared to the 
real life i know. That said I spent some time thinking about your arguments and 
I guess i can live with sealed (

> Likewise, it's not true that "the documenting aspect of `unsealed` is so 
> small".  Under sealed-by-default, the developer has to make a conscious, 
> deliberate step to allow subclasses outside of their library.  They clearly 
> do intend for you to be able to subclass this class.  It's actually the 
> reverse situation where the user doesn't know how to interpret the code,

I believe most devs are not able to accurately predict what their code does and 
will allow to do be done. Over the last 20 years i have usually seen the most 
creative solutions being found despite what the original library writers did, 
but it is just my personal exp. i would prefer a world without forking 
dependencies, but... 

But i think you best argument is that idiomatic swift should not rely on 
classes as much as other languages. So in the end, the applicability will 
become 

Re: [swift-evolution] [Proposal] Sealed classes by default

2016-07-02 Thread T.J. Usiyan via swift-evolution
+1 to sealed
+1 to sealed-as-default.

I prefer the need to explicitly share details that I would like to share.
Separately, I do think that we need to improve the tools for auditing and
organizing APIs.

On Sat, Jul 2, 2016 at 8:35 AM, L. Mihalkovic via swift-evolution <
swift-evolution@swift.org> wrote:

> Inline
> Regards
> (From mobile)
>
> On Jul 2, 2016, at 10:51 AM, Brent Royal-Gordon 
> wrote:
>
> >> On Jul 2, 2016, at 12:42 AM, L. Mihalkovic <
> laurent.mihalko...@gmail.com> wrote:
> >>
> >> This is a situation I often run into in jave where I would use an enum
> to create a finite set of constants to be passed (say action identifers).
> But then this makes it very difficult for external modules to extend the
> core set of actions locally. So i generally windup with an enum and an
> interface (the enum implements the interface).
> >
> > Sure. I would argue that that's the exact right approach to take for
> this kind of thing. For instance, for storyboard segue identifiers, I would
> write something like this:
> >
> >open protocol SegueIdentifierProtocol: RawRepresentable where
> RawValue == String {}
> >
> >open protocol SeguePerformable {
> >associatedtype SegueIdentifier: SegueIdentifierProtocol
> >
> >// Hooks
> >func shouldPerformSegue(with identifier: SegueIdentifier, sender:
> AnyObject?) -> Bool
> >func prepare(for segue: UIStoryboardSegue, with identifier:
> SegueIdentifier, sender: AnyObject?)
> >}
> >
> >public extension SeguePerformable where Self: UIViewController {
> >// Machinery to bridge to normal UIViewController API
> >
> >func performSegue(with identifier: SegueIdentifier, sender:
> AnyObject?) {...}
> >override func shouldPerformSegue(withIdentifier identifier:
> String, sender: AnyObject?) -> Bool {...}
> >override func prepare(for segue: UIStoryboardSegue, sender:
> AnyObject?) {...}
> >}
> >
> > Rather than attempting some sort of universal enum of all identifiers:
> >
> >extension UIViewController {
> >open enum SegueIdentifier: String {
> >// Extensible for users
> >}
> >
> >// Hooks
> >open func shouldPerformSegue(with identifier: SegueIdentifier,
> sender: AnyObject?) -> Bool {...}
> >open func prepare(for segue: UIStoryboardSegue, with identifier:
> SegueIdentifier, sender: AnyObject?) {...}
> >
> >// Machinery to bridge to normal UIViewController API
> >public func performSegue(with identifier: SegueIdentifier,
> sender: AnyObject?) {...}
> >override public func shouldPerformSegue(withIdentifier
> identifier: String, sender: AnyObject?) -> Bool {...}
> >override public func prepare(for segue: UIStoryboardSegue,
> sender: AnyObject?) {...}
> >}
> >
> >> Then local extensions are free to define their own local enums to cover
> only their local extensions to the original core set of actions. Then the
> public api definition constrains the action parameter to be
> enum
> >
> > Okay, but why constrain it to `enum`? Do you actually care that it's an
> `enum`, or do you just care that there's a type which can give you the
> identifier you need? If somebody wrote a highly dynamic client of your code
> that needed to generate identifiers on the fly, why should your code reject
> that?
>
> In the case of a segway id (i did watch the wwdc presentation last year
> too) the protocol representation is IMHO more a pedentic exercise in 'look
> how pretty i can make my code' than an actual technical necessity
> (considering people have been writing the same apps in objc for years,
> their argument of 'avoiding mismatch' did not hold much water when
> considering the scale we are talking about).
>
> I was refering to real life systems (think state machine-like libraries
> for eg) where having access to the complete set carries a real value. For
> some, dealing with multiple disjointed sets is a minor hickup, for others a
> real feature. The point is i am describing carefully designed real life
> (many trading) systems for which i truly care about every piece of what i
> described for various reasons (be it size/modularity 400KLOC+ systems,
> bytecode level efficiency of enums as Hash keys,  ). At this point none
> of these systems could be done in swift yet due to small gaps here and
> there (of course they could technically be rewritten in cobol if need be,
> but at a tremendous loss):
> * can't constrain on enum (what's worse is Dave is not even convinced
> there is any case for it)
> * can't easily discover all cases
> * can't annotate enum case with meta information making runtime adaptation
> possible
> ...
>
> Maybe the gap will never close and java/scala/kotlin/ceylon will remain
> the languages of choice for the real life servers of this world. An
> interesting question might be: what to do when a phonegap app written in
> typescript is much more expressive than its swift 

Re: [swift-evolution] [Proposal] Sealed classes by default

2016-07-02 Thread Brent Royal-Gordon via swift-evolution
> On Jul 2, 2016, at 12:42 AM, L. Mihalkovic  
> wrote:
> 
> This is a situation I often run into in jave where I would use an enum to 
> create a finite set of constants to be passed (say action identifers). But 
> then this makes it very difficult for external modules to extend the core set 
> of actions locally. So i generally windup with an enum and an interface (the 
> enum implements the interface).

Sure. I would argue that that's the exact right approach to take for this kind 
of thing. For instance, for storyboard segue identifiers, I would write 
something like this:

open protocol SegueIdentifierProtocol: RawRepresentable where RawValue 
== String {}

open protocol SeguePerformable {
associatedtype SegueIdentifier: SegueIdentifierProtocol

// Hooks
func shouldPerformSegue(with identifier: SegueIdentifier, 
sender: AnyObject?) -> Bool
func prepare(for segue: UIStoryboardSegue, with identifier: 
SegueIdentifier, sender: AnyObject?)
}

public extension SeguePerformable where Self: UIViewController {
// Machinery to bridge to normal UIViewController API

func performSegue(with identifier: SegueIdentifier, sender: 
AnyObject?) {...}
override func shouldPerformSegue(withIdentifier identifier: 
String, sender: AnyObject?) -> Bool {...}
override func prepare(for segue: UIStoryboardSegue, sender: 
AnyObject?) {...}
}

Rather than attempting some sort of universal enum of all identifiers:

extension UIViewController {
open enum SegueIdentifier: String {
// Extensible for users
}

// Hooks
open func shouldPerformSegue(with identifier: SegueIdentifier, 
sender: AnyObject?) -> Bool {...}
open func prepare(for segue: UIStoryboardSegue, with 
identifier: SegueIdentifier, sender: AnyObject?) {...}

// Machinery to bridge to normal UIViewController API
public func performSegue(with identifier: SegueIdentifier, 
sender: AnyObject?) {...}
override public func shouldPerformSegue(withIdentifier 
identifier: String, sender: AnyObject?) -> Bool {...}
override public func prepare(for segue: UIStoryboardSegue, 
sender: AnyObject?) {...}
}

> Then local extensions are free to define their own local enums to cover only 
> their local extensions to the original core set of actions. Then the public 
> api definition constrains the action parameter to be 
> enum

Okay, but why constrain it to `enum`? Do you actually care that it's an `enum`, 
or do you just care that there's a type which can give you the identifier you 
need? If somebody wrote a highly dynamic client of your code that needed to 
generate identifiers on the fly, why should your code reject that?

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] [Proposal] Sealed classes by default

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


Regards
(From mobile)

On Jul 1, 2016, at 6:43 PM, John McCall via swift-evolution 
 wrote:

>>> On Jul 1, 2016, at 2:08 AM, Brent Royal-Gordon  
>>> wrote:
>>> That starts to look an awful lot like a fifth access level just for classes 
>>> (I know you're not proposing one, but it could start to look that way to a 
>>> user).
>> 
>> You know, it *could* be.
>> 
>> Suppose that, in `internal` scope, you can do all of these things:
>> 
>> * Subclass a class.
>> * Add a case to an enum in an extension.[1]
>> * Add a stored property to a struct in an extension.
>> * Conform to a protocol (as opposed to just using and constraining with the 
>> existing conformances).
>> * Override an individual initializer, property, subscript, or method in an 
>> extension or subclass.[2]
>> 
>> But `public` does not permit them. You can *use* something that is public, 
>> but you can't extend it. `open`, on the other hand, *does* allow you to 
>> extend them. It means that outside code has (about) as much freedom to 
>> extend the `open` item as code inside your module does.
>> 
>> This approach would allow us to make the "sealing" very tight—if you changed 
>> a class from `public` to `open`, all of its `public` members would still be 
>> sealed—without actually making that a heavy burden on programmers who want 
>> things unsealed.
> 
> Yes, this is the way I've been thinking about it.
> 
>> This also suggests that perhaps `final` is best thought of as foreclosing 
>> the things that `open` permits, either within a module or in future versions:
>> 
>> * A `final` class can never be subclassed.
>> * A `final` enum can never have cases added.
>> * A `final` struct can never have stored properties added.
>> * A `final` protocol...well, okay, that one's pretty useless. Maybe there 
>> just aren't `final` protocols.[3]
>> * A `final` property, subscript, or method can never be overridden.
>> 
>> A `final` thing would be fast both inside and outside the module, because it 
>> would have guarantees about its size/dynamic type/implementation; an `open` 
>> thing would be slow both inside and outside, because it would have no such 
>> guarantees; and a non-`final`, non-`open` thing would be slow externally but 
>> fast internally.
> 
> This is an interesting thought.  Its application to 'struct', though, seems a 
> bit strange, since 'final' on classes doesn't remove the ability for the 
> module to change the stored properties (and clearly we wouldn't want it to do 
> so).
> 
>> [1] There's another thread floating around where I've seen people suggest 
>> that enums could never be open because you couldn't unique integer raw 
>> values to each case. I think that's a rather narrow view of what an enum is 
>> for; many, perhaps most, enums don't need raw values, and even those that do 
>> could support string raw values with little danger.
> 
> If we know that an enum needs to be extensible, we can leave room in its 
> implementation for cases with arbitrary associated values.  This isn't a 
> problem.
> 
> Raw values are perhaps different.

This is a situation I often run into in jave where I would use an enum to 
create a finite set of constants to be passed (say action identifers). But then 
this makes it very difficult for external modules to extend the core set of 
actions locally. So i generally windup with an enum and an interface (the enum 
implements the interface).
Then local extensions are free to define their own local enums to cover only 
their local extensions to the original core set of actions. Then the public api 
definition constrains the action parameter to be enum In 
the end this is a pattern I've come to like because tracing usage of the 
interface I can find all subsequent entensions to the core set of actions. Each 
subsequent set of extensions is just that: its own closed enum showing that 
they all form a coherent namespace for that extension (being a different enum 
than my original set, they do not prevent me extending the core set without 
risking name collisions with their extensions). The only cost is the heavier 
api declation site signature that is wearing the double enum & interface 
constraint.
The point is that you can extend enums without have to open them, and the 
resulting pattern may be even better than if you open the enum. The only 
hickup. Swift does not let you express

protocol Command{}
func myCommand Handler{}


>> [2] You can't currently override a member in an extension, but I think that 
>> would be essential for initializing extension stored properties and 
>> especially for adding cases to enums (you'd want to override members to 
>> handle your cases).
> 
> Yes, I think allowing extensions to override members is an eventual goal.  It 
> needs runtime support, though, and some careful language design.
> 
>> [3] Or maybe a `final` protocol can't be conformed to directly, but only 
>> through a sub-protocol (which could only 

Re: [swift-evolution] [Proposal] Sealed classes by default

2016-07-01 Thread Ben Rimmington via swift-evolution

> On 1 Jul 2016, at 17:47, John McCall wrote:
> 
> I don't think we'd ever use a compound keyword that starts with public; 
> we'd just separate them and say that the second half can only be present 
> on a public declaration, or do this parenthesized syntax.

The `super` keyword could be reused:

public super class ParentClass {
public   func foo() { }
public super func bar() { }
public final func baz() { }
}

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


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-07-01 Thread Jose Cheyo Jimenez via swift-evolution
I almost sent out an email with what you wrote. 

how about `public( nonfinal )`

> - use “public(nonfinal)” to mean “exported out of the module, 
> subclass/overridable”

I think just `open` would be a little bit better. `public( open )`



> On Jul 1, 2016, at 11:20 AM, Sean Heber via swift-evolution 
>  wrote:
> 
> Ok, I suppose that this design *basically* undoes the sealed by default 
> thing, doesn’t it? :P  lol. One of those days, I guess..
> 
> Sigh.
> 
> Crawling away…
> 
> l8r
> Sean
> 
> 
>> On Jul 1, 2016, at 1:16 PM, Sean Heber  wrote:
>> 
>> Coming in late on this, but here’s my take guided by the principal of least 
>> surprise (according to me):
>> 
>> - everything is sealed within its module by default, no keyword
>> - use “public” to mean “exported out of the module, subclass/overridable”
>> - use “public(final)” to mean “exported out of the module, no subclassing or 
>> overriding externally, but overriding and subclasses allowed internally”
>> - meaning of “final” does not change
>> - using “public final” then means the same as both public(final) and also 
>> “final” internal to the module
>> - using “public(final) final” could be presented as an error with fixit 
>> since it’s redundant
>> 
>> Did I miss anything?
>> 
>> l8r
>> Sean
>> 
>> 
>> 
>>> On Jul 1, 2016, at 12:53 PM, John McCall via swift-evolution 
>>>  wrote:
>>> 
 On Jul 1, 2016, at 10:51 AM, Michael Ilseman  wrote:
 If “opened”, who or what did the opening? If “open” is like “extensible”, 
 then I would interpret “opened” to be like “extended”.
>>> 
>>> Yeah, I would prefer "open" to "opened".
>>> 
>>> John.
>>> 
 
> On Jul 1, 2016, at 10:35 AM, Leonardo Pessoa via swift-evolution 
>  wrote:
> 
> The proposal was to use "sealed" so why not "opened"? I understand it
> may not be common to use "opened" as an adjective but from the
> dictionaries I consulted it is possible to.
> 
> opened class MyViewController: UIViewController {
>   opened func displayMe(_ me: person) { … }
> }
> 
> On 1 July 2016 at 13:47, John McCall via swift-evolution
>  wrote:
>> On Jul 1, 2016, at 12:23 AM, Xiaodi Wu  wrote:
>> That starts to look an awful lot like a fifth access level just for 
>> classes
>> (I know you're not proposing one, but it could start to look that way to 
>> a
>> user). I think there's much to be said for having the word public in 
>> front
>> of things that are public. Unless, of course, your strawman keyword is a
>> much maligned compound word that begins with "public", like
>> "publicoverridable".
>> 
>> 
>> I would also prefer a single keyword if the word implies something about
>> accessibility.  "open" does that, although using it here would conflict 
>> with
>> its potential use on enums unless we required all cases within the 
>> defining
>> module to be present in the enum declaration rather than extensions.
>> 
>> I don't think we'd ever use a compound keyword that starts with public; 
>> we'd
>> just separate them and say that the second half can only be present on a
>> public declaration, or do this parenthesized syntax.
>> 
>> John.
>> 
>> 
>> On Fri, Jul 1, 2016 at 01:54 Brent Royal-Gordon 
>> wrote:
>>> 
 If we're going to go along those lines, we should just use
 public(subclassable) and public(overridable).  We can fall back on 
 those if
 necessary; I would just like to continue looking for better 
 alternatives.
>>> 
>>> I would prefer to have a *single* keyword which meant both public and
>>> overridable. That would minimize the impact of this feature—instead of
>>> writing:
>>> 
>>>public class MyViewController: UIViewController {
>>>public func displayMe(_ me: person) { … }
>>>}
>>> 
>>> You'd write (strawman keyword):
>>> 
>>>openseason class MyViewController: UIViewController {
>>>openseason func displayMe(_ me: person) { … }
>>>}
>>> 
>>> And then `MyViewController` could be subclassed, and `displayMe`
>>> overridden.
>>> 
>>> --
>>> Brent Royal-Gordon
>>> Architechies
>>> 
>> 
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
 
>>> 
>>> ___
>>> swift-evolution mailing list
>>> 

Re: [swift-evolution] [Proposal] Sealed classes by default

2016-07-01 Thread Sean Heber via swift-evolution
Ok, I suppose that this design *basically* undoes the sealed by default thing, 
doesn’t it? :P  lol. One of those days, I guess..

Sigh.

Crawling away…

l8r
Sean


> On Jul 1, 2016, at 1:16 PM, Sean Heber  wrote:
> 
> Coming in late on this, but here’s my take guided by the principal of least 
> surprise (according to me):
> 
> - everything is sealed within its module by default, no keyword
> - use “public” to mean “exported out of the module, subclass/overridable”
> - use “public(final)” to mean “exported out of the module, no subclassing or 
> overriding externally, but overriding and subclasses allowed internally”
> - meaning of “final” does not change
> - using “public final” then means the same as both public(final) and also 
> “final” internal to the module
> - using “public(final) final” could be presented as an error with fixit since 
> it’s redundant
> 
> Did I miss anything?
> 
> l8r
> Sean
> 
> 
> 
>> On Jul 1, 2016, at 12:53 PM, John McCall via swift-evolution 
>>  wrote:
>> 
>>> On Jul 1, 2016, at 10:51 AM, Michael Ilseman  wrote:
>>> If “opened”, who or what did the opening? If “open” is like “extensible”, 
>>> then I would interpret “opened” to be like “extended”.
>> 
>> Yeah, I would prefer "open" to "opened".
>> 
>> John.
>> 
>>> 
 On Jul 1, 2016, at 10:35 AM, Leonardo Pessoa via swift-evolution 
  wrote:
 
 The proposal was to use "sealed" so why not "opened"? I understand it
 may not be common to use "opened" as an adjective but from the
 dictionaries I consulted it is possible to.
 
 opened class MyViewController: UIViewController {
opened func displayMe(_ me: person) { … }
 }
 
 On 1 July 2016 at 13:47, John McCall via swift-evolution
  wrote:
> On Jul 1, 2016, at 12:23 AM, Xiaodi Wu  wrote:
> That starts to look an awful lot like a fifth access level just for 
> classes
> (I know you're not proposing one, but it could start to look that way to a
> user). I think there's much to be said for having the word public in front
> of things that are public. Unless, of course, your strawman keyword is a
> much maligned compound word that begins with "public", like
> "publicoverridable".
> 
> 
> I would also prefer a single keyword if the word implies something about
> accessibility.  "open" does that, although using it here would conflict 
> with
> its potential use on enums unless we required all cases within the 
> defining
> module to be present in the enum declaration rather than extensions.
> 
> I don't think we'd ever use a compound keyword that starts with public; 
> we'd
> just separate them and say that the second half can only be present on a
> public declaration, or do this parenthesized syntax.
> 
> John.
> 
> 
> On Fri, Jul 1, 2016 at 01:54 Brent Royal-Gordon 
> wrote:
>> 
>>> If we're going to go along those lines, we should just use
>>> public(subclassable) and public(overridable).  We can fall back on 
>>> those if
>>> necessary; I would just like to continue looking for better 
>>> alternatives.
>> 
>> I would prefer to have a *single* keyword which meant both public and
>> overridable. That would minimize the impact of this feature—instead of
>> writing:
>> 
>> public class MyViewController: UIViewController {
>> public func displayMe(_ me: person) { … }
>> }
>> 
>> You'd write (strawman keyword):
>> 
>> openseason class MyViewController: UIViewController {
>> openseason func displayMe(_ me: person) { … }
>> }
>> 
>> And then `MyViewController` could be subclassed, and `displayMe`
>> overridden.
>> 
>> --
>> Brent Royal-Gordon
>> Architechies
>> 
> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
 ___
 swift-evolution mailing list
 swift-evolution@swift.org
 https://lists.swift.org/mailman/listinfo/swift-evolution
>>> 
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 

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


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-07-01 Thread Sean Heber via swift-evolution
Coming in late on this, but here’s my take guided by the principal of least 
surprise (according to me):

- everything is sealed within its module by default, no keyword
- use “public” to mean “exported out of the module, subclass/overridable”
- use “public(final)” to mean “exported out of the module, no subclassing or 
overriding externally, but overriding and subclasses allowed internally”
- meaning of “final” does not change
- using “public final” then means the same as both public(final) and also 
“final” internal to the module
- using “public(final) final” could be presented as an error with fixit since 
it’s redundant

Did I miss anything?

l8r
Sean



> On Jul 1, 2016, at 12:53 PM, John McCall via swift-evolution 
>  wrote:
> 
>> On Jul 1, 2016, at 10:51 AM, Michael Ilseman  wrote:
>> If “opened”, who or what did the opening? If “open” is like “extensible”, 
>> then I would interpret “opened” to be like “extended”.
> 
> Yeah, I would prefer "open" to "opened".
> 
> John.
> 
>> 
>>> On Jul 1, 2016, at 10:35 AM, Leonardo Pessoa via swift-evolution 
>>>  wrote:
>>> 
>>> The proposal was to use "sealed" so why not "opened"? I understand it
>>> may not be common to use "opened" as an adjective but from the
>>> dictionaries I consulted it is possible to.
>>> 
>>> opened class MyViewController: UIViewController {
>>> opened func displayMe(_ me: person) { … }
>>> }
>>> 
>>> On 1 July 2016 at 13:47, John McCall via swift-evolution
>>>  wrote:
 On Jul 1, 2016, at 12:23 AM, Xiaodi Wu  wrote:
 That starts to look an awful lot like a fifth access level just for classes
 (I know you're not proposing one, but it could start to look that way to a
 user). I think there's much to be said for having the word public in front
 of things that are public. Unless, of course, your strawman keyword is a
 much maligned compound word that begins with "public", like
 "publicoverridable".
 
 
 I would also prefer a single keyword if the word implies something about
 accessibility.  "open" does that, although using it here would conflict 
 with
 its potential use on enums unless we required all cases within the defining
 module to be present in the enum declaration rather than extensions.
 
 I don't think we'd ever use a compound keyword that starts with public; 
 we'd
 just separate them and say that the second half can only be present on a
 public declaration, or do this parenthesized syntax.
 
 John.
 
 
 On Fri, Jul 1, 2016 at 01:54 Brent Royal-Gordon 
 wrote:
> 
>> If we're going to go along those lines, we should just use
>> public(subclassable) and public(overridable).  We can fall back on those 
>> if
>> necessary; I would just like to continue looking for better alternatives.
> 
> I would prefer to have a *single* keyword which meant both public and
> overridable. That would minimize the impact of this feature—instead of
> writing:
> 
>  public class MyViewController: UIViewController {
>  public func displayMe(_ me: person) { … }
>  }
> 
> You'd write (strawman keyword):
> 
>  openseason class MyViewController: UIViewController {
>  openseason func displayMe(_ me: person) { … }
>  }
> 
> And then `MyViewController` could be subclassed, and `displayMe`
> overridden.
> 
> --
> Brent Royal-Gordon
> Architechies
> 
 
 
 ___
 swift-evolution mailing list
 swift-evolution@swift.org
 https://lists.swift.org/mailman/listinfo/swift-evolution
 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-07-01 Thread Leonardo Pessoa via swift-evolution
The proposal was to use "sealed" so why not "opened"? I understand it
may not be common to use "opened" as an adjective but from the
dictionaries I consulted it is possible to.

opened class MyViewController: UIViewController {
   opened func displayMe(_ me: person) { … }
}

On 1 July 2016 at 13:47, John McCall via swift-evolution
 wrote:
> On Jul 1, 2016, at 12:23 AM, Xiaodi Wu  wrote:
> That starts to look an awful lot like a fifth access level just for classes
> (I know you're not proposing one, but it could start to look that way to a
> user). I think there's much to be said for having the word public in front
> of things that are public. Unless, of course, your strawman keyword is a
> much maligned compound word that begins with "public", like
> "publicoverridable".
>
>
> I would also prefer a single keyword if the word implies something about
> accessibility.  "open" does that, although using it here would conflict with
> its potential use on enums unless we required all cases within the defining
> module to be present in the enum declaration rather than extensions.
>
> I don't think we'd ever use a compound keyword that starts with public; we'd
> just separate them and say that the second half can only be present on a
> public declaration, or do this parenthesized syntax.
>
> John.
>
>
> On Fri, Jul 1, 2016 at 01:54 Brent Royal-Gordon 
> wrote:
>>
>> > If we're going to go along those lines, we should just use
>> > public(subclassable) and public(overridable).  We can fall back on those if
>> > necessary; I would just like to continue looking for better alternatives.
>>
>> I would prefer to have a *single* keyword which meant both public and
>> overridable. That would minimize the impact of this feature—instead of
>> writing:
>>
>> public class MyViewController: UIViewController {
>> public func displayMe(_ me: person) { … }
>> }
>>
>> You'd write (strawman keyword):
>>
>> openseason class MyViewController: UIViewController {
>> openseason func displayMe(_ me: person) { … }
>> }
>>
>> And then `MyViewController` could be subclassed, and `displayMe`
>> overridden.
>>
>> --
>> Brent Royal-Gordon
>> Architechies
>>
>
>
> ___
> 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] [Proposal] Sealed classes by default

2016-07-01 Thread John McCall via swift-evolution
> On Jul 1, 2016, at 12:23 AM, Xiaodi Wu  wrote:
> That starts to look an awful lot like a fifth access level just for classes 
> (I know you're not proposing one, but it could start to look that way to a 
> user). I think there's much to be said for having the word public in front of 
> things that are public. Unless, of course, your strawman keyword is a much 
> maligned compound word that begins with "public", like "publicoverridable".

I would also prefer a single keyword if the word implies something about 
accessibility.  "open" does that, although using it here would conflict with 
its potential use on enums unless we required all cases within the defining 
module to be present in the enum declaration rather than extensions.

I don't think we'd ever use a compound keyword that starts with public; we'd 
just separate them and say that the second half can only be present on a public 
declaration, or do this parenthesized syntax.

John.


> On Fri, Jul 1, 2016 at 01:54 Brent Royal-Gordon  > wrote:
> > If we're going to go along those lines, we should just use 
> > public(subclassable) and public(overridable).  We can fall back on those if 
> > necessary; I would just like to continue looking for better alternatives.
> 
> I would prefer to have a *single* keyword which meant both public and 
> overridable. That would minimize the impact of this feature—instead of 
> writing:
> 
> public class MyViewController: UIViewController {
> public func displayMe(_ me: person) { … }
> }
> 
> You'd write (strawman keyword):
> 
> openseason class MyViewController: UIViewController {
> openseason func displayMe(_ me: person) { … }
> }
> 
> And then `MyViewController` could be subclassed, and `displayMe` overridden.
> 
> --
> Brent Royal-Gordon
> Architechies
> 

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


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-07-01 Thread John McCall via swift-evolution
> On Jul 1, 2016, at 2:08 AM, Brent Royal-Gordon  wrote:
>> That starts to look an awful lot like a fifth access level just for classes 
>> (I know you're not proposing one, but it could start to look that way to a 
>> user).
> 
> You know, it *could* be.
> 
> Suppose that, in `internal` scope, you can do all of these things:
> 
> * Subclass a class.
> * Add a case to an enum in an extension.[1]
> * Add a stored property to a struct in an extension.
> * Conform to a protocol (as opposed to just using and constraining with the 
> existing conformances).
> * Override an individual initializer, property, subscript, or method in an 
> extension or subclass.[2]
> 
> But `public` does not permit them. You can *use* something that is public, 
> but you can't extend it. `open`, on the other hand, *does* allow you to 
> extend them. It means that outside code has (about) as much freedom to extend 
> the `open` item as code inside your module does.
> 
> This approach would allow us to make the "sealing" very tight—if you changed 
> a class from `public` to `open`, all of its `public` members would still be 
> sealed—without actually making that a heavy burden on programmers who want 
> things unsealed.

Yes, this is the way I've been thinking about it.

> This also suggests that perhaps `final` is best thought of as foreclosing the 
> things that `open` permits, either within a module or in future versions:
> 
> * A `final` class can never be subclassed.
> * A `final` enum can never have cases added.
> * A `final` struct can never have stored properties added.
> * A `final` protocol...well, okay, that one's pretty useless. Maybe there 
> just aren't `final` protocols.[3]
> * A `final` property, subscript, or method can never be overridden.
> 
> A `final` thing would be fast both inside and outside the module, because it 
> would have guarantees about its size/dynamic type/implementation; an `open` 
> thing would be slow both inside and outside, because it would have no such 
> guarantees; and a non-`final`, non-`open` thing would be slow externally but 
> fast internally.

This is an interesting thought.  Its application to 'struct', though, seems a 
bit strange, since 'final' on classes doesn't remove the ability for the module 
to change the stored properties (and clearly we wouldn't want it to do so).

> [1] There's another thread floating around where I've seen people suggest 
> that enums could never be open because you couldn't unique integer raw values 
> to each case. I think that's a rather narrow view of what an enum is for; 
> many, perhaps most, enums don't need raw values, and even those that do could 
> support string raw values with little danger.

If we know that an enum needs to be extensible, we can leave room in its 
implementation for cases with arbitrary associated values.  This isn't a 
problem.

Raw values are perhaps different.

> [2] You can't currently override a member in an extension, but I think that 
> would be essential for initializing extension stored properties and 
> especially for adding cases to enums (you'd want to override members to 
> handle your cases).

Yes, I think allowing extensions to override members is an eventual goal.  It 
needs runtime support, though, and some careful language design.

> [3] Or maybe a `final` protocol can't be conformed to directly, but only 
> through a sub-protocol (which could only be defined within the module). That 
> would allow arrangements like "Sequence is the parent protocol of both 
> IteratorProtocol and Collection, but all Sequences must conform to one of 
> those sub-protocols".

It's okay for a modifier to not have meaning for absolutely everything. :)

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


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-07-01 Thread Brent Royal-Gordon via swift-evolution
> That starts to look an awful lot like a fifth access level just for classes 
> (I know you're not proposing one, but it could start to look that way to a 
> user).

You know, it *could* be.

Suppose that, in `internal` scope, you can do all of these things:

* Subclass a class.
* Add a case to an enum in an extension.[1]
* Add a stored property to a struct in an extension.
* Conform to a protocol (as opposed to just using and constraining with the 
existing conformances).
* Override an individual initializer, property, subscript, or method in an 
extension or subclass.[2]

But `public` does not permit them. You can *use* something that is public, but 
you can't extend it. `open`, on the other hand, *does* allow you to extend 
them. It means that outside code has (about) as much freedom to extend the 
`open` item as code inside your module does.

This approach would allow us to make the "sealing" very tight—if you changed a 
class from `public` to `open`, all of its `public` members would still be 
sealed—without actually making that a heavy burden on programmers who want 
things unsealed.

This also suggests that perhaps `final` is best thought of as foreclosing the 
things that `open` permits, either within a module or in future versions:

* A `final` class can never be subclassed.
* A `final` enum can never have cases added.
* A `final` struct can never have stored properties added.
* A `final` protocol...well, okay, that one's pretty useless. Maybe there just 
aren't `final` protocols.[3]
* A `final` property, subscript, or method can never be overridden.

A `final` thing would be fast both inside and outside the module, because it 
would have guarantees about its size/dynamic type/implementation; an `open` 
thing would be slow both inside and outside, because it would have no such 
guarantees; and a non-`final`, non-`open` thing would be slow externally but 
fast internally.



[1] There's another thread floating around where I've seen people suggest that 
enums could never be open because you couldn't unique integer raw values to 
each case. I think that's a rather narrow view of what an enum is for; many, 
perhaps most, enums don't need raw values, and even those that do could support 
string raw values with little danger.

[2] You can't currently override a member in an extension, but I think that 
would be essential for initializing extension stored properties and especially 
for adding cases to enums (you'd want to override members to handle your 
cases). 

[3] Or maybe a `final` protocol can't be conformed to directly, but only 
through a sub-protocol (which could only be defined within the module). That 
would allow arrangements like "Sequence is the parent protocol of both 
IteratorProtocol and Collection, but all Sequences must conform to one of those 
sub-protocols".

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-07-01 Thread Xiaodi Wu via swift-evolution
That starts to look an awful lot like a fifth access level just for classes
(I know you're not proposing one, but it could start to look that way to a
user). I think there's much to be said for having the word public in front
of things that are public. Unless, of course, your strawman keyword is a
much maligned compound word that begins with "public", like
"publicoverridable".
On Fri, Jul 1, 2016 at 01:54 Brent Royal-Gordon 
wrote:

> > If we're going to go along those lines, we should just use
> public(subclassable) and public(overridable).  We can fall back on those if
> necessary; I would just like to continue looking for better alternatives.
>
> I would prefer to have a *single* keyword which meant both public and
> overridable. That would minimize the impact of this feature—instead of
> writing:
>
> public class MyViewController: UIViewController {
> public func displayMe(_ me: person) { … }
> }
>
> You'd write (strawman keyword):
>
> openseason class MyViewController: UIViewController {
> openseason func displayMe(_ me: person) { … }
> }
>
> And then `MyViewController` could be subclassed, and `displayMe`
> overridden.
>
> --
> Brent Royal-Gordon
> Architechies
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-07-01 Thread Brent Royal-Gordon via swift-evolution
> If we're going to go along those lines, we should just use 
> public(subclassable) and public(overridable).  We can fall back on those if 
> necessary; I would just like to continue looking for better alternatives.

I would prefer to have a *single* keyword which meant both public and 
overridable. That would minimize the impact of this feature—instead of writing:

public class MyViewController: UIViewController {
public func displayMe(_ me: person) { … }
}

You'd write (strawman keyword):

openseason class MyViewController: UIViewController {
openseason func displayMe(_ me: person) { … }
}

And then `MyViewController` could be subclassed, and `displayMe` overridden.

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-30 Thread John McCall via swift-evolution
> On Jun 30, 2016, at 1:44 PM, Xiaodi Wu  wrote:
> On Thu, Jun 30, 2016 at 3:36 PM, John McCall  > wrote:
>> On Jun 29, 2016, at 1:33 PM, Xiaodi Wu > > wrote:
>> On Wed, Jun 29, 2016 at 2:54 PM, John McCall via swift-evolution 
>> > wrote:
>> > On Jun 29, 2016, at 11:39 AM, Vladimir.S > > > wrote:
>> > How about `public(extensible)` ?
>> 
>> Hmm.  I started to work out an example with these as separate modifiers, and 
>> I think I understand the need to combine them in some way.
>> 
>> I wonder if just "extensible" would be good enough.  It is a term that's 
>> used in API descriptions.
>> 
>> This particular word is unfortunate because it has nothing to do with an 
>> extension, which shares the same etymological root.
> 
> I agree, but I'm not sure that it's particularly confusing in practice.
>  
> Why not just "inheritable"? That is, after all, what we mean, no?

All class methods are intrinsically inheritable.  A non-inheritable method 
would *require* an override.

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


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-30 Thread Xiaodi Wu via swift-evolution
On Thu, Jun 30, 2016 at 3:36 PM, John McCall  wrote:

> On Jun 29, 2016, at 1:33 PM, Xiaodi Wu  wrote:
> On Wed, Jun 29, 2016 at 2:54 PM, John McCall via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> > On Jun 29, 2016, at 11:39 AM, Vladimir.S  wrote:
>> > How about `public(extensible)` ?
>>
>> Hmm.  I started to work out an example with these as separate modifiers,
>> and I think I understand the need to combine them in some way.
>>
>> I wonder if just "extensible" would be good enough.  It is a term that's
>> used in API descriptions.
>>
>
> This particular word is unfortunate because it has nothing to do with an
> extension, which shares the same etymological root.
>
>
> I agree, but I'm not sure that it's particularly confusing in practice.
>

Why not just "inheritable"? That is, after all, what we mean, no?

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


Re: [swift-evolution] [Proposal] Sealed classes by default

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


Sent from my iPad

On Jun 30, 2016, at 1:15 PM, John McCall via swift-evolution 
 wrote:

>>> On Jun 30, 2016, at 11:07 AM, Andrew Trick  wrote:
 On Jun 30, 2016, at 1:21 AM, John McCall via swift-evolution 
  wrote:
 
> On Jun 29, 2016, at 10:17 PM, L. Mihalkovic 
>  wrote:
> On Jun 29, 2016, at 8:39 PM, Vladimir.S via swift-evolution 
>  wrote:
> 
> How about `public(extensible)` ?
> 
> On 29.06.2016 21:32, John McCall via swift-evolution wrote:
>>> On Jun 29, 2016, at 11:16 AM, Michael Peternell via swift-evolution 
>>>  wrote:
>>> Do you mean `public(unsealed)`? Because `internal(unsealed)` doesn't 
>>> really make sense. `internal` declarations are always sealed.
>> 
>> Right.
>> 
>> If "sealed" is the default behavior for public classes and methods — and 
>> I don't think the modifier is worth adding unless it's the default
 
 What a jump... I am very curious about this rational that seems so obvious 
 to you?
>>> 
>>> There are a thousand different ways to add minor variations on language 
>>> features.  In almost every single thread of any length on this list, you 
>>> can find someone who got attached to a slightly different feature from the 
>>> one that eventually got picked, and often you can find them asking why we 
>>> didn't just add that, too, maybe under a different name or using different 
>>> syntax.  If we added every single one of those, the language would not be 
>>> better, it would just be absurdly, dauntingly complex.  We have to look at 
>>> these kinds of additive features with a very critical eye and decide how 
>>> much code will really benefit from it.
>>> 
>>> In our experience, idiomatic Swift libraries don't center that much around 
>>> classes, and especially not around class inheritance.  Value types are 
>>> usually a better and more efficient data representation than juggling 
>>> shared mutable state, and protocols are a cleaner and much more robust tool 
>>> for polymorphism than overriding methods.  Classes are useful for modeling 
>>> values with "identity", but even then, the class itself can often be final: 
>>> when its operations need to be polymorphic, it's usually better to just 
>>> pass in a closure or an existential, because piling up overrides turns code 
>>> into spaghetti very quickly.
>>> 
>>> That doesn't mean we don't want to add good tools for classes, of course, 
>>> but inheritance and overriding have a lot of subtle interactions, both at a 
>>> low level with other language features and at a high level with any attempt 
>>> to establish basic object invariants.  Programmers want an endless variety 
>>> of language tools for ensuring that overrides satisfy the contract 
>>> correctly — "require the super method to be called", "require the super 
>>> method to be called in exactly this way", "require the super method to be 
>>> called unless the method exits early", "only allow calls to these specific 
>>> other methods", "require this method to be called before doing anything 
>>> else", ad infinitum.  The only way we could possibly support all that is by 
>>> first adding some massive new contracts feature and then embellishing it 
>>> with a ton of inheritance-specific logic; in other words, everything with 
>>> classes quickly balloons into a a huge research project, because (in my 
>>> opinion) overriding is just an inherently clumsy tool.
>>> 
>>> So when you look at something like 'sealed' as an opt-in modifier, you have 
>>> to think carefully about who is actually going to use it.  It's an explicit 
>>> modifier that limits inheritance, but we already have 'final', so it's only 
>>> useful when the library wants to provide its own private subclasses, but 
>>> doesn't want to commit to full public inheritability.  How often does that 
>>> happen, really?  Are we adding this feature for a handful of developers in 
>>> the entire world, most of whom could probably find another solution to 
>>> their problem?  And that's for 'sealed' on a class — are we really supposed 
>>> to expect that someone will unseal a class, but individually protect all 
>>> the methods and properties they don't want overridden?
>>> 
>>> In contrast, 'sealed' as a default is a conservative protection against 
>>> forgetting to add 'final' (which will quickly get caught if the class is 
>>> truly meant to be subclassed), and applied method-by-method it encourages 
>>> the developer to think carefully about where they want the extension points 
>>> to be on their class.  Moreover, it enables a number of interesting 
>>> language enhancements which can only be done safely with complete knowledge 
>>> of the inheritance tree, and it significantly improves performance without 
>>> adding any invasive annotations.  And because 

Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-30 Thread John McCall via swift-evolution
> On Jun 30, 2016, at 11:07 AM, Andrew Trick  wrote:
>> On Jun 30, 2016, at 1:21 AM, John McCall via swift-evolution 
>>  wrote:
>> 
>>> On Jun 29, 2016, at 10:17 PM, L. Mihalkovic  
>>> wrote:
 On Jun 29, 2016, at 8:39 PM, Vladimir.S via swift-evolution 
  wrote:
 
 How about `public(extensible)` ?
 
 On 29.06.2016 21:32, John McCall via swift-evolution wrote:
>> On Jun 29, 2016, at 11:16 AM, Michael Peternell via swift-evolution 
>>  wrote:
>> Do you mean `public(unsealed)`? Because `internal(unsealed)` doesn't 
>> really make sense. `internal` declarations are always sealed.
> 
> Right.
> 
> If "sealed" is the default behavior for public classes and methods — and 
> I don't think the modifier is worth adding unless it's the default
>>> 
>>> What a jump... I am very curious about this rational that seems so obvious 
>>> to you?
>> 
>> There are a thousand different ways to add minor variations on language 
>> features.  In almost every single thread of any length on this list, you can 
>> find someone who got attached to a slightly different feature from the one 
>> that eventually got picked, and often you can find them asking why we didn't 
>> just add that, too, maybe under a different name or using different syntax.  
>> If we added every single one of those, the language would not be better, it 
>> would just be absurdly, dauntingly complex.  We have to look at these kinds 
>> of additive features with a very critical eye and decide how much code will 
>> really benefit from it.
>> 
>> In our experience, idiomatic Swift libraries don't center that much around 
>> classes, and especially not around class inheritance.  Value types are 
>> usually a better and more efficient data representation than juggling shared 
>> mutable state, and protocols are a cleaner and much more robust tool for 
>> polymorphism than overriding methods.  Classes are useful for modeling 
>> values with "identity", but even then, the class itself can often be final: 
>> when its operations need to be polymorphic, it's usually better to just pass 
>> in a closure or an existential, because piling up overrides turns code into 
>> spaghetti very quickly.
>> 
>> That doesn't mean we don't want to add good tools for classes, of course, 
>> but inheritance and overriding have a lot of subtle interactions, both at a 
>> low level with other language features and at a high level with any attempt 
>> to establish basic object invariants.  Programmers want an endless variety 
>> of language tools for ensuring that overrides satisfy the contract correctly 
>> — "require the super method to be called", "require the super method to be 
>> called in exactly this way", "require the super method to be called unless 
>> the method exits early", "only allow calls to these specific other methods", 
>> "require this method to be called before doing anything else", ad infinitum. 
>>  The only way we could possibly support all that is by first adding some 
>> massive new contracts feature and then embellishing it with a ton of 
>> inheritance-specific logic; in other words, everything with classes quickly 
>> balloons into a a huge research project, because (in my opinion) overriding 
>> is just an inherently clumsy tool.
>> 
>> So when you look at something like 'sealed' as an opt-in modifier, you have 
>> to think carefully about who is actually going to use it.  It's an explicit 
>> modifier that limits inheritance, but we already have 'final', so it's only 
>> useful when the library wants to provide its own private subclasses, but 
>> doesn't want to commit to full public inheritability.  How often does that 
>> happen, really?  Are we adding this feature for a handful of developers in 
>> the entire world, most of whom could probably find another solution to their 
>> problem?  And that's for 'sealed' on a class — are we really supposed to 
>> expect that someone will unseal a class, but individually protect all the 
>> methods and properties they don't want overridden?
>> 
>> In contrast, 'sealed' as a default is a conservative protection against 
>> forgetting to add 'final' (which will quickly get caught if the class is 
>> truly meant to be subclassed), and applied method-by-method it encourages 
>> the developer to think carefully about where they want the extension points 
>> to be on their class.  Moreover, it enables a number of interesting language 
>> enhancements which can only be done safely with complete knowledge of the 
>> inheritance tree, and it significantly improves performance without adding 
>> any invasive annotations.  And because it's already there as the default 
>> behavior, that handful of developers who actually need it specifically can 
>> get it for free.
>> 
>> John.
> 
> 100% agree. Sealed-by-default is the only thing that 

Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-30 Thread Andrew Trick via swift-evolution

> On Jun 30, 2016, at 1:21 AM, John McCall via swift-evolution 
>  wrote:
> 
>> On Jun 29, 2016, at 10:17 PM, L. Mihalkovic  
>> wrote:
>>> On Jun 29, 2016, at 8:39 PM, Vladimir.S via swift-evolution 
>>>  wrote:
>>> 
>>> How about `public(extensible)` ?
>>> 
>>> On 29.06.2016 21:32, John McCall via swift-evolution wrote:
> On Jun 29, 2016, at 11:16 AM, Michael Peternell via swift-evolution 
>  wrote:
> Do you mean `public(unsealed)`? Because `internal(unsealed)` doesn't 
> really make sense. `internal` declarations are always sealed.
 
 Right.
 
 If "sealed" is the default behavior for public classes and methods — and I 
 don't think the modifier is worth adding unless it's the default
>> 
>> What a jump... I am very curious about this rational that seems so obvious 
>> to you?
> 
> There are a thousand different ways to add minor variations on language 
> features.  In almost every single thread of any length on this list, you can 
> find someone who got attached to a slightly different feature from the one 
> that eventually got picked, and often you can find them asking why we didn't 
> just add that, too, maybe under a different name or using different syntax.  
> If we added every single one of those, the language would not be better, it 
> would just be absurdly, dauntingly complex.  We have to look at these kinds 
> of additive features with a very critical eye and decide how much code will 
> really benefit from it.
> 
> In our experience, idiomatic Swift libraries don't center that much around 
> classes, and especially not around class inheritance.  Value types are 
> usually a better and more efficient data representation than juggling shared 
> mutable state, and protocols are a cleaner and much more robust tool for 
> polymorphism than overriding methods.  Classes are useful for modeling values 
> with "identity", but even then, the class itself can often be final: when its 
> operations need to be polymorphic, it's usually better to just pass in a 
> closure or an existential, because piling up overrides turns code into 
> spaghetti very quickly.
> 
> That doesn't mean we don't want to add good tools for classes, of course, but 
> inheritance and overriding have a lot of subtle interactions, both at a low 
> level with other language features and at a high level with any attempt to 
> establish basic object invariants.  Programmers want an endless variety of 
> language tools for ensuring that overrides satisfy the contract correctly — 
> "require the super method to be called", "require the super method to be 
> called in exactly this way", "require the super method to be called unless 
> the method exits early", "only allow calls to these specific other methods", 
> "require this method to be called before doing anything else", ad infinitum.  
> The only way we could possibly support all that is by first adding some 
> massive new contracts feature and then embellishing it with a ton of 
> inheritance-specific logic; in other words, everything with classes quickly 
> balloons into a a huge research project, because (in my opinion) overriding 
> is just an inherently clumsy tool.
> 
> So when you look at something like 'sealed' as an opt-in modifier, you have 
> to think carefully about who is actually going to use it.  It's an explicit 
> modifier that limits inheritance, but we already have 'final', so it's only 
> useful when the library wants to provide its own private subclasses, but 
> doesn't want to commit to full public inheritability.  How often does that 
> happen, really?  Are we adding this feature for a handful of developers in 
> the entire world, most of whom could probably find another solution to their 
> problem?  And that's for 'sealed' on a class — are we really supposed to 
> expect that someone will unseal a class, but individually protect all the 
> methods and properties they don't want overridden?
> 
> In contrast, 'sealed' as a default is a conservative protection against 
> forgetting to add 'final' (which will quickly get caught if the class is 
> truly meant to be subclassed), and applied method-by-method it encourages the 
> developer to think carefully about where they want the extension points to be 
> on their class.  Moreover, it enables a number of interesting language 
> enhancements which can only be done safely with complete knowledge of the 
> inheritance tree, and it significantly improves performance without adding 
> any invasive annotations.  And because it's already there as the default 
> behavior, that handful of developers who actually need it specifically can 
> get it for free.
> 
> John.

100% agree. Sealed-by-default is the only thing that makes sense to me at 
module boundaries and would obsolete the use of final-like keywords as magical 
performance tools. I was dismayed to see “final” added 

Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-30 Thread John McCall via swift-evolution
> On Jun 29, 2016, at 10:17 PM, L. Mihalkovic  
> wrote:
>> On Jun 29, 2016, at 8:39 PM, Vladimir.S via swift-evolution 
>>  wrote:
>> 
>> How about `public(extensible)` ?
>> 
>> On 29.06.2016 21:32, John McCall via swift-evolution wrote:
 On Jun 29, 2016, at 11:16 AM, Michael Peternell via swift-evolution 
  wrote:
 Do you mean `public(unsealed)`? Because `internal(unsealed)` doesn't 
 really make sense. `internal` declarations are always sealed.
>>> 
>>> Right.
>>> 
>>> If "sealed" is the default behavior for public classes and methods — and I 
>>> don't think the modifier is worth adding unless it's the default
> 
> What a jump... I am very curious about this rational that seems so obvious to 
> you?

There are a thousand different ways to add minor variations on language 
features.  In almost every single thread of any length on this list, you can 
find someone who got attached to a slightly different feature from the one that 
eventually got picked, and often you can find them asking why we didn't just 
add that, too, maybe under a different name or using different syntax.  If we 
added every single one of those, the language would not be better, it would 
just be absurdly, dauntingly complex.  We have to look at these kinds of 
additive features with a very critical eye and decide how much code will really 
benefit from it.

In our experience, idiomatic Swift libraries don't center that much around 
classes, and especially not around class inheritance.  Value types are usually 
a better and more efficient data representation than juggling shared mutable 
state, and protocols are a cleaner and much more robust tool for polymorphism 
than overriding methods.  Classes are useful for modeling values with 
"identity", but even then, the class itself can often be final: when its 
operations need to be polymorphic, it's usually better to just pass in a 
closure or an existential, because piling up overrides turns code into 
spaghetti very quickly.

That doesn't mean we don't want to add good tools for classes, of course, but 
inheritance and overriding have a lot of subtle interactions, both at a low 
level with other language features and at a high level with any attempt to 
establish basic object invariants.  Programmers want an endless variety of 
language tools for ensuring that overrides satisfy the contract correctly — 
"require the super method to be called", "require the super method to be called 
in exactly this way", "require the super method to be called unless the method 
exits early", "only allow calls to these specific other methods", "require this 
method to be called before doing anything else", ad infinitum.  The only way we 
could possibly support all that is by first adding some massive new contracts 
feature and then embellishing it with a ton of inheritance-specific logic; in 
other words, everything with classes quickly balloons into a a huge research 
project, because (in my opinion) overriding is just an inherently clumsy tool.

So when you look at something like 'sealed' as an opt-in modifier, you have to 
think carefully about who is actually going to use it.  It's an explicit 
modifier that limits inheritance, but we already have 'final', so it's only 
useful when the library wants to provide its own private subclasses, but 
doesn't want to commit to full public inheritability.  How often does that 
happen, really?  Are we adding this feature for a handful of developers in the 
entire world, most of whom could probably find another solution to their 
problem?  And that's for 'sealed' on a class — are we really supposed to expect 
that someone will unseal a class, but individually protect all the methods and 
properties they don't want overridden?

In contrast, 'sealed' as a default is a conservative protection against 
forgetting to add 'final' (which will quickly get caught if the class is truly 
meant to be subclassed), and applied method-by-method it encourages the 
developer to think carefully about where they want the extension points to be 
on their class.  Moreover, it enables a number of interesting language 
enhancements which can only be done safely with complete knowledge of the 
inheritance tree, and it significantly improves performance without adding any 
invasive annotations.  And because it's already there as the default behavior, 
that handful of developers who actually need it specifically can get it for 
free.

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


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-30 Thread John McCall via swift-evolution
> On Jun 29, 2016, at 10:27 PM, L. Mihalkovic  
> wrote:
> 
> On Jun 29, 2016, at 9:54 PM, John McCall via swift-evolution 
>  wrote:
> 
>>> On Jun 29, 2016, at 12:05 PM, Michael Peternell  
>>> wrote:
>>> I'm still unhappy about this "sealed by default" proposal. That really 
>>> looks like premature optimization to me. Instead there should be some 
>>> `sealed` keyword. Maybe it should be called `applepublic` :-p Everyone will 
>>> understand!
>>> 
>>> `sealed` classes should be a special optimization used by optimizing 
>>> developers who ask for it. Don't make it an unwanted and un-asked-for 
>>> default optimization. The people who care for optimization much will learn 
>>> about `sealed` and be able to apply the concept in both cases. The people 
>>> who don't care about performance will just be disappointed by the 
>>> "implicitly sealed" behavior. And with this proposal, when I read 
>>> `unsealed` I can never know: "did this developer intend me to be able to 
>>> subclass this class? or did he just not want to restrict me unnecessarily?" 
>>> The documenting aspect of `unsealed` is so small.
>>> 
>>> And `sealed` is just an optimization; IMHO the magic of static dispatch 
>>> lies in final classes or final methods. Sealing everything by default just 
>>> marks many classes and methods as implicitly final (because it can be 
>>> proven that they are not subclassed). I just don't think that all these 
>>> theoretical performance improvements are really worth the trouble in 
>>> practice.
>> 
>> I'm confused about why you think this is so much of a problem.  Do you 
>> really anticipate writing so many Swift libraries with public classes?
>> 
> 
> Look at some of the public libs on github for server side swift.. one 
> recently claimed 50 modules and counting... I think swift is missing a level 
> of containment below modules, and people are starting to make up for it by 
> creating a flury of (1class+1protocol) modules, especially now that package 
> manager makes it so trivial to create them. I think this is only the 
> begining... and nodejs is there to show how insane it could become:  remember 
> the recent "trimleft" nightmare (1 module with 15 LOC including brackets used 
> pervasively that suddenly disapears).

I'm not arguing that there aren't going to be a lot of libraries.  We're all 
excited about the number of libraries.  Libraries are great.  I'm trying to 
understand whether the objections here — which only matter on library 
boundaries — are motivated by any concrete experience writing such libraries in 
Swift.

Michael's argument was that sealed-by-default will be a major problem for those 
libraries and their users.  Let's suppose that there's a library with a public 
class, and it's sealed by default.  We can conclude that the author has never 
once tried to subclass this class outside of their library, because if they 
had, they would have gotten a compiler error.  Therefore, at best, if I hack 
the library to allow subclasses, I'm going to be doing something that has never 
once been tested and certainly was not considered when the class was written.  
It's pretty clear that this is not the developer's intent.

Likewise, it's not true that "the documenting aspect of `unsealed` is so 
small".  Under sealed-by-default, the developer has to make a conscious, 
deliberate step to allow subclasses outside of their library.  They clearly do 
intend for you to be able to subclass this class.  It's actually the reverse 
situation where the user doesn't know how to interpret the code, because under 
unsealed-by-default, they can't know whether the class is really intended to be 
subclassed or whether they just forgot to add the restriction.

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


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-29 Thread L. Mihalkovic via swift-evolution


Regards
(From mobile)

On Jun 29, 2016, at 9:54 PM, John McCall via swift-evolution 
 wrote:

>> On Jun 29, 2016, at 12:05 PM, Michael Peternell  
>> wrote:
>> I'm still unhappy about this "sealed by default" proposal. That really looks 
>> like premature optimization to me. Instead there should be some `sealed` 
>> keyword. Maybe it should be called `applepublic` :-p Everyone will 
>> understand!
>> 
>> `sealed` classes should be a special optimization used by optimizing 
>> developers who ask for it. Don't make it an unwanted and un-asked-for 
>> default optimization. The people who care for optimization much will learn 
>> about `sealed` and be able to apply the concept in both cases. The people 
>> who don't care about performance will just be disappointed by the 
>> "implicitly sealed" behavior. And with this proposal, when I read `unsealed` 
>> I can never know: "did this developer intend me to be able to subclass this 
>> class? or did he just not want to restrict me unnecessarily?" The 
>> documenting aspect of `unsealed` is so small.
>> 
>> And `sealed` is just an optimization; IMHO the magic of static dispatch lies 
>> in final classes or final methods. Sealing everything by default just marks 
>> many classes and methods as implicitly final (because it can be proven that 
>> they are not subclassed). I just don't think that all these theoretical 
>> performance improvements are really worth the trouble in practice.
> 
> I'm confused about why you think this is so much of a problem.  Do you really 
> anticipate writing so many Swift libraries with public classes?
> 

Look at some of the public libs on github for server side swift.. one recently 
claimed 50 modules and counting... I think swift is missing a level of 
containment below modules, and people are starting to make up for it by 
creating a flury of (1class+1protocol) modules, especially now that package 
manager makes it so trivial to create them. I think this is only the 
begining... and nodejs is there to show how insane it could become:  remember 
the recent "trimleft" nightmare (1 module with 15 LOC including brackets used 
pervasively that suddenly disapears).


> John.
> 
>> 
>> -Michael
>> 
>>> Am 29.06.2016 um 20:39 schrieb Vladimir.S via swift-evolution 
>>> :
>>> 
>>> How about `public(extensible)` ?
>>> 
>>> On 29.06.2016 21:32, John McCall via swift-evolution wrote:
> On Jun 29, 2016, at 11:16 AM, Michael Peternell via swift-evolution 
>  wrote:
> Do you mean `public(unsealed)`? Because `internal(unsealed)` doesn't 
> really make sense. `internal` declarations are always sealed.
 
 Right.
 
 If "sealed" is the default behavior for public classes and methods — and I 
 don't think the modifier is worth adding unless it's the default — then we 
 need a way of "unsealing" classes and methods that's fairly pithy.  I 
 don't think a parenthesized spelling is good enough for that.  And we 
 should try to make the positive form ("can be overridden") shorter than 
 the negative ("cannot be overridden"), because the latter will not usually 
 be written.
 
 To me, the ideal spelling would be usable in place of "public".  If it 
 does have to be stacked with "public", then I think it ought to be pretty 
 short.
 
 "communal"? :)
 
 "open" doesn't carry quite the right meaning, and it would need to be 
 paired with "public", I think.
 
 John.
 
 
> 
> -Michael
> 
>> Am 29.06.2016 um 20:11 schrieb Xiaodi Wu via swift-evolution 
>> :
>> 
>> Do we really need a new keyword? Since we already have syntax like 
>> `internal(set)` couldn't we do `internal(unsealed)`, etc.
>> 
>>> On Wed, Jun 29, 2016 at 12:21 PM, David Sweeris via swift-evolution 
>>>  wrote:
>>> On Jun 29, 2016, at 12:15 PM, Michael Peternell 
>>>  wrote:
>>> 
>>> 
 Am 29.06.2016 um 15:54 schrieb David Sweeris via swift-evolution 
 :
 
 +1 for the concept of a "sealed” class.
 -1 for making it default.
>>> 
>>> Aren't sealed classes already implemented? I think the keyword is 
>>> `final`..
>>> So there is nothing left to do :)
>> 
>> No, `final` doesn’t allow for any subclassing, but `sealed` allows for 
>> subclassing within your module (where you can presumably write more 
>> efficient code based on knowledge of each subclass).
>> 
>> - Dave Sweeris
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
>> ___
>> swift-evolution 

Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-29 Thread L. Mihalkovic via swift-evolution


Regards
(From mobile)

> On Jun 29, 2016, at 8:39 PM, Vladimir.S via swift-evolution 
>  wrote:
> 
> How about `public(extensible)` ?
> 
> On 29.06.2016 21:32, John McCall via swift-evolution wrote:
>>> On Jun 29, 2016, at 11:16 AM, Michael Peternell via swift-evolution 
>>>  wrote:
>>> Do you mean `public(unsealed)`? Because `internal(unsealed)` doesn't really 
>>> make sense. `internal` declarations are always sealed.
>> 
>> Right.
>> 
>> If "sealed" is the default behavior for public classes and methods — and I 
>> don't think the modifier is worth adding unless it's the default

What a jump... I am very curious about this rational that seems so obvious to 
you?

>> — then we need a way of "unsealing" classes and methods that's fairly pithy. 
>>  I don't think a parenthesized spelling is good enough for that.  And we 
>> should try to make the positive form ("can be overridden") shorter than the 
>> negative ("cannot be overridden"), because the latter will not usually be 
>> written.
>> 
>> To me, the ideal spelling would be usable in place of "public".  If it does 
>> have to be stacked with "public", then I think it ought to be pretty short.
>> 
>> "communal"? :)
>> 
>> "open" doesn't carry quite the right meaning, and it would need to be paired 
>> with "public", I think.
>> 
>> John.
>> 
>> 
>>> 
>>> -Michael
>>> 
 Am 29.06.2016 um 20:11 schrieb Xiaodi Wu via swift-evolution 
 :
 
 Do we really need a new keyword? Since we already have syntax like 
 `internal(set)` couldn't we do `internal(unsealed)`, etc.
 
> On Wed, Jun 29, 2016 at 12:21 PM, David Sweeris via swift-evolution 
>  wrote:
> On Jun 29, 2016, at 12:15 PM, Michael Peternell 
>  wrote:
> 
> 
>> Am 29.06.2016 um 15:54 schrieb David Sweeris via swift-evolution 
>> :
>> 
>> +1 for the concept of a "sealed” class.
>> -1 for making it default.
> 
> Aren't sealed classes already implemented? I think the keyword is 
> `final`..
> So there is nothing left to do :)
 
 No, `final` doesn’t allow for any subclassing, but `sealed` allows for 
 subclassing within your module (where you can presumably write more 
 efficient code based on knowledge of each subclass).
 
 - Dave Sweeris
 ___
 swift-evolution mailing list
 swift-evolution@swift.org
 https://lists.swift.org/mailman/listinfo/swift-evolution
 
 ___
 swift-evolution mailing list
 swift-evolution@swift.org
 https://lists.swift.org/mailman/listinfo/swift-evolution
>>> 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-29 Thread John McCall via swift-evolution
> On Jun 29, 2016, at 4:05 PM, Matthew Johnson via swift-evolution 
>  wrote:
>> On Jun 29, 2016, at 5:56 PM, Mark Lacey via swift-evolution 
>> > wrote:
>> 
>>> 
>>> On Jun 29, 2016, at 3:45 PM, Rod Brown via swift-evolution 
>>> > wrote:
>>> 
>>> From my understanding, "Sealed" or whatever we will call it technically 
>>> provides no actual optimisations. We cannot assume the class is final 
>>> because something inside the module may have vended a subclass.
>> 
>> It can enable optimization when compiling with -whole-module-optimization 
>> since we know all the subclasses defined within the module. For any call 
>> site where the static type and all subclasses are sealed, we can limit the 
>> set of potential callees to only the functions defined in those types. 
>> Further, if the static type at the callsite has no subclasses, we can treat 
>> it like final and devirtualize the call.
> 
> There are other interesting things that you can do when you know a class 
> isn’t public inheritable.  For example, I am planning a proposal (after Swift 
> 3) for exhaustive pattern matching on classes that are not publicly 
> inheritable.  

Yes, there are a number of things in this category.  For example, there's a 
fair amount of pedantry around class initializers that we could significantly 
weaken if we're certain we know about all the subclasses.

John.

> 
>> 
>> Mark
>> 
>>> 
>>> The issue that "sealed" as a concept fills is that you stop people from 
>>> subclassing types that were never specifically designed for subclassing, 
>>> but allows the module to do some subclassing for its own needs because the 
>>> developer understands how the class works.
>>> 
>>> It also means a developer of the framework can retroactively apply "Final" 
>>> to the class if they've worked out it actually should be final and will 
>>> never be subclass. If the concept of Sealed did not exist, then a framework 
>>> could never finalise a class down the track - users of the framework may 
>>> have subclassed the type, and now the framework is hamstrung by its 
>>> previous "openness".
>>> 
>>> Should this be the default? In my opinion, yes.  Allowing subclassing to 
>>> other clients should be explicit. It will tie you down and limit you from 
>>> developing into the future. Allowing subclasses from other clients is a 
>>> promise for the life of your product, and cannot be reneged. On classes 
>>> that are not designed for subclassing, this is ill advised, and on classes 
>>> you wish to optimise, it's a permanent limitation.
>>> 
>>> While I fear the abuse framework vendors will exercise, by allowing clever 
>>> private hacks, and disallowing obj-c style workarounds, I think the safety 
>>> and longevity of this approach is far more important.
>>> 
>>> +1 to the concept. I agree "sealed" is not foot wording and can be improved.
>>> 
>>> - Rod Brown
>>> 
 On 30 Jun. 2016, at 5:05 am, Michael Peternell via swift-evolution 
 > wrote:
 
 I'm still unhappy about this "sealed by default" proposal. That really 
 looks like premature optimization to me. Instead there should be some 
 `sealed` keyword. Maybe it should be called `applepublic` :-p Everyone 
 will understand!
 
 `sealed` classes should be a special optimization used by optimizing 
 developers who ask for it. Don't make it an unwanted and un-asked-for 
 default optimization. The people who care for optimization much will learn 
 about `sealed` and be able to apply the concept in both cases. The people 
 who don't care about performance will just be disappointed by the 
 "implicitly sealed" behavior. And with this proposal, when I read 
 `unsealed` I can never know: "did this developer intend me to be able to 
 subclass this class? or did he just not want to restrict me 
 unnecessarily?" The documenting aspect of `unsealed` is so small.
 
 And `sealed` is just an optimization; IMHO the magic of static dispatch 
 lies in final classes or final methods. Sealing everything by default just 
 marks many classes and methods as implicitly final (because it can be 
 proven that they are not subclassed). I just don't think that all these 
 theoretical performance improvements are really worth the trouble in 
 practice.
 
 -Michael
 
> Am 29.06.2016 um 20:39 schrieb Vladimir.S via swift-evolution 
> >:
> 
> How about `public(extensible)` ?
> 
> On 29.06.2016 21:32, John McCall via swift-evolution wrote:
>>> On Jun 29, 2016, at 11:16 AM, Michael Peternell via swift-evolution 
>>> > wrote:
>>> Do you mean 

Re: [swift-evolution] [Proposal] Sealed classes by default

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

> On Jun 29, 2016, at 6:05 PM, David Sweeris via swift-evolution 
>  wrote:
> 
> 
> 
> Sent from my iPhone
> 
>> On Jun 29, 2016, at 17:45, Rod Brown via swift-evolution 
>>  wrote:
>> 
>> From my understanding, "Sealed" or whatever we will call it technically 
>> provides no actual optimisations. We cannot assume the class is final 
>> because something inside the module may have vended a subclass.
> 
> Sure we can. Because the class is sealed, the compiler can know that no 
> further subclassing is possible, which can allowing it to use static 
> dispatch, inlining, etc wherever possible.

The compiler knows that subclasses cannot happen outside the module, but if 
subclasses exist within the module there will be many cases where the compiler 
won’t be able to devirtualize.

> 
> I think...
> 
> - Dave Sweeris
> ___
> 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] [Proposal] Sealed classes by default

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

> On Jun 29, 2016, at 5:56 PM, Mark Lacey via swift-evolution 
>  wrote:
> 
>> 
>> On Jun 29, 2016, at 3:45 PM, Rod Brown via swift-evolution 
>> > wrote:
>> 
>> From my understanding, "Sealed" or whatever we will call it technically 
>> provides no actual optimisations. We cannot assume the class is final 
>> because something inside the module may have vended a subclass.
> 
> It can enable optimization when compiling with -whole-module-optimization 
> since we know all the subclasses defined within the module. For any call site 
> where the static type and all subclasses are sealed, we can limit the set of 
> potential callees to only the functions defined in those types. Further, if 
> the static type at the callsite has no subclasses, we can treat it like final 
> and devirtualize the call.

There are other interesting things that you can do when you know a class isn’t 
public inheritable.  For example, I am planning a proposal (after Swift 3) for 
exhaustive pattern matching on classes that are not publicly inheritable.  

> 
> Mark
> 
>> 
>> The issue that "sealed" as a concept fills is that you stop people from 
>> subclassing types that were never specifically designed for subclassing, but 
>> allows the module to do some subclassing for its own needs because the 
>> developer understands how the class works.
>> 
>> It also means a developer of the framework can retroactively apply "Final" 
>> to the class if they've worked out it actually should be final and will 
>> never be subclass. If the concept of Sealed did not exist, then a framework 
>> could never finalise a class down the track - users of the framework may 
>> have subclassed the type, and now the framework is hamstrung by its previous 
>> "openness".
>> 
>> Should this be the default? In my opinion, yes.  Allowing subclassing to 
>> other clients should be explicit. It will tie you down and limit you from 
>> developing into the future. Allowing subclasses from other clients is a 
>> promise for the life of your product, and cannot be reneged. On classes that 
>> are not designed for subclassing, this is ill advised, and on classes you 
>> wish to optimise, it's a permanent limitation.
>> 
>> While I fear the abuse framework vendors will exercise, by allowing clever 
>> private hacks, and disallowing obj-c style workarounds, I think the safety 
>> and longevity of this approach is far more important.
>> 
>> +1 to the concept. I agree "sealed" is not foot wording and can be improved.
>> 
>> - Rod Brown
>> 
>>> On 30 Jun. 2016, at 5:05 am, Michael Peternell via swift-evolution 
>>>  wrote:
>>> 
>>> I'm still unhappy about this "sealed by default" proposal. That really 
>>> looks like premature optimization to me. Instead there should be some 
>>> `sealed` keyword. Maybe it should be called `applepublic` :-p Everyone will 
>>> understand!
>>> 
>>> `sealed` classes should be a special optimization used by optimizing 
>>> developers who ask for it. Don't make it an unwanted and un-asked-for 
>>> default optimization. The people who care for optimization much will learn 
>>> about `sealed` and be able to apply the concept in both cases. The people 
>>> who don't care about performance will just be disappointed by the 
>>> "implicitly sealed" behavior. And with this proposal, when I read 
>>> `unsealed` I can never know: "did this developer intend me to be able to 
>>> subclass this class? or did he just not want to restrict me unnecessarily?" 
>>> The documenting aspect of `unsealed` is so small.
>>> 
>>> And `sealed` is just an optimization; IMHO the magic of static dispatch 
>>> lies in final classes or final methods. Sealing everything by default just 
>>> marks many classes and methods as implicitly final (because it can be 
>>> proven that they are not subclassed). I just don't think that all these 
>>> theoretical performance improvements are really worth the trouble in 
>>> practice.
>>> 
>>> -Michael
>>> 
 Am 29.06.2016 um 20:39 schrieb Vladimir.S via swift-evolution 
 :
 
 How about `public(extensible)` ?
 
 On 29.06.2016 21:32, John McCall via swift-evolution wrote:
>> On Jun 29, 2016, at 11:16 AM, Michael Peternell via swift-evolution 
>>  wrote:
>> Do you mean `public(unsealed)`? Because `internal(unsealed)` doesn't 
>> really make sense. `internal` declarations are always sealed.
> 
> Right.
> 
> If "sealed" is the default behavior for public classes and methods — and 
> I don't think the modifier is worth adding unless it's the default — then 
> we need a way of "unsealing" classes and methods that's fairly pithy.  I 
> don't think a parenthesized spelling is good enough for that.  And we 
> should try to make the positive form ("can be overridden") shorter than 
> the negative 

Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-29 Thread David Sweeris via swift-evolution


Sent from my iPhone

> On Jun 29, 2016, at 17:45, Rod Brown via swift-evolution 
>  wrote:
> 
> From my understanding, "Sealed" or whatever we will call it technically 
> provides no actual optimisations. We cannot assume the class is final because 
> something inside the module may have vended a subclass.

Sure we can. Because the class is sealed, the compiler can know that no further 
subclassing is possible, which can allowing it to use static dispatch, 
inlining, etc wherever possible.

I think...

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


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-29 Thread Mark Lacey via swift-evolution

> On Jun 29, 2016, at 3:45 PM, Rod Brown via swift-evolution 
>  wrote:
> 
> From my understanding, "Sealed" or whatever we will call it technically 
> provides no actual optimisations. We cannot assume the class is final because 
> something inside the module may have vended a subclass.

It can enable optimization when compiling with -whole-module-optimization since 
we know all the subclasses defined within the module. For any call site where 
the static type and all subclasses are sealed, we can limit the set of 
potential callees to only the functions defined in those types. Further, if the 
static type at the callsite has no subclasses, we can treat it like final and 
devirtualize the call.

Mark

> 
> The issue that "sealed" as a concept fills is that you stop people from 
> subclassing types that were never specifically designed for subclassing, but 
> allows the module to do some subclassing for its own needs because the 
> developer understands how the class works.
> 
> It also means a developer of the framework can retroactively apply "Final" to 
> the class if they've worked out it actually should be final and will never be 
> subclass. If the concept of Sealed did not exist, then a framework could 
> never finalise a class down the track - users of the framework may have 
> subclassed the type, and now the framework is hamstrung by its previous 
> "openness".
> 
> Should this be the default? In my opinion, yes.  Allowing subclassing to 
> other clients should be explicit. It will tie you down and limit you from 
> developing into the future. Allowing subclasses from other clients is a 
> promise for the life of your product, and cannot be reneged. On classes that 
> are not designed for subclassing, this is ill advised, and on classes you 
> wish to optimise, it's a permanent limitation.
> 
> While I fear the abuse framework vendors will exercise, by allowing clever 
> private hacks, and disallowing obj-c style workarounds, I think the safety 
> and longevity of this approach is far more important.
> 
> +1 to the concept. I agree "sealed" is not foot wording and can be improved.
> 
> - Rod Brown
> 
>> On 30 Jun. 2016, at 5:05 am, Michael Peternell via swift-evolution 
>>  wrote:
>> 
>> I'm still unhappy about this "sealed by default" proposal. That really looks 
>> like premature optimization to me. Instead there should be some `sealed` 
>> keyword. Maybe it should be called `applepublic` :-p Everyone will 
>> understand!
>> 
>> `sealed` classes should be a special optimization used by optimizing 
>> developers who ask for it. Don't make it an unwanted and un-asked-for 
>> default optimization. The people who care for optimization much will learn 
>> about `sealed` and be able to apply the concept in both cases. The people 
>> who don't care about performance will just be disappointed by the 
>> "implicitly sealed" behavior. And with this proposal, when I read `unsealed` 
>> I can never know: "did this developer intend me to be able to subclass this 
>> class? or did he just not want to restrict me unnecessarily?" The 
>> documenting aspect of `unsealed` is so small.
>> 
>> And `sealed` is just an optimization; IMHO the magic of static dispatch lies 
>> in final classes or final methods. Sealing everything by default just marks 
>> many classes and methods as implicitly final (because it can be proven that 
>> they are not subclassed). I just don't think that all these theoretical 
>> performance improvements are really worth the trouble in practice.
>> 
>> -Michael
>> 
>>> Am 29.06.2016 um 20:39 schrieb Vladimir.S via swift-evolution 
>>> :
>>> 
>>> How about `public(extensible)` ?
>>> 
>>> On 29.06.2016 21:32, John McCall via swift-evolution wrote:
> On Jun 29, 2016, at 11:16 AM, Michael Peternell via swift-evolution 
>  wrote:
> Do you mean `public(unsealed)`? Because `internal(unsealed)` doesn't 
> really make sense. `internal` declarations are always sealed.
 
 Right.
 
 If "sealed" is the default behavior for public classes and methods — and I 
 don't think the modifier is worth adding unless it's the default — then we 
 need a way of "unsealing" classes and methods that's fairly pithy.  I 
 don't think a parenthesized spelling is good enough for that.  And we 
 should try to make the positive form ("can be overridden") shorter than 
 the negative ("cannot be overridden"), because the latter will not usually 
 be written.
 
 To me, the ideal spelling would be usable in place of "public".  If it 
 does have to be stacked with "public", then I think it ought to be pretty 
 short.
 
 "communal"? :)
 
 "open" doesn't carry quite the right meaning, and it would need to be 
 paired with "public", I think.
 
 John.
 
 
> 
> -Michael
> 
>> Am 29.06.2016 um 20:11 

Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-29 Thread Rod Brown via swift-evolution
From my understanding, "Sealed" or whatever we will call it technically 
provides no actual optimisations. We cannot assume the class is final because 
something inside the module may have vended a subclass.

The issue that "sealed" as a concept fills is that you stop people from 
subclassing types that were never specifically designed for subclassing, but 
allows the module to do some subclassing for its own needs because the 
developer understands how the class works.

It also means a developer of the framework can retroactively apply "Final" to 
the class if they've worked out it actually should be final and will never be 
subclass. If the concept of Sealed did not exist, then a framework could never 
finalise a class down the track - users of the framework may have subclassed 
the type, and now the framework is hamstrung by its previous "openness".

Should this be the default? In my opinion, yes.  Allowing subclassing to other 
clients should be explicit. It will tie you down and limit you from developing 
into the future. Allowing subclasses from other clients is a promise for the 
life of your product, and cannot be reneged. On classes that are not designed 
for subclassing, this is ill advised, and on classes you wish to optimise, it's 
a permanent limitation.

While I fear the abuse framework vendors will exercise, by allowing clever 
private hacks, and disallowing obj-c style workarounds, I think the safety and 
longevity of this approach is far more important.

+1 to the concept. I agree "sealed" is not foot wording and can be improved.

- Rod Brown

> On 30 Jun. 2016, at 5:05 am, Michael Peternell via swift-evolution 
>  wrote:
> 
> I'm still unhappy about this "sealed by default" proposal. That really looks 
> like premature optimization to me. Instead there should be some `sealed` 
> keyword. Maybe it should be called `applepublic` :-p Everyone will understand!
> 
> `sealed` classes should be a special optimization used by optimizing 
> developers who ask for it. Don't make it an unwanted and un-asked-for default 
> optimization. The people who care for optimization much will learn about 
> `sealed` and be able to apply the concept in both cases. The people who don't 
> care about performance will just be disappointed by the "implicitly sealed" 
> behavior. And with this proposal, when I read `unsealed` I can never know: 
> "did this developer intend me to be able to subclass this class? or did he 
> just not want to restrict me unnecessarily?" The documenting aspect of 
> `unsealed` is so small.
> 
> And `sealed` is just an optimization; IMHO the magic of static dispatch lies 
> in final classes or final methods. Sealing everything by default just marks 
> many classes and methods as implicitly final (because it can be proven that 
> they are not subclassed). I just don't think that all these theoretical 
> performance improvements are really worth the trouble in practice.
> 
> -Michael
> 
>> Am 29.06.2016 um 20:39 schrieb Vladimir.S via swift-evolution 
>> :
>> 
>> How about `public(extensible)` ?
>> 
>> On 29.06.2016 21:32, John McCall via swift-evolution wrote:
 On Jun 29, 2016, at 11:16 AM, Michael Peternell via swift-evolution 
  wrote:
 Do you mean `public(unsealed)`? Because `internal(unsealed)` doesn't 
 really make sense. `internal` declarations are always sealed.
>>> 
>>> Right.
>>> 
>>> If "sealed" is the default behavior for public classes and methods — and I 
>>> don't think the modifier is worth adding unless it's the default — then we 
>>> need a way of "unsealing" classes and methods that's fairly pithy.  I don't 
>>> think a parenthesized spelling is good enough for that.  And we should try 
>>> to make the positive form ("can be overridden") shorter than the negative 
>>> ("cannot be overridden"), because the latter will not usually be written.
>>> 
>>> To me, the ideal spelling would be usable in place of "public".  If it does 
>>> have to be stacked with "public", then I think it ought to be pretty short.
>>> 
>>> "communal"? :)
>>> 
>>> "open" doesn't carry quite the right meaning, and it would need to be 
>>> paired with "public", I think.
>>> 
>>> John.
>>> 
>>> 
 
 -Michael
 
> Am 29.06.2016 um 20:11 schrieb Xiaodi Wu via swift-evolution 
> :
> 
> Do we really need a new keyword? Since we already have syntax like 
> `internal(set)` couldn't we do `internal(unsealed)`, etc.
> 
>> On Wed, Jun 29, 2016 at 12:21 PM, David Sweeris via swift-evolution 
>>  wrote:
>> On Jun 29, 2016, at 12:15 PM, Michael Peternell 
>>  wrote:
>> 
>> 
>>> Am 29.06.2016 um 15:54 schrieb David Sweeris via swift-evolution 
>>> :
>>> 
>>> +1 for the concept of a "sealed” class.
>>> -1 for making it default.
>> 

Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-29 Thread Xiaodi Wu via swift-evolution
On Wed, Jun 29, 2016 at 2:54 PM, John McCall via swift-evolution <
swift-evolution@swift.org> wrote:

> > On Jun 29, 2016, at 11:39 AM, Vladimir.S  wrote:
> > How about `public(extensible)` ?
>
> Hmm.  I started to work out an example with these as separate modifiers,
> and I think I understand the need to combine them in some way.
>
> I wonder if just "extensible" would be good enough.  It is a term that's
> used in API descriptions.
>

This particular word is unfortunate because it has nothing to do with an
extension, which shares the same etymological root.


>
> 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] [Proposal] Sealed classes by default

2016-06-29 Thread Jean-Daniel Dupas via swift-evolution

> Le 29 juin 2016 à 21:41, Leonardo Pessoa via swift-evolution 
>  a écrit :
> 
> I actually thought about something like 'public(final)' as it may make
> it clearer the intention to the class (and no new keywords were
> introduced).

I also though about public(final), but it may be confused with "public final" 
which can be used to defined a class final even in the module scope.

> Also I think we should draw a guideline for such naming because there
> are always so many suggestions. Having a guideline would reduce our
> efforts in choosing names.
> 
> L
> 
> On 29 June 2016 at 15:16, Michael Peternell via swift-evolution
>  wrote:
>> Do you mean `public(unsealed)`? Because `internal(unsealed)` doesn't really 
>> make sense. `internal` declarations are always sealed.
>> 
>> -Michael
>> 
>>> Am 29.06.2016 um 20:11 schrieb Xiaodi Wu via swift-evolution 
>>> :
>>> 
>>> Do we really need a new keyword? Since we already have syntax like 
>>> `internal(set)` couldn't we do `internal(unsealed)`, etc.
>>> 
>>> On Wed, Jun 29, 2016 at 12:21 PM, David Sweeris via swift-evolution 
>>>  wrote:
 On Jun 29, 2016, at 12:15 PM, Michael Peternell  
 wrote:
 
 
> Am 29.06.2016 um 15:54 schrieb David Sweeris via swift-evolution 
> :
> 
> +1 for the concept of a "sealed” class.
> -1 for making it default.
 
 Aren't sealed classes already implemented? I think the keyword is `final`..
 So there is nothing left to do :)
>>> 
>>> No, `final` doesn’t allow for any subclassing, but `sealed` allows for 
>>> subclassing within your module (where you can presumably write more 
>>> efficient code based on knowledge of each subclass).
>>> 
>>> - Dave Sweeris
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> ___
> 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] [Proposal] Sealed classes by default

2016-06-29 Thread John McCall via swift-evolution
> On Jun 29, 2016, at 11:16 AM, Michael Peternell via swift-evolution 
>  wrote:
> Do you mean `public(unsealed)`? Because `internal(unsealed)` doesn't really 
> make sense. `internal` declarations are always sealed.

Right.

If "sealed" is the default behavior for public classes and methods — and I 
don't think the modifier is worth adding unless it's the default — then we need 
a way of "unsealing" classes and methods that's fairly pithy.  I don't think a 
parenthesized spelling is good enough for that.  And we should try to make the 
positive form ("can be overridden") shorter than the negative ("cannot be 
overridden"), because the latter will not usually be written.

To me, the ideal spelling would be usable in place of "public".  If it does 
have to be stacked with "public", then I think it ought to be pretty short.

"communal"? :)

"open" doesn't carry quite the right meaning, and it would need to be paired 
with "public", I think.

John.


> 
> -Michael
> 
>> Am 29.06.2016 um 20:11 schrieb Xiaodi Wu via swift-evolution 
>> :
>> 
>> Do we really need a new keyword? Since we already have syntax like 
>> `internal(set)` couldn't we do `internal(unsealed)`, etc.
>> 
>> On Wed, Jun 29, 2016 at 12:21 PM, David Sweeris via swift-evolution 
>>  wrote:
>>> On Jun 29, 2016, at 12:15 PM, Michael Peternell  
>>> wrote:
>>> 
>>> 
 Am 29.06.2016 um 15:54 schrieb David Sweeris via swift-evolution 
 :
 
 +1 for the concept of a "sealed” class.
 -1 for making it default.
>>> 
>>> Aren't sealed classes already implemented? I think the keyword is `final`..
>>> So there is nothing left to do :)
>> 
>> No, `final` doesn’t allow for any subclassing, but `sealed` allows for 
>> subclassing within your module (where you can presumably write more 
>> efficient code based on knowledge of each subclass).
>> 
>> - Dave Sweeris
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-29 Thread Michael Peternell via swift-evolution
Do you mean `public(unsealed)`? Because `internal(unsealed)` doesn't really 
make sense. `internal` declarations are always sealed.

-Michael

> Am 29.06.2016 um 20:11 schrieb Xiaodi Wu via swift-evolution 
> :
> 
> Do we really need a new keyword? Since we already have syntax like 
> `internal(set)` couldn't we do `internal(unsealed)`, etc.
> 
> On Wed, Jun 29, 2016 at 12:21 PM, David Sweeris via swift-evolution 
>  wrote:
> > On Jun 29, 2016, at 12:15 PM, Michael Peternell  
> > wrote:
> >
> >
> >> Am 29.06.2016 um 15:54 schrieb David Sweeris via swift-evolution 
> >> :
> >>
> >> +1 for the concept of a "sealed” class.
> >> -1 for making it default.
> >
> > Aren't sealed classes already implemented? I think the keyword is `final`..
> > So there is nothing left to do :)
> 
> No, `final` doesn’t allow for any subclassing, but `sealed` allows for 
> subclassing within your module (where you can presumably write more efficient 
> code based on knowledge of each subclass).
> 
> - Dave Sweeris
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-29 Thread Xiaodi Wu via swift-evolution
Do we really need a new keyword? Since we already have syntax like
`internal(set)` couldn't we do `internal(unsealed)`, etc.

On Wed, Jun 29, 2016 at 12:21 PM, David Sweeris via swift-evolution <
swift-evolution@swift.org> wrote:

> > On Jun 29, 2016, at 12:15 PM, Michael Peternell <
> michael.petern...@gmx.at> wrote:
> >
> >
> >> Am 29.06.2016 um 15:54 schrieb David Sweeris via swift-evolution <
> swift-evolution@swift.org>:
> >>
> >> +1 for the concept of a "sealed” class.
> >> -1 for making it default.
> >
> > Aren't sealed classes already implemented? I think the keyword is
> `final`..
> > So there is nothing left to do :)
>
> No, `final` doesn’t allow for any subclassing, but `sealed` allows for
> subclassing within your module (where you can presumably write more
> efficient code based on knowledge of each subclass).
>
> - Dave Sweeris
> ___
> 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] [Proposal] Sealed classes by default

2016-06-29 Thread Michael Peternell via swift-evolution

> Am 29.06.2016 um 15:54 schrieb David Sweeris via swift-evolution 
> :
> 
> +1 for the concept of a "sealed” class.
> -1 for making it default.

Aren't sealed classes already implemented? I think the keyword is `final`..
So there is nothing left to do :)

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


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-29 Thread David Sweeris via swift-evolution
> On Jun 29, 2016, at 12:15 PM, Michael Peternell  
> wrote:
> 
> 
>> Am 29.06.2016 um 15:54 schrieb David Sweeris via swift-evolution 
>> :
>> 
>> +1 for the concept of a "sealed” class.
>> -1 for making it default.
> 
> Aren't sealed classes already implemented? I think the keyword is `final`..
> So there is nothing left to do :)

No, `final` doesn’t allow for any subclassing, but `sealed` allows for 
subclassing within your module (where you can presumably write more efficient 
code based on knowledge of each subclass).

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


Re: [swift-evolution] [Proposal] Sealed classes by default

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


Sent from my iPhone

> On Jun 29, 2016, at 12:15 PM, Michael Peternell via swift-evolution 
>  wrote:
> 
> 
>> Am 29.06.2016 um 15:54 schrieb David Sweeris via swift-evolution 
>> :
>> 
>> +1 for the concept of a "sealed” class.
>> -1 for making it default.
> 
> Aren't sealed classes already implemented? I think the keyword is `final`..
> So there is nothing left to do :)

Sealed and final are very different.  Sealed allows subclasses *within the 
declaring module* but final does not allow any subclasses at all.

> 
> ___
> 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] [Proposal] Sealed classes by default

2016-06-29 Thread Michael Peternell via swift-evolution

> Am 29.06.2016 um 08:33 schrieb Jean-Daniel Dupas via swift-evolution 
> :
> 
> 
>> Le 29 juin 2016 à 01:01, Michael Peternell via swift-evolution 
>>  a écrit :
>> 
>> 
>>> Am 29.06.2016 um 00:32 schrieb John McCall :
>>> 
>>> The decision to make class methods polymorphic by default was always 
>>> premised on being able to undo that in obvious cases where methods are 
>>> never overridden.  Making a class public so that clients can use it 
>>> shouldn't cause significant performance degradations just because you 
>>> forgot to also write "final".
>>> 
>>> John.
>> 
>> I do care about performance. For this reason I don't want a fully dynamic 
>> language. I disagree about the "significant performance degradations just 
>> because you forgot to also write `final`". I mentioned "performance" in my 
>> original post only because it would be the only convincing argument - if 
>> there were indeed superior performance when using `final`.
>> 
>> Of course, dynamic dispatch is much slower than static dispatch. But 
>> optimized code does not spend much time dispatching. If a method takes 3 
>> seconds to complete, and from that 2 seconds are used for dynamically 
>> dispatching method calls, then I would say that it has not been optimized 
>> for performance yet. How would such a function look like? The function being 
>> dynamically dispatched should probably not be statically dispatched but 
>> inlined completely. And for the rare case that the dispatch type really 
>> makes all the difference, it's always possible to `final`ize (or 
>> `private`ize) some of the used methods.
> 
> Swift dynamic dispatch is not Obj-C dynamic dispatch. Talking about the cost 
> of dynamic dispatch without real benchmark is premature optimization IMHO.

Whom are you telling this? And which do you think is faster? Objc dynamic 
dispatch or Swift dynamic dispatch? I think, in the long run, Swift dynamic 
dispatch will be faster because Swift is less dynamic on that level.

-Michael


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


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-29 Thread Jean-Daniel Dupas via swift-evolution

> Le 29 juin 2016 à 01:01, Michael Peternell via swift-evolution 
>  a écrit :
> 
> 
>> Am 29.06.2016 um 00:32 schrieb John McCall :
>> 
>> The decision to make class methods polymorphic by default was always 
>> premised on being able to undo that in obvious cases where methods are never 
>> overridden.  Making a class public so that clients can use it shouldn't 
>> cause significant performance degradations just because you forgot to also 
>> write "final".
>> 
>> John.
> 
> I do care about performance. For this reason I don't want a fully dynamic 
> language. I disagree about the "significant performance degradations just 
> because you forgot to also write `final`". I mentioned "performance" in my 
> original post only because it would be the only convincing argument - if 
> there were indeed superior performance when using `final`.
> 
> Of course, dynamic dispatch is much slower than static dispatch. But 
> optimized code does not spend much time dispatching. If a method takes 3 
> seconds to complete, and from that 2 seconds are used for dynamically 
> dispatching method calls, then I would say that it has not been optimized for 
> performance yet. How would such a function look like? The function being 
> dynamically dispatched should probably not be statically dispatched but 
> inlined completely. And for the rare case that the dispatch type really makes 
> all the difference, it's always possible to `final`ize (or `private`ize) some 
> of the used methods.

Swift dynamic dispatch is not Obj-C dynamic dispatch. Talking about the cost of 
dynamic dispatch without real benchmark is premature optimization IMHO.


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


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-28 Thread John McCall via swift-evolution
> On Jun 28, 2016, at 4:01 PM, Michael Peternell  
> wrote:
>> Am 29.06.2016 um 00:32 schrieb John McCall :
>> 
>> The decision to make class methods polymorphic by default was always 
>> premised on being able to undo that in obvious cases where methods are never 
>> overridden.  Making a class public so that clients can use it shouldn't 
>> cause significant performance degradations just because you forgot to also 
>> write "final".
>> 
>> John.
> 
> I do care about performance. For this reason I don't want a fully dynamic 
> language. I disagree about the "significant performance degradations just 
> because you forgot to also write `final`". I mentioned "performance" in my 
> original post only because it would be the only convincing argument - if 
> there were indeed superior performance when using `final`.
> 
> Of course, dynamic dispatch is much slower than static dispatch. But 
> optimized code does not spend much time dispatching. If a method takes 3 
> seconds to complete, and from that 2 seconds are used for dynamically 
> dispatching method calls, then I would say that it has not been optimized for 
> performance yet. How would such a function look like? The function being 
> dynamically dispatched should probably not be statically dispatched but 
> inlined completely. And for the rare case that the dispatch type really makes 
> all the difference, it's always possible to `final`ize (or `private`ize) some 
> of the used methods.

Getters and setters are major examples of methods that (1) are very likely to 
be made public on a public class, (2) are very, very profitable to devirtualize 
and inline within the class's implementation, and (3) most programmers will 
never think to mark final (and are very annoying to "inline").  Now, if the 
program contains some cubic algorithm, then of course this level of micro 
performance doesn't matter much; it's at best a constant factor on the Nested 
Loop Of Doom.  However, as a language implementor, it is not fair for me to 
assume that the program contains brazen inefficiencies that will swamp the 
impact of any decision I make; it is often the case that, after crossing off a 
few prominent hot-spots, programmers find themselves staring at profiles that 
are disconcertingly flat.  And a lot of programmers feel quite rightly that 
they shouldn't have to massively uglify their source code with annotations just 
to get a little bit of performance, especially if it feels like something the 
language ought to just know.

I also have some responsibility to the system to try to run code as efficiently 
as possible, even if the programmer (be it through laziness, ignorance, or — 
more likely — just being over-worked) didn't put much conscious effort into 
optimizing it.

Anyway, I think you're underselling the advantages of devirtualization.

First, modern systems do a *lot* of indirect calls.  On a typical iOS device, 
the indirect branch predictor is not very effective, not because its prediction 
algorithm is in any way inadequate but because its cache is just not large 
enough to deal with all the indirect branches being executed by (mostly) 
objc_msgSend.  (I am not a hardware expert, but as I understand it, it is not 
easy to just make these caches bigger.)  Just making a bunch of calls direct 
instead means those calls (1) won't miss in the cache and (2) won't contribute 
to thrashing the cache for other calls.

Second, devirtualization is a major enabling optimization.  Many methods are 
quite small, especially the ones that you probably don't think of as methods, 
like the implicit accessors for stored properties.  Being able to inline them, 
or even just reason about whether they change memory, can have a big impact.

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 also think this is the right thing to do for library evolution, but yes, it 
is a very valuable optimization that we would otherwise struggle to do for 
public classes.

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


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-28 Thread Mark Lacey via swift-evolution

> On Jun 28, 2016, at 4:01 PM, Michael Peternell via swift-evolution 
>  wrote:
> 
> 
>> Am 29.06.2016 um 00:32 schrieb John McCall :
>> 
>> The decision to make class methods polymorphic by default was always 
>> premised on being able to undo that in obvious cases where methods are never 
>> overridden.  Making a class public so that clients can use it shouldn't 
>> cause significant performance degradations just because you forgot to also 
>> write "final".
>> 
>> John.
> 
> I do care about performance. For this reason I don't want a fully dynamic 
> language. I disagree about the "significant performance degradations just 
> because you forgot to also write `final`". I mentioned "performance" in my 
> original post only because it would be the only convincing argument - if 
> there were indeed superior performance when using `final`.

There is, and it can be very substantial. Knowing a method is final enables the 
optimizer to devirtualize, and devirtualization enables type-based 
specialization for generic functions, as well as inlining (each of which enable 
further devirtualization, etc., etc.). Devirtualization also makes it possible 
to do specialization of function signatures, which can remove ARC overhead. 
When that kicks in it can be a substantial win by itself. It can also improve 
the results of interprocedural analysis, which can provide further benefit (and 
which we’ll likely rely on more for performance improvement in the future). For 
example we are currently able to stack-allocate some data that was heap 
allocated in Swift 2.x because we do escape analysis, which is only possible 
when you know all the potential callees at a call site.

I recall seeing performance differences of 40x (yes, 40x, not 40%) on 
small-to-moderately sized benchmarks that use generics due to whole module 
optimization being able to infer final for internal classes. Part of that 
performance difference can be accounted for by known issues with the 
performance of generic code, but even if we substantially improve that I 
believe we would still have cases where lack of devirtualizing, inlining, and 
specialization would result in substantially slower code. 

Mark

> 
> Of course, dynamic dispatch is much slower than static dispatch. But 
> optimized code does not spend much time dispatching. If a method takes 3 
> seconds to complete, and from that 2 seconds are used for dynamically 
> dispatching method calls, then I would say that it has not been optimized for 
> performance yet. How would such a function look like? The function being 
> dynamically dispatched should probably not be statically dispatched but 
> inlined completely. And for the rare case that the dispatch type really makes 
> all the difference, it's always possible to `final`ize (or `private`ize) some 
> of the used methods.
> 
> -Michael
> 
> ___
> 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] [Proposal] Sealed classes by default

2016-06-28 Thread Michael Peternell via swift-evolution

> Am 29.06.2016 um 00:32 schrieb John McCall :
> 
> The decision to make class methods polymorphic by default was always premised 
> on being able to undo that in obvious cases where methods are never 
> overridden.  Making a class public so that clients can use it shouldn't cause 
> significant performance degradations just because you forgot to also write 
> "final".
> 
> John.

I do care about performance. For this reason I don't want a fully dynamic 
language. I disagree about the "significant performance degradations just 
because you forgot to also write `final`". I mentioned "performance" in my 
original post only because it would be the only convincing argument - if there 
were indeed superior performance when using `final`.

Of course, dynamic dispatch is much slower than static dispatch. But optimized 
code does not spend much time dispatching. If a method takes 3 seconds to 
complete, and from that 2 seconds are used for dynamically dispatching method 
calls, then I would say that it has not been optimized for performance yet. How 
would such a function look like? The function being dynamically dispatched 
should probably not be statically dispatched but inlined completely. And for 
the rare case that the dispatch type really makes all the difference, it's 
always possible to `final`ize (or `private`ize) some of the used methods.

-Michael

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


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-28 Thread John McCall via swift-evolution
> On Jun 28, 2016, at 2:20 PM, Christopher Kornher  wrote:
>> On Jun 28, 2016, at 2:31 PM, John McCall via swift-evolution 
>> > wrote:
>> 
>>> On Jun 28, 2016, at 12:39 PM, Michael Peternell via swift-evolution 
>>> > wrote:
>>> Sealing classes by default is a terrible idea IMHO. Fortunately, my faith 
>>> in the Swift core team is strong enough so that I cannot believe that this 
>>> has a chance of ever being implemented at all :)
>>> 
>>> Why do I think it's terrible? I do subclass classes even when they say that 
>>> you shouldn't do it. I even monkey-patched a few classes in the past. Why? 
>>> Not because I prefer hacking over clean coding, but to get the job done. 
>>> Every few months or so I encounter a situation where such hacking attempts 
>>> are the only feasible way to make something work. Or I use them during 
>>> research activities or unofficial "feasibility studies". (If that's not the 
>>> case for you, then maybe you are working in a different job than I. Monkey 
>>> patching is rarely necessary if you make iPhone apps.) These are situations 
>>> where everyone else just says "that's not possible". Yes, you can make that 
>>> USB driver class stop spamming the console; yes, you can stop that library 
>>> from crashing randomly.
>>> 
>>> There is so much more to say on this topic. Sealing classes is also bad 
>>> because it prevents forms of experimental coding. It doesn't solve a real 
>>> problem. How often have I seen bugs where someone subclassed a class that 
>>> shouldn't be subclassed? That's so rare. But if all classes are sealed by 
>>> default this will lead to far worse problems. When a developer subclasses a 
>>> class, he usually has a reason. There already is a `final` keyword in 
>>> Swift, and a dev really thinks that a class shouldn't be subclass-able, he 
>>> can use it already. And if I subclass it from Objective-C anyways, then 
>>> maybe I know what I'm doing?
>>> 
>>> And I'm not buying this "performance" argument. If you want better 
>>> performance, write the hot functions in C or maybe even in assembler. The 
>>> dynamic dispatch overhead is not the feature that makes programs bad or 
>>> slow. It's quadratic algorithms (e.g. unnecessary nested loops), calling 
>>> functions multiple times (e.g. if(a.foo.bar(x[2]) == "joo" || 
>>> a.foo.bar(x[2]) == "fooo" || a.foo.bar(x[2]) == nil) { ... }), or just 
>>> overly complex code: all of them have more impact than dynamic dispatch. 
>>> Even worse for performance is unnecessary IO or using graphics APIs 
>>> inefficiently. A good profiler can help a lot with these issues.
>>> 
>>> Swift should be designed for the real world, not for an ideal world that 
>>> does not exist and that will never exist.
>> 
>> The design intent of much of Swift is to allow "free" coding within a 
>> module/file/type while encouraging programmers to think more carefully about 
>> their public interfaces.  Module interfaces are the most serious and 
>> permanent of these interfaces.  It's in keeping with that for declarations 
>> to make only minimal public guarantees and require the programmer to be more 
>> explicit about the things they want to allow.
>> 
>> Your arguments about patchability and performance could be applied to every 
>> feature in the language.  They are essentially arguments for a fully-dynamic 
>> environment.
> 
> see https://en.wikipedia.org/wiki/Straw_man 
> 
What's the limiting argument?  Why is it critical for practical programmers to 
be able to arbitrarily patch someone else's code, but only at the point where 
it calls public methods on public classes?  That's a very strange idea in 
Swift, given how we encourage the use of structs and non-public types.

> Most OO languages do not seal seal modules (or the equivalent) by default. 
> Forcing developers to add “final” does not seem onerous. If authors do not 
> have time to audit their frameworks, the language should not pretend do it 
> for them.

Again, this could be an argument for making everything public by default.  
(Many OO languages essentially do.)  What's the limiting argument?

Swift takes a consistent line here: the default rule across a module boundary 
is the rule that reserves the implementation the greatest flexibility in the 
future.  Making classes final outside of the module gives the module the right 
to make the class final everywhere and to change the class's internal 
implementation to call different methods or change delegation patterns without 
worrying about how it affects a use-case that most programmers won't have 
considered.  If they have considered it, of course, it is trivial for them to 
write that down, just as it is trivial for them to make the class public to 
begin with.

>> There's no reason to single out subclassing; for everything you can 

Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-28 Thread Christopher Kornher via swift-evolution

> On Jun 28, 2016, at 2:31 PM, John McCall via swift-evolution 
>  wrote:
> 
>> On Jun 28, 2016, at 12:39 PM, Michael Peternell via swift-evolution 
>>  wrote:
>> Sealing classes by default is a terrible idea IMHO. Fortunately, my faith in 
>> the Swift core team is strong enough so that I cannot believe that this has 
>> a chance of ever being implemented at all :)
>> 
>> Why do I think it's terrible? I do subclass classes even when they say that 
>> you shouldn't do it. I even monkey-patched a few classes in the past. Why? 
>> Not because I prefer hacking over clean coding, but to get the job done. 
>> Every few months or so I encounter a situation where such hacking attempts 
>> are the only feasible way to make something work. Or I use them during 
>> research activities or unofficial "feasibility studies". (If that's not the 
>> case for you, then maybe you are working in a different job than I. Monkey 
>> patching is rarely necessary if you make iPhone apps.) These are situations 
>> where everyone else just says "that's not possible". Yes, you can make that 
>> USB driver class stop spamming the console; yes, you can stop that library 
>> from crashing randomly.
>> 
>> There is so much more to say on this topic. Sealing classes is also bad 
>> because it prevents forms of experimental coding. It doesn't solve a real 
>> problem. How often have I seen bugs where someone subclassed a class that 
>> shouldn't be subclassed? That's so rare. But if all classes are sealed by 
>> default this will lead to far worse problems. When a developer subclasses a 
>> class, he usually has a reason. There already is a `final` keyword in Swift, 
>> and a dev really thinks that a class shouldn't be subclass-able, he can use 
>> it already. And if I subclass it from Objective-C anyways, then maybe I know 
>> what I'm doing?
>> 
>> And I'm not buying this "performance" argument. If you want better 
>> performance, write the hot functions in C or maybe even in assembler. The 
>> dynamic dispatch overhead is not the feature that makes programs bad or 
>> slow. It's quadratic algorithms (e.g. unnecessary nested loops), calling 
>> functions multiple times (e.g. if(a.foo.bar(x[2]) == "joo" || 
>> a.foo.bar(x[2]) == "fooo" || a.foo.bar(x[2]) == nil) { ... }), or just 
>> overly complex code: all of them have more impact than dynamic dispatch. 
>> Even worse for performance is unnecessary IO or using graphics APIs 
>> inefficiently. A good profiler can help a lot with these issues.
>> 
>> Swift should be designed for the real world, not for an ideal world that 
>> does not exist and that will never exist.
> 
> The design intent of much of Swift is to allow "free" coding within a 
> module/file/type while encouraging programmers to think more carefully about 
> their public interfaces.  Module interfaces are the most serious and 
> permanent of these interfaces.  It's in keeping with that for declarations to 
> make only minimal public guarantees and require the programmer to be more 
> explicit about the things they want to allow.
> 
> Your arguments about patchability and performance could be applied to every 
> feature in the language.  They are essentially arguments for a fully-dynamic 
> environment.

see https://en.wikipedia.org/wiki/Straw_man

Most OO languages do not seal seal modules (or the equivalent) by default. 
Forcing developers to add “final” does not seem onerous. If authors do not have 
time to audit their frameworks, the language should not pretend do it for them.


> There's no reason to single out subclassing; for everything you can imagine, 
> one programmer's caution will be another's paternalism.  You're just making 
> the argument here because you're used to a particular way of patching 
> Objective-C code, one which will work regardless of this language decision;

That seems personal.


> but most of the old ObjC techniques (e.g. accessing ivars reflectively) 
> already won't work on Swift code without unsafe operations, and subclassing 
> is a very tiny part of that problem.
> 
> And no, we do not and will not accept that performance-sensitive code can 
> only possibly be written in C or assembly, or that algorithmic performance is 
> the only thing worth worrying about, even for the language implementation.

Could many of the performance advantages of sealing could be gained through 
“whole application” optimization?T he benefits could far exceed what is 
possible with whole module optimization. It would probably be extremely 
difficult and hard to scale, but for packaged, signed applications, it should 
be possible some day.

> 
> John.



> 
> 
> 
>> -Michael
>> 
>>> Am 28.06.2016 um 15:09 schrieb L. Mihalkovic via swift-evolution 
>>> :
>>> 
>>> 
>>> Regards
>>> LM
>>> (From mobile)
 On Jun 28, 2016, at 1:57 PM, Alejandro Martinez via swift-evolution 
  wrote:
 
 Anton 

Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-28 Thread John McCall via swift-evolution
> On Jun 28, 2016, at 12:39 PM, Michael Peternell via swift-evolution 
>  wrote:
> Sealing classes by default is a terrible idea IMHO. Fortunately, my faith in 
> the Swift core team is strong enough so that I cannot believe that this has a 
> chance of ever being implemented at all :)
> 
> Why do I think it's terrible? I do subclass classes even when they say that 
> you shouldn't do it. I even monkey-patched a few classes in the past. Why? 
> Not because I prefer hacking over clean coding, but to get the job done. 
> Every few months or so I encounter a situation where such hacking attempts 
> are the only feasible way to make something work. Or I use them during 
> research activities or unofficial "feasibility studies". (If that's not the 
> case for you, then maybe you are working in a different job than I. Monkey 
> patching is rarely necessary if you make iPhone apps.) These are situations 
> where everyone else just says "that's not possible". Yes, you can make that 
> USB driver class stop spamming the console; yes, you can stop that library 
> from crashing randomly.
> 
> There is so much more to say on this topic. Sealing classes is also bad 
> because it prevents forms of experimental coding. It doesn't solve a real 
> problem. How often have I seen bugs where someone subclassed a class that 
> shouldn't be subclassed? That's so rare. But if all classes are sealed by 
> default this will lead to far worse problems. When a developer subclasses a 
> class, he usually has a reason. There already is a `final` keyword in Swift, 
> and a dev really thinks that a class shouldn't be subclass-able, he can use 
> it already. And if I subclass it from Objective-C anyways, then maybe I know 
> what I'm doing?
> 
> And I'm not buying this "performance" argument. If you want better 
> performance, write the hot functions in C or maybe even in assembler. The 
> dynamic dispatch overhead is not the feature that makes programs bad or slow. 
> It's quadratic algorithms (e.g. unnecessary nested loops), calling functions 
> multiple times (e.g. if(a.foo.bar(x[2]) == "joo" || a.foo.bar(x[2]) == "fooo" 
> || a.foo.bar(x[2]) == nil) { ... }), or just overly complex code: all of them 
> have more impact than dynamic dispatch. Even worse for performance is 
> unnecessary IO or using graphics APIs inefficiently. A good profiler can help 
> a lot with these issues.
> 
> Swift should be designed for the real world, not for an ideal world that does 
> not exist and that will never exist.

The design intent of much of Swift is to allow "free" coding within a 
module/file/type while encouraging programmers to think more carefully about 
their public interfaces.  Module interfaces are the most serious and permanent 
of these interfaces.  It's in keeping with that for declarations to make only 
minimal public guarantees and require the programmer to be more explicit about 
the things they want to allow.

Your arguments about patchability and performance could be applied to every 
feature in the language.  They are essentially arguments for a fully-dynamic 
environment.  There's no reason to single out subclassing; for everything you 
can imagine, one programmer's caution will be another's paternalism.  You're 
just making the argument here because you're used to a particular way of 
patching Objective-C code, one which will work regardless of this language 
decision; but most of the old ObjC techniques (e.g. accessing ivars 
reflectively) already won't work on Swift code without unsafe operations, and 
subclassing is a very tiny part of that problem.

And no, we do not and will not accept that performance-sensitive code can only 
possibly be written in C or assembly, or that algorithmic performance is the 
only thing worth worrying about, even for the language implementation.

John.



> -Michael
> 
>> Am 28.06.2016 um 15:09 schrieb L. Mihalkovic via swift-evolution 
>> :
>> 
>> 
>> Regards
>> LM
>> (From mobile)
>>> On Jun 28, 2016, at 1:57 PM, Alejandro Martinez via swift-evolution 
>>>  wrote:
>>> 
>>> Anton Zhilin: That is one of the points if I’m not mistaken. Sealed
>>> means that with whole-module-optimization the compiler can optimise
>>> more things as it can treat it as final for other modules.
>>> 
>>> L. Mihalkovic: Could you give an example of what exactly do you mean?
>>> I know one of the reasons behind the proposal is to actually improve
>>> those situations by forcing us to think more on customisation when
>>> designing APIs.
>> 
>> In many situation it has been my experience that libraries can be extended 
>> DESPITE their authors, rather than only thanks to the skills the authors  
>> have shown in planning for the future. It is what happened to me with 
>> AlamoFire, where i was able to extend it because some cracks existed which 
>> let me do something the designers did not think about (to me it was a lack 
>> of imagination 

Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-28 Thread Michael Peternell via swift-evolution
Sealing classes by default is a terrible idea IMHO. Fortunately, my faith in 
the Swift core team is strong enough so that I cannot believe that this has a 
chance of ever being implemented at all :)

Why do I think it's terrible? I do subclass classes even when they say that you 
shouldn't do it. I even monkey-patched a few classes in the past. Why? Not 
because I prefer hacking over clean coding, but to get the job done. Every few 
months or so I encounter a situation where such hacking attempts are the only 
feasible way to make something work. Or I use them during research activities 
or unofficial "feasibility studies". (If that's not the case for you, then 
maybe you are working in a different job than I. Monkey patching is rarely 
necessary if you make iPhone apps.) These are situations where everyone else 
just says "that's not possible". Yes, you can make that USB driver class stop 
spamming the console; yes, you can stop that library from crashing randomly.

There is so much more to say on this topic. Sealing classes is also bad because 
it prevents forms of experimental coding. It doesn't solve a real problem. How 
often have I seen bugs where someone subclassed a class that shouldn't be 
subclassed? That's so rare. But if all classes are sealed by default this will 
lead to far worse problems. When a developer subclasses a class, he usually has 
a reason. There already is a `final` keyword in Swift, and a dev really thinks 
that a class shouldn't be subclass-able, he can use it already. And if I 
subclass it from Objective-C anyways, then maybe I know what I'm doing?

And I'm not buying this "performance" argument. If you want better performance, 
write the hot functions in C or maybe even in assembler. The dynamic dispatch 
overhead is not the feature that makes programs bad or slow. It's quadratic 
algorithms (e.g. unnecessary nested loops), calling functions multiple times 
(e.g. if(a.foo.bar(x[2]) == "joo" || a.foo.bar(x[2]) == "fooo" || 
a.foo.bar(x[2]) == nil) { ... }), or just overly complex code: all of them have 
more impact than dynamic dispatch. Even worse for performance is unnecessary IO 
or using graphics APIs inefficiently. A good profiler can help a lot with these 
issues.

Swift should be designed for the real world, not for an ideal world that does 
not exist and that will never exist.

-Michael

> Am 28.06.2016 um 15:09 schrieb L. Mihalkovic via swift-evolution 
> :
> 
> 
> Regards
> LM
> (From mobile)
>> On Jun 28, 2016, at 1:57 PM, Alejandro Martinez via swift-evolution 
>>  wrote:
>> 
>> Anton Zhilin: That is one of the points if I’m not mistaken. Sealed
>> means that with whole-module-optimization the compiler can optimise
>> more things as it can treat it as final for other modules.
>> 
>> L. Mihalkovic: Could you give an example of what exactly do you mean?
>> I know one of the reasons behind the proposal is to actually improve
>> those situations by forcing us to think more on customisation when
>> designing APIs.
> 
> In many situation it has been my experience that libraries can be extended 
> DESPITE their authors, rather than only thanks to the skills the authors  
> have shown in planning for the future. It is what happened to me with 
> AlamoFire, where i was able to extend it because some cracks existed which 
> let me do something the designers did not think about (to me it was a lack of 
> imagination to not have anticipated what i wanted to do).
> 
> So if this can happen with a lib made by very experienced/talented 
> developers, then imagine what happens with far less skilled developers.. it 
> will mean having to copy code in order extend. It may sound pessimistic, but 
> if u had seen as much bad code as i have seen, you might understand the view 
> i am sharing.
> 
> What's worse is that objc is not particularly conducive to good software 
> architecture (it is a bit like perl and javascript where anything can be 
> touched from anywhere, and has a limited set of constructs compared to c++, 
> scala, java, c#, swift). So i do not believe that it has prepared objc devs 
> to suddenly become great code designers with a language that has multiples 
> levels of scoping/nesting (i would not use most of the swift libs i have seen 
> on github to teach software design).
> 
> Hence my conclusion that defaulting to sealed may be giving too much credit 
> to the code that is currently available for reuse.
> 
> 
>> 
>> On Tue, Jun 28, 2016 at 12:44 PM, Anton Zhilin via swift-evolution
>>  wrote:
>>> Does `sealed` allow for any optimizations? Maybe somehow devirtualizing
>>> method calls?
>>> 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
>> 
>> 
>> -- 
>> Alejandro Martinez
>> http://alejandromp.com
>> ___
>> 

Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-28 Thread L. Mihalkovic via swift-evolution


Regards
LM
(From mobile)

> On Jun 28, 2016, at 5:24 PM, Matthew Johnson via swift-evolution 
>  wrote:
> 
> 
>> On Jun 28, 2016, at 10:17 AM, Mark Lacey via swift-evolution 
>>  wrote:
>> 
>> 
 On Jun 28, 2016, at 7:55 AM, Sean Heber  wrote:
 
> On Jun 28, 2016, at 9:52 AM, Mark Lacey via swift-evolution 
>  wrote:
> 
> 
> On Jun 27, 2016, at 9:10 PM, L. Mihalkovic via swift-evolution 
>  wrote:
> 
> -1 for the fact that if all devs can write working code, fewer can do it 
> in a clear structured fashion that is well designed for extensibility.
 
 This sounds more like an argument for having sealed classes than not. As 
 the proposal points out in the motivation, if the base class is not 
 designed with subclassing in mind then overriding methods can result in 
 unintended behavior (e.g. crashing, or other bugs).
>>> 
>>> But I think the counter argument is, what if you need to fix or workaround 
>>> unintended behavior of the class you’re trying to use?
>> 
>> Sure, I understand that, and I don’t mean to trivialize that concern. I’m 
>> just pointing out that “code…that is [not] well designed for extensibility”, 
>> might not  work very well if you start using extension points that weren’t 
>> well thought through.
>> 
>> If you are designing for extensibility you’ll be carefully thinking about 
>> what should and should not be final both within and outside of your module.

We all think carefully about what we do... it just does not mean the same in 
regards to the outcome. It seems it is only in the software industry that we 
all think of ourselves as michelangelos or rubens.. unfortunately it takes a 
lot of errors to become humble about it.

>> Not doing so can result in bugs. This proposal introduces the ability to 
>> allow extension within the module but restrict it outside the module, and 
>> defaults to not allowing extension beyond the module.
>> 
>> You can argue both ways which default would be better, and I suspect people 
>> who mostly write libraries might opt for sealed-by-default, and people who 
>> mostly consume libraries might opt for open-by-default. My point is that 
>> open-by-default isn’t “better” because it allows you to potentially work 
>> around a problem in a base class, because by working around that problem by 
>> overriding a method that wasn’t designed to be overridden you don’t know how 
>> many other new problems you might be introducing (now or in the future if 
>> the implementation of the base class changes).
> 
> I think a good argument for sealed by default is that if we introduce 
> `sealed` responsible library authors will already be marking all classes not 
> intended for external subclassing as either `sealed` or `final` anyway.   The 
> intended (and hopefully actual) public  API will be identical regardless of 
> the default.  Making it the default avoids a lot of boilerplate keywords and 
> makes ensure the API contract is stated more explicitly.
> 
> The only case where the default should make a difference is when a library is 
> written without consideration of subclasses.  As you point out, in that case 
> it is a really bad idea to attempt to work around a bug with a subclass.
> 
>> 
>> Mark
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-28 Thread John McCall via swift-evolution
> On Jun 28, 2016, at 8:09 AM, Javier Soto via swift-evolution 
>  wrote:
> IMO the issue with the argument that we wouldn't be able to "monkey patch" 
> things on sealed classes is that that is already the nature of Swift. The 
> designer of an API can choose to use structs instead of classes, and then 
> there's already no way to "subclass". Moreover, "final" already exists, and 
> whether sealed is introduced or not, and whether it becomes the default or 
> not, API designers are already free to use final in all classes they do not 
> intend to be subclassed, so I think that would be an argument against final 
> existing in the first place, and that ship has already sailed. 
> 
> As for whether sealed would allow for optimizations: my hunch is that it 
> would. However, as I write this I noticed a flaw with my proposal: I said 
> that sealed classes would be exported as final. This is only half-true. They 
> would in that they can't be subclassed outside the module, but there could be 
> subclasses in the same module! That means if the parent were to be treated as 
> final, code outside the module would incorrectly devirtualize non-final 
> methods. 

Also, note that:
  - we're clearly going to have to import ObjC classes as subclassable by 
default, and in fact there's currently no way to explicitly declare an ObjC 
class to be final;
  - many classes in ObjC are actually intended to be subclassed (although not 
every method is intended to be overridden), and those tend to be the classes 
that users most want to patch;
  - methods in ObjC can just be directly monkey-patched without subclassing, 
even if we're not necessarily happy about you doing it; and
  - even if we re-implemented a bunch of frameworks in Swift, we'd still have 
to maintain compatibility with some amount of this stuff.

So I don't think that sealed-by-default would have any significant impact on 
the ability to patch Apple code as a third party.

For code that isn't deployed in an OS that won't be updated, the obviously 
better solution is to fix the library, either yourself or, if it's 
closed-source, through your normal vendor support process.

John.

> On Tue, Jun 28, 2016 at 7:59 AM Charlie Monroe via swift-evolution 
> > wrote:
> 
> > On Jun 28, 2016, at 4:55 PM, Sean Heber via swift-evolution 
> > > wrote:
> >
> >> On Jun 28, 2016, at 9:52 AM, Mark Lacey via swift-evolution 
> >> > wrote:
> >>
> >>>
> >>> On Jun 27, 2016, at 9:10 PM, L. Mihalkovic via swift-evolution 
> >>> > wrote:
> >>>
> >>> -1 for the fact that if all devs can write working code, fewer can do it 
> >>> in a clear structured fashion that is well designed for extensibility.
> >>
> >> This sounds more like an argument for having sealed classes than not. As 
> >> the proposal points out in the motivation, if the base class is not 
> >> designed with subclassing in mind then overriding methods can result in 
> >> unintended behavior (e.g. crashing, or other bugs).
> >
> > But I think the counter argument is, what if you need to fix or workaround 
> > unintended behavior of the class you’re trying to use?
> 
> Typically you modify something open source - 99% of which is on GitHub. IMHO 
> the best way is to either fork it and perhaps submit a pull request with the 
> fix.
> 
> But I understand that this is not always possible...
> 
> 
> >
> > l8r
> > Sean
> >
> > ___
> > 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 
> 
> -- 
> Javier Soto
> ___
> 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] [Proposal] Sealed classes by default

2016-06-28 Thread L. Mihalkovic via swift-evolution

Regards
LM
(From mobile)

> On Jun 28, 2016, at 4:59 PM, Charlie Monroe via swift-evolution 
>  wrote:
> 
> 
>>> On Jun 28, 2016, at 4:55 PM, Sean Heber via swift-evolution 
>>>  wrote:
>>> 
 On Jun 28, 2016, at 9:52 AM, Mark Lacey via swift-evolution 
  wrote:
 
 
 On Jun 27, 2016, at 9:10 PM, L. Mihalkovic via swift-evolution 
  wrote:
 
 -1 for the fact that if all devs can write working code, fewer can do it 
 in a clear structured fashion that is well designed for extensibility.
>>> 
>>> This sounds more like an argument for having sealed classes than not. As 
>>> the proposal points out in the motivation, if the base class is not 
>>> designed with subclassing in mind then overriding methods can result in 
>>> unintended behavior (e.g. crashing, or other bugs).
>> 
>> But I think the counter argument is, what if you need to fix or workaround 
>> unintended behavior of the class you’re trying to use?
> 
> Typically you modify something open source - 99% of which is on GitHub. IMHO 
> the best way is to either fork it and perhaps submit a pull request with the 
> fix.
> 
> But I understand that this is not always possible...

I am a professional dev, and i rarely have the time (or even the legal right) 
to push back the changes i make to public code... the objc world is IMVHO very 
far from the professional open source culture that exists around other 
languages... so far the swift world is very embryonic. Sealing by default looks 
to me like a miss judgement of the maturity of the ecosystem.

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


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-28 Thread L. Mihalkovic via swift-evolution

Regards
LM
(From mobile)

> On Jun 28, 2016, at 4:52 PM, Mark Lacey  wrote:
> 
> 
>> On Jun 27, 2016, at 9:10 PM, L. Mihalkovic via swift-evolution 
>>  wrote:
>> 
>> -1 for the fact that if all devs can write working code, fewer can do it in 
>> a clear structured fashion that is well designed for extensibility.
> 
> This sounds more like an argument for having sealed classes than not. As the 
> proposal points out in the motivation, if the base class is not designed with 
> subclassing in mind then overriding methods can result in unintended behavior 
> (e.g. crashing, or other bugs).
> 

The pb i am referencing is devs who think their code is designed for extension 
but ends up being awkward or incompletely so. In my exp this is true of lots of 
(most) libs, including prominent projects. I got this sense over the years that 
a lot if newb designers want to play gods by showing how well they can juggle 
the different levels of privacy/locking in a language to create great 
extensible codebases.. and after getting burned a few times by their inability 
to think holistically about all possible codepaths, they become more humble and 
write more straightforward code that in the end becomes more extensible.

Crashing because of me deciding to extend something not ready for should remain 
my responsibility, because in the end this is no different than my own code 
crashing because of my bugs. I think it should be everyone's responsibility to 
make sure we pay attention when drinking hot coffee, not the responsibility of 
mcDonald to write in caps on their cups that hot liquids tend to cause burns. 

> Mark
> 
>> A couple months ago I even ran into difficulties when trying to extend 
>> AlamoFire because some things had not been designed as cleanly as they could 
>> have been to make extending it easy. So if the default is now that 
>> everything becomes non-extensible but default, it is going to complicate 
>> (and partially defeat the purpose of) reusing libraries.
>> Regards
>> (From mobile)
>> 
>>> On Jun 28, 2016, at 2:11 AM, Michael Ilseman via swift-evolution 
>>>  wrote:
>>> 
>>> I was also referring to how we present Objective-C classes in Swift. That 
>>> is, if a Swift user tries to subclass an Objective-C-imported class, then 
>>> we’d take into account sealed-ness in order to issue an error/warning, etc. 
>>> If you are also proposing a Clang attribute for this, e.g. ‘swift_sealed’, 
>>> to import as sealed (meaning issue an error if Swift users try to subclass 
>>> it), then that should be spelled out as well. I don’t have an opinion on 
>>> whether this is a good idea yet, just pointing out some more directions to 
>>> explore. In general it feels like your proposal could use more fleshing out.
>>> 
>>> 
 On Jun 27, 2016, at 5:08 PM, Javier Soto  wrote:
 
 That is a very good point, it should be explicitly mentioned in the 
 proposal. My thought would be that since in the Obj-C runtime it's not 
 possible to guarantee a class won't have subclasses, or that a method is 
 not overriden, Obj-C classes would be imported as open. 
 
 On the Swift side, I think today it's possible to declare a "public final 
 @objc class", but you can still inherit from it from Obj-C, right? My 
 hunch would be that that should be disallowed, but perhaps there's a 
 reason why it's allowed today. 
 On Mon, Jun 27, 2016 at 4:25 PM Michael Ilseman  wrote:
> Could you elaborate on how we should treat classes imported from 
> Objective-C or CF-style C? That is, do we always annotate them as being 
> “open” because those paradigms permit subclassing anywhere, or do you 
> propose some kind of recommended “sealed” audit, or what?
> 
> 
>> On Jun 27, 2016, at 3:40 PM, Javier Soto via swift-evolution 
>>  wrote:
>> 
> 
>> Hello!
>> 
>> I sent this as a PR on the swift-evolution repo, but we never had any 
>> discussion about it on-list, besides a long time ago. Here's the first 
>> draft of the proposal:
>> 
>> 
>> Sealed classes by default
>> Introduction
>> 
>> Introduce a new sealed class modifier that makes classes and methods 
>> final outside of the module they're declared in, but non-final within 
>> the module.
>> 
>> Motivation
>> 
>> It is not uncommon to have a need for a reference type without needing 
>> inheritance. Classes must be intentionally designed to be subclassable, 
>> carefully deciding which methods are the override entry-points such that 
>> the the behavior remains correct and subclasses respect the Liskov 
>> substitution principle.
>> Defaulting to non-final allows the author of a class to accidentally 
>> leave the visible methods open for overrides, even if they didn't 

Re: [swift-evolution] [Proposal] Sealed classes by default

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

> On Jun 28, 2016, at 10:17 AM, Mark Lacey via swift-evolution 
>  wrote:
> 
> 
>> On Jun 28, 2016, at 7:55 AM, Sean Heber  wrote:
>> 
>>> On Jun 28, 2016, at 9:52 AM, Mark Lacey via swift-evolution 
>>>  wrote:
>>> 
 
 On Jun 27, 2016, at 9:10 PM, L. Mihalkovic via swift-evolution 
  wrote:
 
 -1 for the fact that if all devs can write working code, fewer can do it 
 in a clear structured fashion that is well designed for extensibility.
>>> 
>>> This sounds more like an argument for having sealed classes than not. As 
>>> the proposal points out in the motivation, if the base class is not 
>>> designed with subclassing in mind then overriding methods can result in 
>>> unintended behavior (e.g. crashing, or other bugs).
>> 
>> But I think the counter argument is, what if you need to fix or workaround 
>> unintended behavior of the class you’re trying to use?
> 
> Sure, I understand that, and I don’t mean to trivialize that concern. I’m 
> just pointing out that “code…that is [not] well designed for extensibility”, 
> might not  work very well if you start using extension points that weren’t 
> well thought through.
> 
> If you are designing for extensibility you’ll be carefully thinking about 
> what should and should not be final both within and outside of your module. 
> Not doing so can result in bugs. This proposal introduces the ability to 
> allow extension within the module but restrict it outside the module, and 
> defaults to not allowing extension beyond the module.
> 
> You can argue both ways which default would be better, and I suspect people 
> who mostly write libraries might opt for sealed-by-default, and people who 
> mostly consume libraries might opt for open-by-default. My point is that 
> open-by-default isn’t “better” because it allows you to potentially work 
> around a problem in a base class, because by working around that problem by 
> overriding a method that wasn’t designed to be overridden you don’t know how 
> many other new problems you might be introducing (now or in the future if the 
> implementation of the base class changes).

I think a good argument for sealed by default is that if we introduce `sealed` 
responsible library authors will already be marking all classes not intended 
for external subclassing as either `sealed` or `final` anyway.   The intended 
(and hopefully actual) public  API will be identical regardless of the default. 
 Making it the default avoids a lot of boilerplate keywords and makes ensure 
the API contract is stated more explicitly.

The only case where the default should make a difference is when a library is 
written without consideration of subclasses.  As you point out, in that case it 
is a really bad idea to attempt to work around a bug with a subclass.

> 
> Mark
> 
> ___
> 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] [Proposal] Sealed classes by default

2016-06-28 Thread Mark Lacey via swift-evolution

> On Jun 28, 2016, at 7:55 AM, Sean Heber  wrote:
> 
>> On Jun 28, 2016, at 9:52 AM, Mark Lacey via swift-evolution 
>>  wrote:
>> 
>>> 
>>> On Jun 27, 2016, at 9:10 PM, L. Mihalkovic via swift-evolution 
>>>  wrote:
>>> 
>>> -1 for the fact that if all devs can write working code, fewer can do it in 
>>> a clear structured fashion that is well designed for extensibility.
>> 
>> This sounds more like an argument for having sealed classes than not. As the 
>> proposal points out in the motivation, if the base class is not designed 
>> with subclassing in mind then overriding methods can result in unintended 
>> behavior (e.g. crashing, or other bugs).
> 
> But I think the counter argument is, what if you need to fix or workaround 
> unintended behavior of the class you’re trying to use?

Sure, I understand that, and I don’t mean to trivialize that concern. I’m just 
pointing out that “code…that is [not] well designed for extensibility”, might 
not  work very well if you start using extension points that weren’t well 
thought through.

If you are designing for extensibility you’ll be carefully thinking about what 
should and should not be final both within and outside of your module. Not 
doing so can result in bugs. This proposal introduces the ability to allow 
extension within the module but restrict it outside the module, and defaults to 
not allowing extension beyond the module.

You can argue both ways which default would be better, and I suspect people who 
mostly write libraries might opt for sealed-by-default, and people who mostly 
consume libraries might opt for open-by-default. My point is that 
open-by-default isn’t “better” because it allows you to potentially work around 
a problem in a base class, because by working around that problem by overriding 
a method that wasn’t designed to be overridden you don’t know how many other 
new problems you might be introducing (now or in the future if the 
implementation of the base class changes).

Mark

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


Re: [swift-evolution] [Proposal] Sealed classes by default

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

> On Jun 28, 2016, at 9:59 AM, Charlie Monroe via swift-evolution 
>  wrote:
> 
>> 
>> On Jun 28, 2016, at 4:55 PM, Sean Heber via swift-evolution 
>>  wrote:
>> 
>>> On Jun 28, 2016, at 9:52 AM, Mark Lacey via swift-evolution 
>>>  wrote:
>>> 
 
 On Jun 27, 2016, at 9:10 PM, L. Mihalkovic via swift-evolution 
  wrote:
 
 -1 for the fact that if all devs can write working code, fewer can do it 
 in a clear structured fashion that is well designed for extensibility.
>>> 
>>> This sounds more like an argument for having sealed classes than not. As 
>>> the proposal points out in the motivation, if the base class is not 
>>> designed with subclassing in mind then overriding methods can result in 
>>> unintended behavior (e.g. crashing, or other bugs).
>> 
>> But I think the counter argument is, what if you need to fix or workaround 
>> unintended behavior of the class you’re trying to use?
> 
> Typically you modify something open source - 99% of which is on GitHub. IMHO 
> the best way is to either fork it and perhaps submit a pull request with the 
> fix.
> 
> But I understand that this is not always possible…

I agree that this is the best approach for open source dependencies.  If the 
authors of the library disagree with you about what the public API should be 
then perhaps it isn’t the right dependency for your project and you should 
either create your own fork or find another library to use.

That said, in the "final by default” thread a lot of the discussion was about 
working around bugs in Apple’s closed source frameworks.  This line of argument 
isn’t really valid because changing the default in Swift won’t affect 
frameworks written in Objective-C and also because the default is unlikely to 
have a significant impact on Apple’s exposed API.  Apple will be free to use 
`sealed` even if they need to apply it manually and is very likely to do so as 
soon as they start writing frameworks in Swift and `sealed` is an option.

IMO the argument for introducing `sealed` and making it the default is roughly 
analogous to the argument for having an `internal` access level and making that 
the default: the author of a library should have tools to control what is and 
is not exposed as public API.  The ability to subclass is an API contract every 
bit as much as anything else.  The safe default is to require library authors 
to opt-in to all public API, thus avoiding "accidentally public” API.  

As was noted in previous threads, making the contract more explicit and 
enforcing it is viewed by many as a good thing.  It prevents hackish 
workarounds which both facilitates framework evolution and also increases 
pressure on framework authors to fix their bugs in a timely manner.

-Matthew

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


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-28 Thread Javier Soto via swift-evolution
IMO the issue with the argument that we wouldn't be able to "monkey patch"
things on sealed classes is that that is already the nature of Swift. The
designer of an API can choose to use structs instead of classes, and then
there's already no way to "subclass". Moreover, "final" already exists, and
whether sealed is introduced or not, and whether it becomes the default or
not, API designers are already free to use final in all classes they do not
intend to be subclassed, so I think that would be an argument against final
existing in the first place, and that ship has already sailed.

As for whether sealed would allow for optimizations: my hunch is that it
would. However, as I write this I noticed a flaw with my proposal: I said
that sealed classes would be exported as final. This is only half-true.
They would in that they can't be subclassed outside the module, but there
could be subclasses in the same module! That means if the parent were to be
treated as final, code outside the module would incorrectly devirtualize
non-final methods.
On Tue, Jun 28, 2016 at 7:59 AM Charlie Monroe via swift-evolution <
swift-evolution@swift.org> wrote:

>
> > On Jun 28, 2016, at 4:55 PM, Sean Heber via swift-evolution <
> swift-evolution@swift.org> wrote:
> >
> >> On Jun 28, 2016, at 9:52 AM, Mark Lacey via swift-evolution <
> swift-evolution@swift.org> wrote:
> >>
> >>>
> >>> On Jun 27, 2016, at 9:10 PM, L. Mihalkovic via swift-evolution <
> swift-evolution@swift.org> wrote:
> >>>
> >>> -1 for the fact that if all devs can write working code, fewer can do
> it in a clear structured fashion that is well designed for extensibility.
> >>
> >> This sounds more like an argument for having sealed classes than not.
> As the proposal points out in the motivation, if the base class is not
> designed with subclassing in mind then overriding methods can result in
> unintended behavior (e.g. crashing, or other bugs).
> >
> > But I think the counter argument is, what if you need to fix or
> workaround unintended behavior of the class you’re trying to use?
>
> Typically you modify something open source - 99% of which is on GitHub.
> IMHO the best way is to either fork it and perhaps submit a pull request
> with the fix.
>
> But I understand that this is not always possible...
>
>
> >
> > l8r
> > Sean
> >
> > ___
> > 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
>
-- 
Javier Soto
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Sealed classes by default

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

> On Jun 28, 2016, at 4:55 PM, Sean Heber via swift-evolution 
>  wrote:
> 
>> On Jun 28, 2016, at 9:52 AM, Mark Lacey via swift-evolution 
>>  wrote:
>> 
>>> 
>>> On Jun 27, 2016, at 9:10 PM, L. Mihalkovic via swift-evolution 
>>>  wrote:
>>> 
>>> -1 for the fact that if all devs can write working code, fewer can do it in 
>>> a clear structured fashion that is well designed for extensibility.
>> 
>> This sounds more like an argument for having sealed classes than not. As the 
>> proposal points out in the motivation, if the base class is not designed 
>> with subclassing in mind then overriding methods can result in unintended 
>> behavior (e.g. crashing, or other bugs).
> 
> But I think the counter argument is, what if you need to fix or workaround 
> unintended behavior of the class you’re trying to use?

Typically you modify something open source - 99% of which is on GitHub. IMHO 
the best way is to either fork it and perhaps submit a pull request with the 
fix.

But I understand that this is not always possible...


> 
> l8r
> Sean
> 
> ___
> 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] [Proposal] Sealed classes by default

2016-06-28 Thread Mark Lacey via swift-evolution

> On Jun 27, 2016, at 9:10 PM, L. Mihalkovic via swift-evolution 
>  wrote:
> 
> -1 for the fact that if all devs can write working code, fewer can do it in a 
> clear structured fashion that is well designed for extensibility.

This sounds more like an argument for having sealed classes than not. As the 
proposal points out in the motivation, if the base class is not designed with 
subclassing in mind then overriding methods can result in unintended behavior 
(e.g. crashing, or other bugs).

Mark

> A couple months ago I even ran into difficulties when trying to extend 
> AlamoFire because some things had not been designed as cleanly as they could 
> have been to make extending it easy. So if the default is now that everything 
> becomes non-extensible but default, it is going to complicate (and partially 
> defeat the purpose of) reusing libraries.
> Regards
> (From mobile)
> 
> On Jun 28, 2016, at 2:11 AM, Michael Ilseman via swift-evolution 
> > wrote:
> 
>> I was also referring to how we present Objective-C classes in Swift. That 
>> is, if a Swift user tries to subclass an Objective-C-imported class, then 
>> we’d take into account sealed-ness in order to issue an error/warning, etc. 
>> If you are also proposing a Clang attribute for this, e.g. ‘swift_sealed’, 
>> to import as sealed (meaning issue an error if Swift users try to subclass 
>> it), then that should be spelled out as well. I don’t have an opinion on 
>> whether this is a good idea yet, just pointing out some more directions to 
>> explore. In general it feels like your proposal could use more fleshing out.
>> 
>> 
>>> On Jun 27, 2016, at 5:08 PM, Javier Soto >> > wrote:
>>> 
>>> That is a very good point, it should be explicitly mentioned in the 
>>> proposal. My thought would be that since in the Obj-C runtime it's not 
>>> possible to guarantee a class won't have subclasses, or that a method is 
>>> not overriden, Obj-C classes would be imported as open. 
>>> 
>>> On the Swift side, I think today it's possible to declare a "public final 
>>> @objc class", but you can still inherit from it from Obj-C, right? My hunch 
>>> would be that that should be disallowed, but perhaps there's a reason why 
>>> it's allowed today. 
>>> On Mon, Jun 27, 2016 at 4:25 PM Michael Ilseman >> > wrote:
>>> Could you elaborate on how we should treat classes imported from 
>>> Objective-C or CF-style C? That is, do we always annotate them as being 
>>> “open” because those paradigms permit subclassing anywhere, or do you 
>>> propose some kind of recommended “sealed” audit, or what?
>>> 
>>> 
 On Jun 27, 2016, at 3:40 PM, Javier Soto via swift-evolution 
 > wrote:
 
>>> 
 Hello!
 
 I sent this as a PR  on 
 the swift-evolution repo, but we never had any discussion about it 
 on-list, besides a long time ago 
 . 
 Here's the first draft of the proposal:
 
 
 Sealed classes by default
 
  
 Introduction
 
 Introduce a new sealed class modifier that makes classes and methods final 
 outside of the module they're declared in, but non-final within the module.
 
  
 Motivation
 
 It is not uncommon to have a need for a reference type without needing 
 inheritance. Classes must be intentionally designed to be subclassable, 
 carefully deciding which methods are the override entry-points such that 
 the the behavior remains correct and subclasses respect the Liskov 
 substitution principle 
 .
 Defaulting to non-final allows the author of a class to accidentally leave 
 the visible methods open for overrides, even if they didn't carefully 
 consider this possibility.
 Requiring that the author of a class mark a class as open is akin to 
 requiring symbols to be explicitly public: it ensures that a conscious 
 decision is made regarding whether the ability to subclass a class is part 
 of the API.
  
 Proposed
  solution
 
 New sealed (actual name pending bike-shedding) class modifier for classes 
 and methods which marks them as only overridable within 

Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-28 Thread Sean Heber via swift-evolution
> On Jun 28, 2016, at 9:52 AM, Mark Lacey via swift-evolution 
>  wrote:
> 
>> 
>> On Jun 27, 2016, at 9:10 PM, L. Mihalkovic via swift-evolution 
>>  wrote:
>> 
>> -1 for the fact that if all devs can write working code, fewer can do it in 
>> a clear structured fashion that is well designed for extensibility.
> 
> This sounds more like an argument for having sealed classes than not. As the 
> proposal points out in the motivation, if the base class is not designed with 
> subclassing in mind then overriding methods can result in unintended behavior 
> (e.g. crashing, or other bugs).

But I think the counter argument is, what if you need to fix or workaround 
unintended behavior of the class you’re trying to use?

l8r
Sean

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


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-28 Thread L. Mihalkovic via swift-evolution

Regards
LM
(From mobile)
> On Jun 28, 2016, at 1:57 PM, Alejandro Martinez via swift-evolution 
>  wrote:
> 
> Anton Zhilin: That is one of the points if I’m not mistaken. Sealed
> means that with whole-module-optimization the compiler can optimise
> more things as it can treat it as final for other modules.
> 
> L. Mihalkovic: Could you give an example of what exactly do you mean?
> I know one of the reasons behind the proposal is to actually improve
> those situations by forcing us to think more on customisation when
> designing APIs.

In many situation it has been my experience that libraries can be extended 
DESPITE their authors, rather than only thanks to the skills the authors  have 
shown in planning for the future. It is what happened to me with AlamoFire, 
where i was able to extend it because some cracks existed which let me do 
something the designers did not think about (to me it was a lack of imagination 
to not have anticipated what i wanted to do).

So if this can happen with a lib made by very experienced/talented developers, 
then imagine what happens with far less skilled developers.. it will mean 
having to copy code in order extend. It may sound pessimistic, but if u had 
seen as much bad code as i have seen, you might understand the view i am 
sharing.

What's worse is that objc is not particularly conducive to good software 
architecture (it is a bit like perl and javascript where anything can be 
touched from anywhere, and has a limited set of constructs compared to c++, 
scala, java, c#, swift). So i do not believe that it has prepared objc devs to 
suddenly become great code designers with a language that has multiples levels 
of scoping/nesting (i would not use most of the swift libs i have seen on 
github to teach software design).

Hence my conclusion that defaulting to sealed may be giving too much credit to 
the code that is currently available for reuse.


> 
> On Tue, Jun 28, 2016 at 12:44 PM, Anton Zhilin via swift-evolution
>  wrote:
>> Does `sealed` allow for any optimizations? Maybe somehow devirtualizing
>> method calls?
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> 
> 
> -- 
> Alejandro Martinez
> http://alejandromp.com
> ___
> 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] [Proposal] Sealed classes by default

2016-06-28 Thread David Rönnqvist via swift-evolution
All bike-shedding aside, I see two parts of this proposal and I come down on 
different sides for the two.

1. Introducing a new class modifier that acts as final outside the defining 
module
2. Changing the default to this new modifier (and thus also introducing a third 
explicit class modifier that represents the current default (non-final) 
behavior.

I think that the behavior of the new proposed modifier is useful. I imagine 
that it would allow for the same type of optimizations as a final class 
(assuming whole module optimizations) while remaining flexible within the 
module itself. We’re currently using a public protocol with one or more 
internal non-final classes to achieve similar results in the specific scenario 
where we want a unified external type. 

On the topic of changing the default, I’m against for the same reasons that was 
brought up in the discussion of making final the default. Since those reasons 
were mostly about usage outside of the same module, I find them equally valid 
in this case.

- David


> On 28 Jun 2016, at 00:40, Javier Soto via swift-evolution 
>  wrote:
> 
> Hello!
> 
> I sent this as a PR  on 
> the swift-evolution repo, but we never had any discussion about it on-list, 
> besides a long time ago 
> . 
> Here's the first draft of the proposal:
> 
> 
> Sealed classes by default
> 
>  
> Introduction
> 
> Introduce a new sealed class modifier that makes classes and methods final 
> outside of the module they're declared in, but non-final within the module.
> 
>  
> Motivation
> 
> It is not uncommon to have a need for a reference type without needing 
> inheritance. Classes must be intentionally designed to be subclassable, 
> carefully deciding which methods are the override entry-points such that the 
> the behavior remains correct and subclasses respect the Liskov substitution 
> principle .
> Defaulting to non-final allows the author of a class to accidentally leave 
> the visible methods open for overrides, even if they didn't carefully 
> consider this possibility.
> Requiring that the author of a class mark a class as open is akin to 
> requiring symbols to be explicitly public: it ensures that a conscious 
> decision is made regarding whether the ability to subclass a class is part of 
> the API.
>  
> Proposed
>  solution
> 
> New sealed (actual name pending bike-shedding) class modifier for classes and 
> methods which marks them as only overridable within the module they're 
> declared in.
> sealed becomes the default for classes and methods.
> New open (actual name pending bike-shedding) class modifier to explicitly 
> mark a class or a method as overridable.
>  
> Detailed
>  design
> 
> Code Examples:
> 
> /// ModuleA:
> 
> /// This class is `sealed` by default.
> /// This is equivalent to `sealed class SealedParentClass`
> class SealedParentClass {
> /// This method is `sealed` by default`.
> func foo()
> 
> /// This raises a compilation error: a method can't have a 
> "subclassability"
> /// level higher than that of its class.
> open func bar()
> 
> /// The behavior of `final` methods remains unchanged.
> final func baz()
> }
> 
> open class OpenParentClass {
> /// This method is `sealed` by default`.
> func foo()
> 
> /// Overridable methods in an `open` class must be explicitly marked as 
> `open`.
> open func bar()
> 
> /// The behavior of a `final` method remains unchanged.
> final func baz()
> }
> 
> /// The behavior of `final` classes remains unchanged.
> final class FinalClass { }
> /// ModuleB:
> 
> import ModuleA
> 
> /// This raises a compilation error: ParentClass is effectively `final` from
> /// this module's point of view.
> class SubclassA : SealedParentClass { }
> 
> /// This is allowed since `OpenParentClass` has been marked explicitly `open`
> class SubclassB : OpenParentClass {
> /// This raises a compilation error: `OpenParentClass.foo` is
> /// effectively `final` outside of `ModuleA`.
> override func foo() { }
> 
> /// This is allowed since `OpenParentClass.bar` is explicitly `open`.
> override func bar() { }
> }
>  
> 

Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-28 Thread Alejandro Martinez via swift-evolution
Anton Zhilin: That is one of the points if I’m not mistaken. Sealed
means that with whole-module-optimization the compiler can optimise
more things as it can treat it as final for other modules.

L. Mihalkovic: Could you give an example of what exactly do you mean?
I know one of the reasons behind the proposal is to actually improve
those situations by forcing us to think more on customisation when
designing APIs.

On Tue, Jun 28, 2016 at 12:44 PM, Anton Zhilin via swift-evolution
 wrote:
> Does `sealed` allow for any optimizations? Maybe somehow devirtualizing
> method calls?
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution



-- 
Alejandro Martinez
http://alejandromp.com
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-28 Thread Anton Zhilin via swift-evolution
Does `sealed` allow for any optimizations? Maybe somehow devirtualizing 
method calls?

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


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-28 Thread Haravikk via swift-evolution
I'm a tentative +1, but I think we might consider a degree of "sealing", e.g- 
make extending the type a warning rather than an error, or require an attribute 
in order to force the extension. In other words, we make it perfectly clear 
that extending anyway is a bad idea, but still allow it to be done in cases 
where code wasn't properly defined with this in mind. Perhaps we could consider 
something like sealed(warning) and sealed(error), with the former being the 
default?

> On 27 Jun 2016, at 23:40, Javier Soto via swift-evolution 
>  wrote:
> 
> Hello!
> 
> I sent this as a PR  on 
> the swift-evolution repo, but we never had any discussion about it on-list, 
> besides a long time ago 
> . 
> Here's the first draft of the proposal:
> 
> 
> Sealed classes by default
> 
>  
> Introduction
> 
> Introduce a new sealed class modifier that makes classes and methods final 
> outside of the module they're declared in, but non-final within the module.
> 
>  
> Motivation
> 
> It is not uncommon to have a need for a reference type without needing 
> inheritance. Classes must be intentionally designed to be subclassable, 
> carefully deciding which methods are the override entry-points such that the 
> the behavior remains correct and subclasses respect the Liskov substitution 
> principle .
> Defaulting to non-final allows the author of a class to accidentally leave 
> the visible methods open for overrides, even if they didn't carefully 
> consider this possibility.
> Requiring that the author of a class mark a class as open is akin to 
> requiring symbols to be explicitly public: it ensures that a conscious 
> decision is made regarding whether the ability to subclass a class is part of 
> the API.
>  
> Proposed
>  solution
> 
> New sealed (actual name pending bike-shedding) class modifier for classes and 
> methods which marks them as only overridable within the module they're 
> declared in.
> sealed becomes the default for classes and methods.
> New open (actual name pending bike-shedding) class modifier to explicitly 
> mark a class or a method as overridable.
>  
> Detailed
>  design
> 
> Code Examples:
> 
> /// ModuleA:
> 
> /// This class is `sealed` by default.
> /// This is equivalent to `sealed class SealedParentClass`
> class SealedParentClass {
> /// This method is `sealed` by default`.
> func foo()
> 
> /// This raises a compilation error: a method can't have a 
> "subclassability"
> /// level higher than that of its class.
> open func bar()
> 
> /// The behavior of `final` methods remains unchanged.
> final func baz()
> }
> 
> open class OpenParentClass {
> /// This method is `sealed` by default`.
> func foo()
> 
> /// Overridable methods in an `open` class must be explicitly marked as 
> `open`.
> open func bar()
> 
> /// The behavior of a `final` method remains unchanged.
> final func baz()
> }
> 
> /// The behavior of `final` classes remains unchanged.
> final class FinalClass { }
> /// ModuleB:
> 
> import ModuleA
> 
> /// This raises a compilation error: ParentClass is effectively `final` from
> /// this module's point of view.
> class SubclassA : SealedParentClass { }
> 
> /// This is allowed since `OpenParentClass` has been marked explicitly `open`
> class SubclassB : OpenParentClass {
> /// This raises a compilation error: `OpenParentClass.foo` is
> /// effectively `final` outside of `ModuleA`.
> override func foo() { }
> 
> /// This is allowed since `OpenParentClass.bar` is explicitly `open`.
> override func bar() { }
> }
>  
> Impact
>  on existing code
> 
> This would be a backwards-breaking change for all classes and methods that 
> are public and non-final, which code outside of their module has overriden. 
> Those classes/methods would fail to compile. Their superclass would need to 
> be changed to open.
>  
> Alternatives
>  considered
> 
> 

Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-27 Thread L. Mihalkovic via swift-evolution
-1 for the fact that if all devs can write working code, fewer can do it in a 
clear structured fashion that is well designed for extensibility. A couple 
months ago I even ran into difficulties when trying to extend AlamoFire because 
some things had not been designed as cleanly as they could have been to make 
extending it easy. So if the default is now that everything becomes 
non-extensible but default, it is going to complicate (and partially defeat the 
purpose of) reusing libraries.
Regards
(From mobile)

> On Jun 28, 2016, at 2:11 AM, Michael Ilseman via swift-evolution 
>  wrote:
> 
> I was also referring to how we present Objective-C classes in Swift. That is, 
> if a Swift user tries to subclass an Objective-C-imported class, then we’d 
> take into account sealed-ness in order to issue an error/warning, etc. If you 
> are also proposing a Clang attribute for this, e.g. ‘swift_sealed’, to import 
> as sealed (meaning issue an error if Swift users try to subclass it), then 
> that should be spelled out as well. I don’t have an opinion on whether this 
> is a good idea yet, just pointing out some more directions to explore. In 
> general it feels like your proposal could use more fleshing out.
> 
> 
>> On Jun 27, 2016, at 5:08 PM, Javier Soto  wrote:
>> 
>> That is a very good point, it should be explicitly mentioned in the 
>> proposal. My thought would be that since in the Obj-C runtime it's not 
>> possible to guarantee a class won't have subclasses, or that a method is not 
>> overriden, Obj-C classes would be imported as open. 
>> 
>> On the Swift side, I think today it's possible to declare a "public final 
>> @objc class", but you can still inherit from it from Obj-C, right? My hunch 
>> would be that that should be disallowed, but perhaps there's a reason why 
>> it's allowed today. 
>> On Mon, Jun 27, 2016 at 4:25 PM Michael Ilseman  wrote:
>>> Could you elaborate on how we should treat classes imported from 
>>> Objective-C or CF-style C? That is, do we always annotate them as being 
>>> “open” because those paradigms permit subclassing anywhere, or do you 
>>> propose some kind of recommended “sealed” audit, or what?
>>> 
>>> 
 On Jun 27, 2016, at 3:40 PM, Javier Soto via swift-evolution 
  wrote:
 
>>> 
 Hello!
 
 I sent this as a PR on the swift-evolution repo, but we never had any 
 discussion about it on-list, besides a long time ago. Here's the first 
 draft of the proposal:
 
 
 Sealed classes by default
 Introduction
 
 Introduce a new sealed class modifier that makes classes and methods final 
 outside of the module they're declared in, but non-final within the module.
 
 Motivation
 
 It is not uncommon to have a need for a reference type without needing 
 inheritance. Classes must be intentionally designed to be subclassable, 
 carefully deciding which methods are the override entry-points such that 
 the the behavior remains correct and subclasses respect the Liskov 
 substitution principle.
 Defaulting to non-final allows the author of a class to accidentally leave 
 the visible methods open for overrides, even if they didn't carefully 
 consider this possibility.
 Requiring that the author of a class mark a class as open is akin to 
 requiring symbols to be explicitly public: it ensures that a conscious 
 decision is made regarding whether the ability to subclass a class is part 
 of the API.
 Proposed solution
 
 New sealed (actual name pending bike-shedding) class modifier for classes 
 and methods which marks them as only overridable within the module they're 
 declared in.
 sealed becomes the default for classes and methods.
 New open (actual name pending bike-shedding) class modifier to explicitly 
 mark a class or a method as overridable.
 Detailed design
 
 Code Examples:
 
 /// ModuleA:
 
 /// This class is `sealed` by default.
 /// This is equivalent to `sealed class SealedParentClass`
 class SealedParentClass {
 /// This method is `sealed` by default`.
 func foo()
 
 /// This raises a compilation error: a method can't have a 
 "subclassability"
 /// level higher than that of its class.
 open func bar()
 
 /// The behavior of `final` methods remains unchanged.
 final func baz()
 }
 
 open class OpenParentClass {
 /// This method is `sealed` by default`.
 func foo()
 
 /// Overridable methods in an `open` class must be explicitly marked 
 as `open`.
 open func bar()
 
 /// The behavior of a `final` method remains unchanged.
 final func baz()
 }
 
 /// The behavior of `final` classes remains unchanged.
 final class FinalClass { }
 

Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-27 Thread Michael Ilseman via swift-evolution
I was also referring to how we present Objective-C classes in Swift. That is, 
if a Swift user tries to subclass an Objective-C-imported class, then we’d take 
into account sealed-ness in order to issue an error/warning, etc. If you are 
also proposing a Clang attribute for this, e.g. ‘swift_sealed’, to import as 
sealed (meaning issue an error if Swift users try to subclass it), then that 
should be spelled out as well. I don’t have an opinion on whether this is a 
good idea yet, just pointing out some more directions to explore. In general it 
feels like your proposal could use more fleshing out.


> On Jun 27, 2016, at 5:08 PM, Javier Soto  wrote:
> 
> That is a very good point, it should be explicitly mentioned in the proposal. 
> My thought would be that since in the Obj-C runtime it's not possible to 
> guarantee a class won't have subclasses, or that a method is not overriden, 
> Obj-C classes would be imported as open. 
> 
> On the Swift side, I think today it's possible to declare a "public final 
> @objc class", but you can still inherit from it from Obj-C, right? My hunch 
> would be that that should be disallowed, but perhaps there's a reason why 
> it's allowed today. 
> On Mon, Jun 27, 2016 at 4:25 PM Michael Ilseman  > wrote:
> Could you elaborate on how we should treat classes imported from Objective-C 
> or CF-style C? That is, do we always annotate them as being “open” because 
> those paradigms permit subclassing anywhere, or do you propose some kind of 
> recommended “sealed” audit, or what?
> 
> 
>> On Jun 27, 2016, at 3:40 PM, Javier Soto via swift-evolution 
>> > wrote:
>> 
> 
>> Hello!
>> 
>> I sent this as a PR  on 
>> the swift-evolution repo, but we never had any discussion about it on-list, 
>> besides a long time ago 
>> . 
>> Here's the first draft of the proposal:
>> 
>> 
>> Sealed classes by default
>> 
>>  
>> Introduction
>> 
>> Introduce a new sealed class modifier that makes classes and methods final 
>> outside of the module they're declared in, but non-final within the module.
>> 
>>  
>> Motivation
>> 
>> It is not uncommon to have a need for a reference type without needing 
>> inheritance. Classes must be intentionally designed to be subclassable, 
>> carefully deciding which methods are the override entry-points such that the 
>> the behavior remains correct and subclasses respect the Liskov substitution 
>> principle .
>> Defaulting to non-final allows the author of a class to accidentally leave 
>> the visible methods open for overrides, even if they didn't carefully 
>> consider this possibility.
>> Requiring that the author of a class mark a class as open is akin to 
>> requiring symbols to be explicitly public: it ensures that a conscious 
>> decision is made regarding whether the ability to subclass a class is part 
>> of the API.
>>  
>> Proposed
>>  solution
>> 
>> New sealed (actual name pending bike-shedding) class modifier for classes 
>> and methods which marks them as only overridable within the module they're 
>> declared in.
>> sealed becomes the default for classes and methods.
>> New open (actual name pending bike-shedding) class modifier to explicitly 
>> mark a class or a method as overridable.
>>  
>> Detailed
>>  design
>> 
>> Code Examples:
>> 
>> /// ModuleA:
>> 
>> /// This class is `sealed` by default.
>> /// This is equivalent to `sealed class SealedParentClass`
>> class SealedParentClass {
>> /// This method is `sealed` by default`.
>> func foo()
>> 
>> /// This raises a compilation error: a method can't have a 
>> "subclassability"
>> /// level higher than that of its class.
>> open func bar()
>> 
>> /// The behavior of `final` methods remains unchanged.
>> final func baz()
>> }
>> 
>> open class OpenParentClass {
>> /// This method is `sealed` by default`.
>> func foo()
>> 
>> /// Overridable methods in an `open` class must be explicitly marked as 
>> `open`.
>> open func bar()
>> 
>> /// The behavior of a `final` method remains unchanged.
>> final func baz()
>> }
>> 
>> /// The behavior of `final` classes remains 

Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-27 Thread Javier Soto via swift-evolution
That is a very good point, it should be explicitly mentioned in the
proposal. My thought would be that since in the Obj-C runtime it's not
possible to guarantee a class won't have subclasses, or that a method is
not overriden, Obj-C classes would be imported as open.

On the Swift side, I think today it's possible to declare a "public final
@objc class", but you can still inherit from it from Obj-C, right? My hunch
would be that that should be disallowed, but perhaps there's a reason why
it's allowed today.
On Mon, Jun 27, 2016 at 4:25 PM Michael Ilseman  wrote:

> Could you elaborate on how we should treat classes imported from
> Objective-C or CF-style C? That is, do we always annotate them as being
> “open” because those paradigms permit subclassing anywhere, or do you
> propose some kind of recommended “sealed” audit, or what?
>
> On Jun 27, 2016, at 3:40 PM, Javier Soto via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> Hello!
>
> I sent this as a PR 
> on the swift-evolution repo, but we never had any discussion about it
> on-list, besides a long time ago
> .
> Here's the first draft of the proposal:
>
>
> Sealed classes by default
> 
> Introduction
>
> Introduce a new sealed class modifier that makes classes and methods final
>  outside of the module they're declared in, but non-final within the
> module.
>
> 
> Motivation
>
>- It is not uncommon to have a need for a reference type without
>needing inheritance. Classes must be intentionally designed to be
>subclassable, carefully deciding which methods are the override
>entry-points such that the the behavior remains correct and subclasses
>respect the Liskov substitution principle
>.
>- Defaulting to non-final allows the author of a class to accidentally
>leave the visible methods open for overrides, even if they didn't carefully
>consider this possibility.
>- Requiring that the author of a class mark a class as open is akin to
>requiring symbols to be explicitly public: it ensures that a conscious
>decision is made regarding whether the ability to subclass a class is
>part of the API.
>
>
> Proposed
> solution
>
>- New sealed (*actual name pending bike-shedding*) class modifier for
>classes and methods which marks them as only overridable within the module
>they're declared in.
>- sealed becomes the default for classes and methods.
>- New open (*actual name pending bike-shedding*) class modifier to
>explicitly mark a class or a method as overridable.
>
>
> Detailed
> design
>
> Code Examples:
>
> /// ModuleA:
> /// This class is `sealed` by default./// This is equivalent to `sealed class 
> SealedParentClass`class SealedParentClass {
> /// This method is `sealed` by default`.
> func foo()
>
> /// This raises a compilation error: a method can't have a 
> "subclassability"
> /// level higher than that of its class.
> open func bar()
>
> /// The behavior of `final` methods remains unchanged.
> final func baz()
> }
>
> open class OpenParentClass {
> /// This method is `sealed` by default`.
> func foo()
>
> /// Overridable methods in an `open` class must be explicitly marked as 
> `open`.
> open func bar()
>
> /// The behavior of a `final` method remains unchanged.
> final func baz()
> }
> /// The behavior of `final` classes remains unchanged.final class FinalClass 
> { }
>
> /// ModuleB:
> import ModuleA
> /// This raises a compilation error: ParentClass is effectively `final` 
> from/// this module's point of view.class SubclassA : SealedParentClass { }
> /// This is allowed since `OpenParentClass` has been marked explicitly 
> `open`class SubclassB : OpenParentClass {
> /// This raises a compilation error: `OpenParentClass.foo` is
> /// effectively `final` outside of `ModuleA`.
> override func foo() { }
>
> /// This is allowed since `OpenParentClass.bar` is explicitly `open`.
> override func bar() { }
> }
>
>
> Impact
> on existing code
>
>- This would be a backwards-breaking change 

Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-27 Thread Michael Ilseman via swift-evolution
Could you elaborate on how we should treat classes imported from Objective-C or 
CF-style C? That is, do we always annotate them as being “open” because those 
paradigms permit subclassing anywhere, or do you propose some kind of 
recommended “sealed” audit, or what?

> On Jun 27, 2016, at 3:40 PM, Javier Soto via swift-evolution 
>  wrote:
> 
> Hello!
> 
> I sent this as a PR  on 
> the swift-evolution repo, but we never had any discussion about it on-list, 
> besides a long time ago 
> . 
> Here's the first draft of the proposal:
> 
> 
> Sealed classes by default
> 
>  
> Introduction
> 
> Introduce a new sealed class modifier that makes classes and methods final 
> outside of the module they're declared in, but non-final within the module.
> 
>  
> Motivation
> 
> It is not uncommon to have a need for a reference type without needing 
> inheritance. Classes must be intentionally designed to be subclassable, 
> carefully deciding which methods are the override entry-points such that the 
> the behavior remains correct and subclasses respect the Liskov substitution 
> principle .
> Defaulting to non-final allows the author of a class to accidentally leave 
> the visible methods open for overrides, even if they didn't carefully 
> consider this possibility.
> Requiring that the author of a class mark a class as open is akin to 
> requiring symbols to be explicitly public: it ensures that a conscious 
> decision is made regarding whether the ability to subclass a class is part of 
> the API.
>  
> Proposed
>  solution
> 
> New sealed (actual name pending bike-shedding) class modifier for classes and 
> methods which marks them as only overridable within the module they're 
> declared in.
> sealed becomes the default for classes and methods.
> New open (actual name pending bike-shedding) class modifier to explicitly 
> mark a class or a method as overridable.
>  
> Detailed
>  design
> 
> Code Examples:
> 
> /// ModuleA:
> 
> /// This class is `sealed` by default.
> /// This is equivalent to `sealed class SealedParentClass`
> class SealedParentClass {
> /// This method is `sealed` by default`.
> func foo()
> 
> /// This raises a compilation error: a method can't have a 
> "subclassability"
> /// level higher than that of its class.
> open func bar()
> 
> /// The behavior of `final` methods remains unchanged.
> final func baz()
> }
> 
> open class OpenParentClass {
> /// This method is `sealed` by default`.
> func foo()
> 
> /// Overridable methods in an `open` class must be explicitly marked as 
> `open`.
> open func bar()
> 
> /// The behavior of a `final` method remains unchanged.
> final func baz()
> }
> 
> /// The behavior of `final` classes remains unchanged.
> final class FinalClass { }
> /// ModuleB:
> 
> import ModuleA
> 
> /// This raises a compilation error: ParentClass is effectively `final` from
> /// this module's point of view.
> class SubclassA : SealedParentClass { }
> 
> /// This is allowed since `OpenParentClass` has been marked explicitly `open`
> class SubclassB : OpenParentClass {
> /// This raises a compilation error: `OpenParentClass.foo` is
> /// effectively `final` outside of `ModuleA`.
> override func foo() { }
> 
> /// This is allowed since `OpenParentClass.bar` is explicitly `open`.
> override func bar() { }
> }
>  
> Impact
>  on existing code
> 
> This would be a backwards-breaking change for all classes and methods that 
> are public and non-final, which code outside of their module has overriden. 
> Those classes/methods would fail to compile. Their superclass would need to 
> be changed to open.
>  
> Alternatives
>  considered
> 
> Defaulting to final instead: This would be comparable to Swift defaulting to 
> private, as opposed to internal. Just like internal is a better trade-off, 
> sealed by default also makes sure that getting started