[discussion] Change the behavior of @objc on a class?


(Jordan Rose) #1

Hey, all. An engineer at Apple noticed the following behavior:

1. class Foo: NSObject → exposed to Objective-C, Swift-style (mangled) runtime name
2. @objc class Foo: NSObject → exposed to Objective-C, Swift-style (mangled) runtime name
3. @objc(Foo) class Foo: NSObject → exposed to Objective-C, unmangled runtime name

(and 4. @objc class Foo → illegal, classes must have ObjC heritage to be @objc.)

They specifically observed that (1) and (2) have the same behavior, and suggested that maybe (2) should be shorthand for (3).

Pros:
- There aren't two ways to spell (1).
- Removing the mangling (and module uniquing) from the runtime name is probably one of the most common uses of @objc on a class.

Cons:
- It's a source-breaking change, for all that the "@objc" in (2) is redundant.
- For protocols, (1) and (2) are not equivalent, because @objc isn't inherited there.
- Mangling is used to namespace class names at run time; if you drop that, the ObjC name should probably have a prefix. (This applies more to frameworks than apps, though.)

There are probably people who say that last con applies to the generated header as well: we shouldn't put (1) or (2) into the generated header because the ObjC name might conflict with another class at compile time. This is valid, but probably too drastic a change at this point.

So, what does everyone think? I'm leaning towards "no change" because it's a bit subtle and not a big enough win, but if there's widespread support for this I'll pull it into a proposal.

Jordan

P.S. This is rdar://problem/22296436 for anyone else at Apple.


(Russ Bishop) #2

Hey, all. An engineer at Apple noticed the following behavior:

1. class Foo: NSObject → exposed to Objective-C, Swift-style (mangled) runtime name
2. @objc class Foo: NSObject → exposed to Objective-C, Swift-style (mangled) runtime name
3. @objc(Foo) class Foo: NSObject → exposed to Objective-C, unmangled runtime name

(and 4. @objc class Foo → illegal, classes must have ObjC heritage to be @objc.)

They specifically observed that (1) and (2) have the same behavior, and suggested that maybe (2) should be shorthand for (3).

I actually wonder why NSObject subclasses magically appear in the generated header when they aren’t marked @objc. If anything I’d say we should remove that behavior.

Pros:
- There aren't two ways to spell (1).
- Removing the mangling (and module uniquing) from the runtime name is probably one of the most common uses of @objc on a class.

Another really common case (at least in our mixed codebase) is bridging to give the class a “private” name in Swift but a sensible name in Objective-C because we have a sensible struct or generic type in Swift, don’t want Swift consumers to use the @objc type, yet need to provide a bridged interface to Objective-C. We do the same with methods too.

@objc(Tile)
public class _objc_Tile: NSObject { }

Cons:
- It's a source-breaking change, for all that the "@objc" in (2) is redundant.
- For protocols, (1) and (2) are not equivalent, because @objc isn't inherited there.

I’d favor consistency even if (1) and (2) are redundant.

- Mangling is used to namespace class names at run time; if you drop that, the ObjC name should probably have a prefix. (This applies more to frameworks than apps, though.)

There are probably people who say that last con applies to the generated header as well: we shouldn't put (1) or (2) into the generated header because the ObjC name might conflict with another class at compile time. This is valid, but probably too drastic a change at this point.

So, what does everyone think? I'm leaning towards "no change" because it's a bit subtle and not a big enough win, but if there's widespread support for this I'll pull it into a proposal.

Jordan

Given other priorities I’d lean toward no change.

Russ

···

On Jun 27, 2016, at 1:26 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:


(Dave Abrahams) #3

It seems like a win and the right solution. Whether the win is “big
enough,” I can't say.

···

on Mon Jun 27 2016, Jordan Rose <swift-evolution@swift.org> wrote:

Hey, all. An engineer at Apple noticed the following behavior:

1. class Foo: NSObject → exposed to Objective-C, Swift-style (mangled) runtime name
2. @objc class Foo: NSObject → exposed to Objective-C, Swift-style (mangled) runtime name
3. @objc(Foo) class Foo: NSObject → exposed to Objective-C, unmangled runtime name

