> On Aug 19, 2016, at 12:56 PM, Jonathan Hull <[email protected]> wrote: > > For my own education, how is does it break the encapsulation in a way which > subclassing does not? I may not have mentioned it, but in my mind, this > construct would be limited by the compiler to being called from within a > conforming type (in the same way super is). Given that,
You did not, in fact, mention that. :) Like "super", you would still want to restrict this to "self", or at the very least to only objects of your own class type, so that you can't just make a subclass and then apply it to an arbitrary object. In that case, it's basically just super dispatch, except that you can go to an arbitrary protocol-extension implementation. (Unless you really want to be able to skip your superclass's implementation, which is encapsulation-breaking again.) John. > it seems to me that the considerations by both the ancestor class and the > subclass would be exactly the same as in a super-subclass relationship. I > agree that it wouldn’t be a frequent use case, but I have definitely had > times where it would have greatly simplified my class structure if allowed. > I don’t see any reason to limit it (beyond the needs of the type), but I > could easily be missing something fairly obvious... > > Thanks, > Jon > >> On Aug 17, 2016, at 6:57 PM, John McCall <[email protected] >> <mailto:[email protected]>> wrote: >> >>> On Aug 17, 2016, at 5:46 PM, Jonathan Hull via swift-evolution >>> <[email protected] <mailto:[email protected]>> wrote: >>> >>> I believe this affects the ABI (especially the second part), but if not, >>> let me know and we can talk about it in phase 2... >>> >>> There are times where you would like to call a specific implementation of a >>> method. One of the most common is calling super from a subclass, but you >>> may want to do similar things when overriding a default implementation of a >>> protocol. I also have definitely had times where I wanted to call the >>> implementation of an ancestor other than super. It also solves some of the >>> issues that came up during the non-subclassable by default discussion, >>> because it allows you to statically dispatch to a known implementation in >>> cases where you need that assurance, but don’t want to mark a method final. >>> (essentially it gives you the benefits of final for a single call) >>> >>> Here are a couple of potential ideas on how to represent this (P represents >>> a protocol or class ancestor type): >>> >>> varName.P::methodName >>> >>> varName.methodName using P >>> >>> >>> This is mainly to start a discussion, so feel free to counter-propose a >>> better syntax, etc… >>> >>> It seems fairly straightforward to me. The only objection that I remember >>> coming up when this was discussed before was that the compiler had to keep >>> some information around between modules that it wasn’t keeping around at >>> the time (which is what makes me think it affects the ABI). >>> >>> One complication which could come up is what happens when P is a variable >>> holding a type instead of a constant type. There are a few options: >>> >>> 1) Don’t allow such shenanigans (compiler error) >>> >>> 2) Dynamically dispatch based on a runtime check (trap at runtime if P is >>> not an ancestor/conformed-to protocol) >>> >>> 3) Same as 2, except that the protocol conformance uses duck-typing >>> >>> 4) Same as 2/3, except the command is not executed instead of trapping >>> >>> Of those options, 1 is the simplest, but 3 is my favorite, as it is the >>> most powerful (but also has the largest impact on the ABI). 4 could >>> co-exist with 2/3 by adding a ‘?’ variant of the syntax (e.g. >>> varName.P?::methodName) >>> >>> Thoughts? >> >> I think being able to name and call a specific protocol-extension method >> would be an interesting enhancement. >> >> Being able to bypass another class's overrides and jump to a specific >> superclass implementation on an arbitrary method call is badly >> encapsulation-breaking, and I can't think of any OO language with >> first-class support for it besides C++. In every other language I know of, >> super dispatch is always restricted to the self object and only bypasses the >> overrides of the current class and its subclasses. Of course there are >> runtime tricks you can play to get this in, say, ObjC, but I'm not aware of >> them being frequently used. I would really to see concrete evidence of this >> being useful and necessary before considering it any further. >> >> John. >
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
