I'd strongly favor correcting this inconsistency; I’ve run into it and been confused until I remembered the semantics more than once. I would much prefer always explicitly specifying the access modifier to receive its effect (versus changing the documentation) - in short I agree that extensions should be internal until declared otherwise.
-- Gwynne Raskind > On Jun 20, 2016, at 03:35, Adrian Zubarev via swift-evolution > <[email protected]> wrote: > > Everyone does feel comfortable with implicit public extensions? > > > > > -- > Adrian Zubarev > Sent with Airmail > > Am 19. Juni 2016 um 09:18:35, Adrian Zubarev ([email protected] > <mailto:[email protected]>) schrieb: > >> One problem I found with the mentioned suggestion of mine is this: >> >> public protocol A {} >> >> public class B {} >> >> // 'public' modifier cannot be used with >> // extensions that declare protocol conformances >> public extension B: A {} >> Why is that like this? >> Can this be fixed? >> Implicit public extension feels odd and is inconsistent if you ask me. >> Any statement to the pitched suggestion? >> >> >> >> -- >> Adrian Zubarev >> Sent with Airmail >> >> Am 17. Juni 2016 um 11:28:18, Adrian Zubarev >> ([email protected] <mailto:[email protected]>) >> schrieb: >> >>> I’ve spotted some inconsistency on access control modifier I’d like to >>> discuss in this thread (the behavior is not groundbreaking but inconsistent >>> from readers and developers view perspective). >>> >>> Why are extensions not marked as public in public apis when the module is >>> imported? >>> >>> Any type members added in an extension have the same default access level >>> as type members declared in the original type being extended. If you extend >>> a public or internal type, any new type members you add will have a default >>> access level of internal. If you extend a private type, any new type >>> members you add will have a default access level of private. >>> >>> Alternatively, you can mark an extension with an explicit access level >>> modifier (for example, private extension) to set a new default access level >>> for all members defined within the extension. This new default can still be >>> overridden within the extension for individual type members. >>> >>> Source: Apple Inc. The Swift Programming Language (Swift 2.2). >>> This does not tell us how the access control modifier works on extensions. >>> Here are three examples: >>> public struct A {} >>> >>> /* implicitly internal */ extension A {} >>> >>> // This extension won't be exported >>> as soon as at least one member modifier of an extension is public (if the >>> extended type allows that and is also public), the extension itself becomes >>> implicitly public: >>> public struct B {} >>> >>> /* implicitly public */ extension B { >>> >>> public func foo() {} >>> >>> /* implicitly internal */ func boo() {} >>> } >>> >>> // This extension will be exported as >>> >>> extension B { >>> >>> public func foo() >>> } >>> This is inconsistent to other types, because you can not leave out the >>> modifier for instance on classes, then add a public member and assume that >>> your class is implicitly public! The compiler knows that and provides a >>> correct warning that the mentioned class is internal. >>> >>> public struct C {} >>> >>> public extension C { >>> >>> public func foo() {} >>> >>> /* implicitly internal */ func boo() {} >>> } >>> >>> // This extension will be exported as >>> >>> /* public is missing here */ extension C { >>> >>> public func foo() >>> } >>> Extensions seem to behave differently and its behaviors is inconsistent and >>> not documented. >>> >>> protocols has explicit public modifier on its members when the module is >>> imported. However, 'public' modifier cannot be used in protocols is how the >>> compiler treat modifiers in protocols on declaration. >>> >>> public protocol D { >>> >>> func doSomething() >>> } >>> Protocol D will be exported as: >>> >>> public protocol D { >>> >>> public func doSomething() >>> } >>> Here is my suggestion: >>> >>> Fix the behavior for extensions and document it correctly: >>> >>> public struct B {} >>> >>> /* implicitly public */ extension B { >>> >>> public func foo() {} >>> >>> /* implicitly internal */ func boo() {} >>> } >>> Such an extension should not be implicitly public and behave like other >>> types and stay implicitly internal. >>> The compiler should provide a warning for the foo() function: Declaring a >>> public function for an internal type >>> Extensions should have explicit public modifier like other types if the >>> extension was marked as public and was imported into an other >>> project/module. >>> This inconsistent behavior is source breaking and I’d suggest this change >>> to happen in Swift 3! >>> Remove public modifier from imported protocols OR document this behavior >>> correctly! >>> >>> >>> >>> -- >>> Adrian Zubarev >>> Sent with Airmail >> > > > _______________________________________________ > swift-evolution mailing list > [email protected] <mailto:[email protected]> > https://lists.swift.org/mailman/listinfo/swift-evolution > <https://lists.swift.org/mailman/listinfo/swift-evolution>
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