(and 4. @objc class Foo → illegal, classes must have ObjC heritage to be @objc.)

They specifically observed that (1) and (2) have the same behavior,
and suggested that maybe (2) should be shorthand for (3).

Pros:
- There aren't two ways to spell (1).
- Removing the mangling (and module uniquing) from the runtime name is
probably one of the most common uses of @objc on a class.

Cons:
- It's a source-breaking change, for all that the "@objc" in (2) is redundant.
- For protocols, (1) and (2) are not equivalent, because @objc isn't inherited there.
- Mangling is used to namespace class names at run time; if you drop
that, the ObjC name should probably have a prefix. (This applies more
to frameworks than apps, though.)

There are probably people who say that last con applies to the
generated header as well: we shouldn't put (1) or (2) into the
generated header because the ObjC name might conflict with another
class at compile time. This is valid, but probably too drastic a
change at this point.

So, what does everyone think? I'm leaning towards "no change" because
it's a bit subtle and not a big enough win, but if there's widespread
support for this I'll pull it into a proposal.

--
Dave


(Charlie Monroe) #4

Do you know how would this affect e.g. XIB files or CoreData models where you have the class name + module? If the class was previously marked @objc and now it would be implicitely @objc(ClassName), would it require all XIB files to be updated, or would the XIB compiler be able to deal with it? If the former, than it's a big no for me.

I'm not a big fan of a change on any account either, though, since it's absolutely not clear that @objc would have this side-effect.

···

On Jun 27, 2016, at 10:26 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:

Hey, all. An engineer at Apple noticed the following behavior:

1. class Foo: NSObject → exposed to Objective-C, Swift-style (mangled) runtime name
2. @objc class Foo: NSObject → exposed to Objective-C, Swift-style (mangled) runtime name
3. @objc(Foo) class Foo: NSObject → exposed to Objective-C, unmangled runtime name

(and 4. @objc class Foo → illegal, classes must have ObjC heritage to be @objc.)

They specifically observed that (1) and (2) have the same behavior, and suggested that maybe (2) should be shorthand for (3).

Pros:
- There aren't two ways to spell (1).
- Removing the mangling (and module uniquing) from the runtime name is probably one of the most common uses of @objc on a class.

Cons:
- It's a source-breaking change, for all that the "@objc" in (2) is redundant.
- For protocols, (1) and (2) are not equivalent, because @objc isn't inherited there.
- Mangling is used to namespace class names at run time; if you drop that, the ObjC name should probably have a prefix. (This applies more to frameworks than apps, though.)

There are probably people who say that last con applies to the generated header as well: we shouldn't put (1) or (2) into the generated header because the ObjC name might conflict with another class at compile time. This is valid, but probably too drastic a change at this point.

So, what does everyone think? I'm leaning towards "no change" because it's a bit subtle and not a big enough win, but if there's widespread support for this I'll pull it into a proposal.

Jordan

P.S. This is rdar://problem/22296436 <rdar://problem/22296436> for anyone else at Apple.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Douglas Gregor) #5

I’m -1 on this, because bare “@objc” in other contexts means “make sure this is exposed to Objective-C, but I don’t want to be explicit about the name” while “@objc(something)” means “make sure this is exposed to Objective-C, and ‘something’ is the name”.

  - Doug

···

On Jun 27, 2016, at 1:26 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:

Hey, all. An engineer at Apple noticed the following behavior:

1. class Foo: NSObject → exposed to Objective-C, Swift-style (mangled) runtime name
2. @objc class Foo: NSObject → exposed to Objective-C, Swift-style (mangled) runtime name
3. @objc(Foo) class Foo: NSObject → exposed to Objective-C, unmangled runtime name

(and 4. @objc class Foo → illegal, classes must have ObjC heritage to be @objc.)

They specifically observed that (1) and (2) have the same behavior, and suggested that maybe (2) should be shorthand for (3).

Pros:
- There aren't two ways to spell (1).
- Removing the mangling (and module uniquing) from the runtime name is probably one of the most common uses of @objc on a class.

Cons:
- It's a source-breaking change, for all that the "@objc" in (2) is redundant.
- For protocols, (1) and (2) are not equivalent, because @objc isn't inherited there.
- Mangling is used to namespace class names at run time; if you drop that, the ObjC name should probably have a prefix. (This applies more to frameworks than apps, though.)


