> On Mar 22, 2017, at 10:55 PM, Brent Royal-Gordon via swift-evolution > <swift-evolution@swift.org> wrote: > >> On Mar 21, 2017, at 11:03 PM, Chris Lattner via swift-evolution >> <swift-evolution@swift.org> 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 swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution