On 18 July 2016 at 16:06, Károly Lőrentey <[email protected]> wrote: > On 2016-07-18 16:15:10 +0000, Leonardo Pessoa via swift-evolution said: > >> I believe sealed by default applied to functions makes the behaviour >> consistent with classes and allows for the same behaviour we wanted >> with this proposal. It would allows us to create subclassable classes >> in which we would be able to internally override a method but not >> outside the library and selectively allow other methods to be >> overriden. Final won't do it so if this is not the default behaviour, >> it will be necessary to introduce the sealed keyword so we can achieve >> this. > > > Can you give an example where you'd need such a sealed method, but the > obvious pattern I described wouldn't work?
I'm not saying your pattern doesn't work; I'm saying it requires more code. >> It's inconsistent to have to explicitly open a class and >> explicitly seal its methods and vice-versa. It was my assumption that >> when we chose sealed by default with the proposal we were talking >> about everything and not just classes (I at least was talking >> everything). > > > This was my assumption as well, but then I thought things through. I suspect > this might be what our friendly review manager was getting at when he gently > lamented the lack of sufficient discussion on "overridable". > >> Introducing "dynamic" or some other keyword to mark explicitly methods >> that should be overriden is just the same "open" with sealed methods >> by default would mean for public methods so it makes no difference to >> me. > > > "dynamic" is already in the language. It changes method dispatch to use > Objective-C style message passing, enabling advanced techniques based on the > dynamic runtime, such as method swizzling or KVO. Since it already exists, > I'm not arguing for its introduction; I merely want it integrated into the > proposal, in order to keep the language coherent. When I was talking "dynamic" here, I was meaning as in .NET (dynamic is required to say a method can be overriden). Perhaps I was misguided here. >> Also having no default will not change that some library >> developers will have everything sealed and selectively open. >> No default shall also make developers prone to open to think more about >> the keyword they'll choose to use, > > > Exactly! For this particular corner of the language, it fulfills the > "unwavering goal of requiring additional thought when publishing a class as > public API". Forcing people to make an explicit choice is by far the most > straightforward way to achieve this. It also has the nice property of being > harder to interpret as a value judgement on overridability, which is clearly > a topic that gets people's monocles popping. ಠ_ರೃ > >> but I'm not fond of no default. > > > If adding an extra qualifier turns out to be an onerous requirement, we can > choose a default at any time later, without breaking existing code. It'll > probably be easier to do so once we have a little experience in actually > using the new language. So should we drop internal by default too? >> As for the inheritance of openness, I firmly believe it shouldn't. If >> a class inherited from an open class is open by default, there will be >> no libraries making use of other libraries or we should also introduce >> the sealed keyword in order to make the class (or method) sealed >> again. This behaviour seems inconsistent to me too. > > > Agreed. > > >> >> L >> >> >> On 18 July 2016 at 09:07, Károly Lőrentey <[email protected]> >> wrote: >>> >>> On 2016-07-18 09:17:43 +0000, David Hart via swift-evolution said: >>> >>>> On 18 Jul 2016, at 11:11, Xiaodi Wu via swift-evolution >>>> <[email protected]> wrote: >>>> >>>> On Mon, Jul 18, 2016 at 3:27 AM, Brent Royal-Gordon via swift-evolution >>>> <[email protected]> wrote: >>>>> >>>>> On Jul 17, 2016, at 8:57 PM, L. Mihalkovic via swift-evolution >>>>> <[email protected]> wrote: >>>>> >>>>>> On Jul 17, 2016, at 9:14 PM, Garth Snyder via swift-evolution >>>>>> <[email protected]> wrote: >>>>>> >>>>>> Is there a summary somewhere of the motivation for allowing methods to >>>>>> be declared non-overridable within open classes? >>>> >>>> [...] >>>> Garth: I think it's implicit in the reasons to prevent subclassing. The >>>> mere fact that a class allows subclassing doesn't necessarily mean that >>>> every member in it is designed to be subclassed. Consider >>>> `UIViewController`: It's obviously designed to be subclassed, and some >>>> methods in it (such as `loadView`) are intended to be overridden, but >>>> others >>>> (such as `loadViewIfNeeded`) are *not* intended to be overridden. >>>> >>>> And [if UIViewController were to be written in Swift] there'd be a good >>>> reason why `loadViewIfNeeded` and others of its ilk couldn't be final? >>>> >>>> I don't know UIKit internals, but I could imagine loadViewIfNeeded be >>>> overridden internally, if one knows the precise internal workings of >>>> UIViewController. That would require open, to allow overriding >>>> internally >>>> but not externally. >>> >>> >>> >>> >>> I thought about this aspect a little more. I think it's fair to say that >>> we're breaking new ground for language design here. Classes limiting >>> inheritance to a certain set of subclasses are nothing new (I've written >>> & >>> used classes doing this in C++, Java and C#), but no language that I know >>> of >>> allows limiting overrides of a specific public member in such a way. I >>> think >>> we need a convincing rationale for making this esoteric middle ground >>> between final and open members the new default. >>> >>> The UIKit example above isn't convincing at all. It is already quite easy >>> to >>> allow package-internal subclasses to configure the behavior of >>> loadViewIfNeeded without such a novel language feature. E.g., the UIKit >>> team >>> can simply make loadViewIfNeeded call into a non-final but internal >>> method: >>> >>> public open class UIViewController { >>> private var _view: UIView? = nil >>> >>> public final func loadViewIfNeeded() { >>> internalLoadViewIfNeeded() >>> } >>> >>> internal func internalLoadViewIfNeeded() { // overridable internally >>> if let view = _view { return } >>> loadView() >>> } >>> >>> public open func loadView() { >>> // Load it from a nib or whatevs >>> } >>> } >>> >>> I see no drawback to this pattern; it is quite clear and simple. >>> Therefore, >>> in the interest of keeping the language free of needless complexity, I >>> suggest we change the proposal to remove the implicit "sealed" level of >>> public member overridability, and support only "open" or "final" class >>> members. >>> >>> For members, "open" should mean the opposite of "final", with no levels >>> in >>> between. Member-level openness should be entirely independent of >>> visibility; >>> so it should be possible to say "internal open" to mean an internally >>> overridable member that's not at all visible outside the module -- the >>> same >>> as today's default. >>> >>> (Note that (on platforms with an Objective-C runtime) "dynamic" provides >>> a >>> third level of flexibility for class members; I argue that it should >>> imply >>> "open". So in order of increasing flexibility, we'd have "final", "open" >>> and >>> "dynamic" members. This seems easy enough to describe and understand.) >>> >>> I also suggest that for now, we should make neither "final" nor "open" >>> nor >>> "dynamic" the default for public members of open classes: we should >>> rather >>> require class authors to explicity add one of these qualifiers to all >>> public >>> member declarations. This way, we can defer the argument for choosing a >>> default to a later (additive) proposal, once we have some experience with >>> this setup. Non-public members can safely keep defaulting to "internal >>> open", like they do today. >>> >>> -- >>> Károly >>> @lorentey >>> >>> >>> >>> _______________________________________________ >>> swift-evolution mailing list >>> [email protected] >>> https://lists.swift.org/mailman/listinfo/swift-evolution >> >> _______________________________________________ >> swift-evolution mailing list >> [email protected] >> https://lists.swift.org/mailman/listinfo/swift-evolution > > > > -- > Károly > @lorentey > > > _______________________________________________ > swift-evolution mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-evolution _______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
