Overriding object-code names

In another thread, I have problem with a current protocol. I want to supplant it, but ABI-stability frustrates that. I can't just kill the old protocol, let alone reuse the name for something that may have a different disassembly. Then I remembered that we can give a name to Objective-C items with the @objc(identifier) attribute before the given item's declaration.

I propose we make this a general facility, even for entities in Swift code that are not Objective-C imports. Here's the example from the other thread:

@objectName(Sequence)
public protocol OldAndBusted {
    // What the current Sequence has here
}

@objectName(TheNewHotness)
public protocol Sequence: IterableSet {
    // Put @CTMacUser's reinterpretation of Sequence here 
}

This facility will give the option of transition plans concerning ABI-frozen entities. If "objectName" isn't the best way to express an entity's name, feel free to bike-shed suggestions here. Also mention if we need extra (possibly optional) parameters besides the internal identifier. Should the name be a String instead of a directly-in-line identifier? Using a string lets us use internal names that can't be valid for Swift identifiers, but still legal for LLVM (or whatever) to lay out in the object code.

I thought about this some more, and wanted to note that the idea will kind-of introduce two names for checking purposes.

// Continuing with the first post's example

// Of course this is an error.
public protocol Sequence {}  // Error: Invalid redeclaration of 'Sequence'

// But so is this
public protocol TheNewHotness {}  // Error: Invalid redeclaration of implementation name 'TheNewHotness' (for 'Sequence')
    // Fix-It: Would you like to supply an implementation name?

But there is a workaround, which you already saw:

@objectName(TheLukewarmButObsolete)
public protocol TheNewHotness {}

But the implementation name can't be a redeclaration:

@objectName(OldAndBusted)
public protocol TheNewHotness {}  // Error: Invalid redeclaration of 'OldAndBusted' as an implementation name

On either side of the object-name:

@objectName(Sequence)
public protocol TheNewHotness {}  // Error: Invalid redeclaration of 'Sequence' as an implementation name (It currently already is for 'OldAndBusted'.)

Is there any reason that simple deprecation is not sufficient here? I think having the name of a thing change to being something totally different, while having a different type have the same name at the object level, is likely to be profoundly confusing. It also makes demangling a nightmare.

Yeah, I agree with your view @lukasa.

While I see the point of the pitch, to maintain the base name, I’m not sure the value in this for most projects, and the added complexity would be a bit of a nightmare.

If this API is public, I think you should be careful with declaring public content to ensure you don’t shoot yourself in the foot like this. It the API is internal, then a simple refactor should be able to rename to a reasonable “Legacy” name and allow you to create your new hotness with the original name.

It’s a no win situation either way to start muddling names. While there may be regrets and wishes to break source compatibility without breaking ABI by some smart rename, trying to do this doesn’t scale when you rename the type 2, 3 or 4 times.

Terms of Service

Privacy Policy

Cookie Policy