> On Mar 22, 2017, at 10:55 PM, Brent Royal-Gordon via swift-evolution
> <[email protected]> wrote:
>
>> On Mar 21, 2017, at 11:03 PM, Chris Lattner via swift-evolution
>> <[email protected]> wrote:
>>
>> * What is your evaluation of the proposal?
>
> I'm going to have to come down on the "no" side on this one.
>
> I'm actually not worried about methods so much as properties. KVC is
> completely untyped on the Objective-C side, and there are several different
> mechanisms there which use KVC with poorly validated external strings, like
> bindings, sort descriptors, and predicates. Tons of migration errors are
> going to escape into production if we do this,
We can avoid these by migrating conservatively (have the migrator add @objc
everywhere it’s inferred in Swift 3).
> and undetectable mistakes are going to continue on an ongoing basis.
… but what you say above is definitely true: the error of omission of @objc
will cause breakage for these cases.
> Have we explored alternate implementations? For instance, when the compiler
> can statically determine all of the call sites for an `@objc` member, could
> we emit *only* an implementation with the Objective-C calling convention and
> call that directly from Swift?
>
> Could members with binary-compatible signatures share a thunk? The
> Objective-C calling convention includes a selector parameter, so you can
> still determine the desired message.
>
> Could we give implicit methods and properties a different, slower
> implementation that leverages Objective-C's dynamic features? Imagine, for
> instance, mapping in `imp_implementationWithBlock()`-style pages of
> general-purpose thunks at runtime to reduce code size, then installing them
> lazily with `+resolveClassMethod:`. (Maybe this could actually be made fast
> enough, amortized over all calls, that we could get rid of the thunks
> entirely—I don't know.)
(Slava talked through some of these)
> Have you evaluated applying different rules to methods and properties?
For me, I’d rather reject the proposal as a whole than further complicate the
rules for @objc inference.
> Have you considered a deprecation cycle (for instance, having Swift 4 thunks
> log a warning that they're going away in Swift 5)?
I think Swift 3 -> Swift 4 is the deprecation cycle, no?
> Or is the real motivation that, code size issues aside, you think these
> members ought to be explicitly marked `@objc` for philosophical reasons?
That’s certainly *a* reason. The @objc inference rules are fairly complicated
and even experienced developers can’t easily guess whether something will be
exposed to Objective-C or not because (e.g.) minor changes in the
parameter/result types of a method can affect it.
> If so, how many times do you want people to say so?
Once per API that’s exposed to Objective-C.
> You already have to explicitly inherit from an `@objc` base class;
You don’t *need* to inherit from an `@objc` base class to have an @objc member,
but @objc inference ties together the notions of
Plus, inheritance from an Objective-C class is often incidental: you do it
because you need an NSObjectProtocol conformance, or something else expects
NSObject. I haven’t heard of developers inheriting from NSObject solely to get
@objc inference for their members.
> you already have to specify `dynamic` to avoid optimizations;
Conceptually, ‘dynamic’ is orthogonal to ‘@objc’. In today’s implementation, we
can only implement ‘dynamic’ via the Objective-C runtime, hence this proposal’s
requirement to write both.
> now you also have to mark individual members `@objc`? Would you like the
> request for bridging notarized and filed in triplicate?
> I can understand the impulse to require it explicitly on `public` members,
> but on the other hand, if you *do* accidentally publish a member as `@objc`,
> what's the harm? Is there any non-breaking change you can make to a
> `@nonobjc` method which wouldn't be legal on an `@objc` one?
There probably are; making an Int parameter of a final method Int? isn’t
generally source-breaking, but means that you can no longer expose an @objc
entrypoint. That said...
> Or can you just deprecate the `@objc` version and move on?
it’s easy to leave a deprecated @objc entrypoint in place if this happened to
you, so I don’t think “accidentally made an @objc API that I wanted to be
@nonobjc and now I have to support it going forward” is strong argument in
favor of this proposal.
- Doug
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution