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

Reply via email to