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

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.

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:

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

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

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.)

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

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

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

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.