(Jean-Daniel) #6

As the IB compiler is able to compile xib into nib without knowledge of the actual code, I hardly see how it would guess that a class named Foo in Module Bar should now be compiled as Foo and no longer be mangled as Bar.Foo.

Maybe that issue can be mitigated by allowing a @objc(Bar.Foo) annotation and use it when migrating existing code.

···

Le 28 juin 2016 à 06:56, Charlie Monroe via swift-evolution <swift-evolution@swift.org> a écrit :

Do you know how would this affect e.g. XIB files or CoreData models where you have the class name + module? If the class was previously marked @objc and now it would be implicitely @objc(ClassName), would it require all XIB files to be updated, or would the XIB compiler be able to deal with it? If the former, than it's a big no for me.

I'm not a big fan of a change on any account either, though, since it's absolutely not clear that @objc would have this side-effect.

On Jun 27, 2016, at 10:26 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Hey, all. An engineer at Apple noticed the following behavior:

1. class Foo: NSObject → exposed to Objective-C, Swift-style (mangled) runtime name
2. @objc class Foo: NSObject → exposed to Objective-C, Swift-style (mangled) runtime name
3. @objc(Foo) class Foo: NSObject → exposed to Objective-C, unmangled runtime name

(and 4. @objc class Foo → illegal, classes must have ObjC heritage to be @objc.)

They specifically observed that (1) and (2) have the same behavior, and suggested that maybe (2) should be shorthand for (3).

Pros:
- There aren't two ways to spell (1).
- Removing the mangling (and module uniquing) from the runtime name is probably one of the most common uses of @objc on a class.

Cons:
- It's a source-breaking change, for all that the "@objc" in (2) is redundant.
- For protocols, (1) and (2) are not equivalent, because @objc isn't inherited there.
- Mangling is used to namespace class names at run time; if you drop that, the ObjC name should probably have a prefix. (This applies more to frameworks than apps, though.)

There are probably people who say that last con applies to the generated header as well: we shouldn't put (1) or (2) into the generated header because the ObjC name might conflict with another class at compile time. This is valid, but probably too drastic a change at this point.

So, what does everyone think? I'm leaning towards "no change" because it's a bit subtle and not a big enough win, but if there's widespread support for this I'll pull it into a proposal.

Jordan

P.S. This is rdar://problem/22296436 <rdar://problem/22296436> for anyone else at Apple.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Jordan Rose) #7

Xcode plans are a little beyond the scope of the Swift project, so I can't promise that there would be any such autoupdating. If there were such a feature, I'd expect it to be in the form of a one-time migration, probably triggered along with the Swift 3 migrator…but the IB team might have other ideas, or decide they have more important things to finish for this release. So I guess the answer is "don't count on it".

Jordan

···

On Jun 27, 2016, at 21:56, Charlie Monroe <charlie@charliemonroe.net> wrote:

Do you know how would this affect e.g. XIB files or CoreData models where you have the class name + module? If the class was previously marked @objc and now it would be implicitely @objc(ClassName), would it require all XIB files to be updated, or would the XIB compiler be able to deal with it? If the former, than it's a big no for me.

I'm not a big fan of a change on any account either, though, since it's absolutely not clear that @objc would have this side-effect.

On Jun 27, 2016, at 10:26 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Hey, all. An engineer at Apple noticed the following behavior:

1. class Foo: NSObject → exposed to Objective-C, Swift-style (mangled) runtime name
2. @objc class Foo: NSObject → exposed to Objective-C, Swift-style (mangled) runtime name
3. @objc(Foo) class Foo: NSObject → exposed to Objective-C, unmangled runtime name

(and 4. @objc class Foo → illegal, classes must have ObjC heritage to be @objc.)

They specifically observed that (1) and (2) have the same behavior, and suggested that maybe (2) should be shorthand for (3).

Pros:
- There aren't two ways to spell (1).
- Removing the mangling (and module uniquing) from the runtime name is probably one of the most common uses of @objc on a class.

