[swift-evolution] [Proposal] Nested extensions

Tino Heth 2th at gmx.de
Fri Apr 14 07:54:38 CDT 2017


Hi Tony,

> Sorry to be a (hopefully polite) ogre, but from my perspective, your proposal does not address nor nullify the issues with access modifier levels in Swift, and I don’t think you should be pitching it as a stop-gap. It could make the use of extensions consistent with other similar declarations, but ultimately the access modifier level issues remain. 
Maybe this will be the case forever: Some people seem to have an affection for such things that goes far beyond my personal requirements, so I have no idea what someone else might come up with (I've already been joking about "cryptographic inheritance", which would allow you to override something only if you know the right transformation for the checksum of your new implementation ;-).
None the less, the concept is the most versatile I've have seen so far, yet it is less complex than some alternatives.

Right now, you can have your private properties in type declarations and extensions protected from all other types and extensions in the same file, and people say they want to have this option, so SE-0169 would hurt them.
Other people want same-file extensions to share private parts, and, at the same time, hide them from alien types in the same file (therefor, they don't want to use fileprivate).
Those two standpoints could coexist in Swift if we added another access modifier, but even if someone has a better name than "fileprivateButVisibleToSameTypeExtensionsInThisFile", this wouldn't be that nice…

Nested extensions, on the other hand, would require no new modifiers (actually, it would render fileprivate superfluous), and all you would have to do to have the effect of SE-0169 would be putting your extensions between an existing pair of curly braces, instead of placing them below that block.
I don't know about your specific issues with access levels, but the ones I have read about can be solved.

> - Can you clarify for me: does this proposal suggest allowing extensions on the enclosing type to be nested within the type declaration, or within other extensions on the original type? If so, can you please word that more clearly.
Both: Whatever is possible outside the curly braces should be possible between them as well (at least I have no spontaneous example for something that should be forbidden).

> - I would like to see some examples of the proposed syntax included in your proposal (perhaps via a link to the markdown source on GitHub?). Best case and worst case examples would show what impact it will have on readability and file length when someone goes a bit nuts with this feature.
No rules will stop people doing stupid things, but I'd rather give the people a tool they could use to harm their codebase, instead of bugging all users of Swift by trying to make it foolproof.
The linked discussion has an example - I'll attach it here as well, because the HTML has no syntax colouring ;-)

> - Do you know how much work will be required to implement this change at this stage? Is it feasible within the bounds of the time remaining before Swift 4’s release?
Well, one major positive aspect of the idea is that there is no need to hurry:
I have an impression that we are in danger to make decisions without taking enough time to think about their consequences, just because a proposal should be part of the next release.
Nested extensions wouldn't break anything, so we could just leave this topic alone for now and include it in Swift 5 or 6 — or never, I someone has a better idea in the meantime.
SE-0169, on the other hand, would be yet another breaking change, and some people think it would harm Swift 4 and possible all versions to come after...

> Off-topic suggestion: Using the words “Simply” or “just” when describing work to be done by others is something that you should avoid (unless you’ve already implemented the feature and there’s a PR sitting on GitHub, ready to go). Removing those words allows the sentences to communicate the same ideas, but they no longer trivialise the size/scope of the work to be done during implementation.
Oh yes, especially that last one — I did not find the fitting word yet, but I have to agree that this part could be interpreted in a way that wasn't intended.

> At this stage, I’m really not sure whether I’d add my support for this proposal were it to go to review, but hopefully my comments are useful.

Well, I expected little more than a handful of comments saying "I like X better" and general disregard, so "I might support it" is already quite positive ;-)

- Tino

class MyVC: UIViewController {
    private let numberOfSections = 0

    extension: UITableViewDataSource {
        // Skipping the class and assume we want to extend the surrounding type
        func numberOfSections(in tableView: UITableView) -> Int {
            return numberOfSections
        }

        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return 0
        }
    }

    private extension {
        // this would contain everything that shoudn't be visible for other extensios

        var secret: Int = 0

        public extension MyFriendClass {
            // oh, well, I make an exception here for a trustworthy type
            func checkSecret(of controller: MyVC) -> Bool {
                return controller.secret > 0
            }
        }

        private extension {
            // this is so secret, I'm not even allowed to copy it
        }
    }

    public func myMethod() {
        print("This is just a boring method")
    }
}

It has the downside of shifting code to the right (you could as well leave those extension-blocks unindented), but lots of advantages:
- No change for private needed
- It can be nested as much as you like to satisfy even the most absurd desires of encapsulation
- It reminds me on operator definitions inside type declarations 
- No change for fileprivate needed (but actually, I think there is very little need to keep fileprivate)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170414/edaaafd6/attachment.html>


More information about the swift-evolution mailing list