[swift-evolution] Proposal: Add public(objc) modifier

Kevin Ballard kevin at sb.org
Tue Jan 5 17:17:45 CST 2016


Why would you need to change the call sites? If you have existing Swift
code that calls these Obj-C entrypoints, you simply wouldn't mark them
as `public(objc)` but would just leave them as, well, public API.

There's nothing about this proposal that *forces* you to use it. You can
continue to expose API to Obj-C the same way you do today. But the
entire point of public(objc) is to expose API to Obj-C *without*
exposing it to Swift as well (because there's already a better API
exposed to Swift).

-Kevin Ballard

On Tue, Jan 5, 2016, at 03:15 PM, Félix Cloutier wrote:
> I can't agree to that. If I gradually port an API from Objective-C to
> Swift and at some point decide to go back to make a Swiftier entry
> point, I'll be very disappointed that I need to change the call sites
> to the Objective-C-compatible one, not because something will break,
> but because the Swift mailing list thought Swift would be purer if I
> couldn't use it.
>
> Félix
>
>> Le 5 janv. 2016 à 17:56:42, Kevin Ballard <kevin at sb.org> a écrit :
>>
>> Code completion aside, it just makes me really unhappy to expose a
>> Swift API that nobody should *ever* call from Swift. I just don't
>> want to have that API be accessible at all when it only exists to
>> serve as the Obj-C entrypoint.
>>
>> -Kevin Ballard
>>
>> On Tue, Jan 5, 2016, at 02:55 PM, Félix Cloutier wrote:
>>> .NET has an EditorBrowsable[1] attribute that controls whether
>>> things appear in autocomplete or not. I think that this alternative
>>> deserves some consideration.
>>>
>>> It clearly won't have identical semantics, but I think that it would
>>> be a little more graceful and much less involved. This solution only
>>> needs a new attribute and SourceKit changes.
>>>
>>> Félix
>>>
>>>> Le 5 janv. 2016 à 15:23:55, Kevin Ballard via swift-evolution <swift-
>>>> evolution at swift.org> a écrit :
>>>>
>>>> Proposal PR submitted as
>>>> https://github.com/apple/swift-evolution/pull/85
>>>>
>>>> -Kevin Ballard
>>>>
>>>> On Tue, Dec 15, 2015, at 11:18 AM, Kevin Ballard wrote:
>>>>> When writing ObjC code, there's a macro NS_REFINED_FOR_SWIFT (or
>>>>> __attribute__((swift_private))) that mangles the name when
>>>>> imported into Swift. The intention here is to hide an API from
>>>>> normal Swift usage (but still make it callable) so that a better
>>>>> Swift API can be written around it.
>>>>>
>>>>> But there's no facility for doing this in reverse. You can expose
>>>>> Swift APIs to ObjC, but the API has to be ObjC-compatible. Which
>>>>> means that if you have a non-ObjC-compatible API, you have to
>>>>> write a separate API to expose it to ObjC, and this separate API
>>>>> now shows up in the Swift API too.
>>>>>
>>>>> I think the simplest way to fix this is to allow for a modifier
>>>>> public(objc) (following the syntax of private(set)). The only
>>>>> thing this modifier does is ensure the declaration gets added to
>>>>> the generated header as if it were public (or—for apps—internal).
>>>>> If the declaration is not marked as @objc then it would emit an
>>>>> error (it could imply @objc but it feels weird to me to have an
>>>>> access control modifier do that). If the declaration is already
>>>>> public (but not internal, so the same source can be used in apps
>>>>> and libraries) it will emit a warning.
>>>>>
>>>>> Armed with this new modifier, I can start to write code like
>>>>>
>>>>> class MyClass: NSObject {    func foo<T>(x: T) { ... } }
>>>>>
>>>>> extension MyClass {    @objc(foo) public(objc) private func
>>>>> __foo(x: AnyObject) { ... } }
>>>>>
>>>>> When used on a property that already has private(set), the
>>>>> public(objc) modifier will only apply to the getter (e.g. the
>>>>> private(set) takes precedence for the setter).
>>>>>
>>>>> Alternatives:
>>>>>
>>>>> * Add a new attribute @export_objc that has the same behavior.
>>>>>
>>>>> * Change the @objc attribute to take an optional second argument,
>>>>>   which may be the token "exported", as in @objc(foo,exported).
>>>>>   When using the "exported" token, the selector portion is
>>>>>   required. We could possibly support an empty selector to
>>>>>   indicate the default, as in @objc(,exported), but that looks
>>>>>   odd.
>>>>>
>>>>> My preference is for public(objc) as proposed as it matches more
>>>>> closely with the intended behavior, which is "this API is private
>>>>> in Swift and public in ObjC".
>>>>>
>>>>> -Kevin Ballard
>>>> _______________________________________________
>>>> swift-evolution mailing list swift-evolution at swift.org
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>



Links:

  1. https://msdn.microsoft.com/en-us/library/system.componentmodel.editorbrowsableattribute(v=vs.110).aspx
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160105/46437902/attachment.html>


More information about the swift-evolution mailing list