Cons:
- It's a source-breaking change, for all that the "@objc" in (2) is redundant.
- For protocols, (1) and (2) are not equivalent, because @objc isn't inherited there.
- Mangling is used to namespace class names at run time; if you drop that, the ObjC name should probably have a prefix. (This applies more to frameworks than apps, though.)

There are probably people who say that last con applies to the generated header as well: we shouldn't put (1) or (2) into the generated header because the ObjC name might conflict with another class at compile time. This is valid, but probably too drastic a change at this point.

So, what does everyone think? I'm leaning towards "no change" because it's a bit subtle and not a big enough win, but if there's widespread support for this I'll pull it into a proposal.

Jordan

P.S. This is rdar://problem/22296436 <rdar://problem/22296436> for anyone else at Apple.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(L Mihalkovic) #8

Regards
LM
(From mobile)

Hey, all. An engineer at Apple noticed the following behavior:

1. class Foo: NSObject → exposed to Objective-C, Swift-style (mangled) runtime name
2. @objc class Foo: NSObject → exposed to Objective-C, Swift-style (mangled) runtime name
3. @objc(Foo) class Foo: NSObject → exposed to Objective-C, unmangled runtime name

(and 4. @objc class Foo → illegal, classes must have ObjC heritage to be @objc.)

They specifically observed that (1) and (2) have the same behavior, and suggested that maybe (2) should be shorthand for (3).

Pros:
- There aren't two ways to spell (1).
- Removing the mangling (and module uniquing) from the runtime name is probably one of the most common uses of @objc on a class.

Cons:
- It's a source-breaking change, for all that the "@objc" in (2) is redundant.
- For protocols, (1) and (2) are not equivalent, because @objc isn't inherited there.
- Mangling is used to namespace class names at run time; if you drop that, the ObjC name should probably have a prefix. (This applies more to frameworks than apps, though.)

I’m -1 on this, because bare “@objc” in other contexts means “make sure this is exposed to Objective-C, but I don’t want to be explicit about the name” while “@objc(something)” means “make sure this is exposed to Objective-C, and ‘something’ is the name”.

-1
Please'o'please ... I find it useful for complexifying simple swift names into the kind that typically exists on the objc side.

···

On Jun 28, 2016, at 8:04 PM, Douglas Gregor via swift-evolution <swift-evolution@swift.org> wrote:

On Jun 27, 2016, at 1:26 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:

  - Doug

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Jordan Rose) #9

To be clear, the argument form wouldn’t change, but it seems like there’s enough negative feedback on this that we shouldn’t do it. Thanks, everyone!

Jordan

···

On Jun 28, 2016, at 21:50, L. Mihalkovic <laurent.mihalkovic@gmail.com> wrote:

Regards
LM
(From mobile)

On Jun 28, 2016, at 8:04 PM, Douglas Gregor via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Jun 27, 2016, at 1:26 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Hey, all. An engineer at Apple noticed the following behavior:

1. class Foo: NSObject → exposed to Objective-C, Swift-style (mangled) runtime name
2. @objc class Foo: NSObject → exposed to Objective-C, Swift-style (mangled) runtime name
3. @objc(Foo) class Foo: NSObject → exposed to Objective-C, unmangled runtime name

(and 4. @objc class Foo → illegal, classes must have ObjC heritage to be @objc.)

They specifically observed that (1) and (2) have the same behavior, and suggested that maybe (2) should be shorthand for (3).

Pros:
- There aren't two ways to spell (1).
- Removing the mangling (and module uniquing) from the runtime name is probably one of the most common uses of @objc on a class.

Cons:
- It's a source-breaking change, for all that the "@objc" in (2) is redundant.
- For protocols, (1) and (2) are not equivalent, because @objc isn't inherited there.
- Mangling is used to namespace class names at run time; if you drop that, the ObjC name should probably have a prefix. (This applies more to frameworks than apps, though.)

I’m -1 on this, because bare “@objc” in other contexts means “make sure this is exposed to Objective-C, but I don’t want to be explicit about the name” while “@objc(something)” means “make sure this is exposed to Objective-C, and ‘something’ is the name”.

-1
Please'o'please ... I find it useful for complexifying simple swift names into the kind that typically exists on the objc side.