Proposal: Bridging for Swift Structs in Objective-C


(Dan Stenmark) #1

Swift’s Struct type is one of the most praised features of the language, but is currently unavailable in Objective-C. This poses problems for large legacy codebases that can’t be ported to Swift as quickly but still want to begin using some of the mutability semantics it introduces. As such, I’d like to propose syntax for creating bridged classes that can utilized in Objective-C.

@objc struct Letter {
  var address : String?

  init(withAddress address : String? ) {
    self.address = address
  }
}

At compile-time, this would create two bridge classes: Letter and MutableLetter, both conforming to the NSMutableCopying protocol.

Letter *letter = [[Letter alloc] initWithAddress:address]; // equivalent to ‘let letter = Letter(address: address)’
MutableLetter *mutableLetter = letter.mutableCopy; // equivalent to ‘var mutableLetter = letter’

With Objective-C’s lack of namespacing, the @objc decorator would likely need to accept an optional class prefix parameter to help guard against class name collisions.

@objc(US) struct Letter {
  var address : String?

  init(withAddress address : String? ) {
    self.address = address
  }
}

···

-------

USLetter *letter = [[USLetter alloc] initWithAddress:address]; // equivalent to ‘let letter = Letter(address: address)’
USMutableLetter *mutableLetter = letter.mutableCopy; // equivalent to ‘var mutableLetter = letter’

Nested types would also be represented via this proposal:

@objc(US) class PostalService {
  struct Letter {
    var address : String?

    init(withAddress address : String? ) {
      self.address = address
    }
  }
}

-------

USPostalServiceLetter *letter = [[USPostalServiceLetter alloc] initWithAddress:address]; // equivalent to ‘let letter = PostalService.Letter(address: address)’
USMutablePostalServiceLetter *mutableLetter = letter.mutableCopy; // equivalent to ‘var mutableLetter = letter’

Dan


(Jean-Daniel) #2

How do you deal with the fact that structs have value semantic, while your generated class have reference semantic ?

···

Le 4 déc. 2015 à 23:06, Dan Stenmark <daniel.j.stenmark@gmail.com> a écrit :

Swift’s Struct type is one of the most praised features of the language, but is currently unavailable in Objective-C. This poses problems for large legacy codebases that can’t be ported to Swift as quickly but still want to begin using some of the mutability semantics it introduces. As such, I’d like to propose syntax for creating bridged classes that can utilized in Objective-C.

@objc struct Letter {
  var address : String?

  init(withAddress address : String? ) {
    self.address = address
  }
}

At compile-time, this would create two bridge classes: Letter and MutableLetter, both conforming to the NSMutableCopying protocol.

Letter *letter = [[Letter alloc] initWithAddress:address]; // equivalent to ‘let letter = Letter(address: address)’
MutableLetter *mutableLetter = letter.mutableCopy; // equivalent to ‘var mutableLetter = letter’

With Objective-C’s lack of namespacing, the @objc decorator would likely need to accept an optional class prefix parameter to help guard against class name collisions.

@objc(US) struct Letter {
  var address : String?

  init(withAddress address : String? ) {
    self.address = address
  }
}

-------

USLetter *letter = [[USLetter alloc] initWithAddress:address]; // equivalent to ‘let letter = Letter(address: address)’
USMutableLetter *mutableLetter = letter.mutableCopy; // equivalent to ‘var mutableLetter = letter’

Nested types would also be represented via this proposal:

@objc(US) class PostalService {
  struct Letter {
    var address : String?

    init(withAddress address : String? ) {
      self.address = address
    }
  }
}

-------

USPostalServiceLetter *letter = [[USPostalServiceLetter alloc] initWithAddress:address]; // equivalent to ‘let letter = PostalService.Letter(address: address)’
USMutablePostalServiceLetter *mutableLetter = letter.mutableCopy; // equivalent to ‘var mutableLetter = letter’

Dan

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


(Chris Lattner) #3

Swift’s Struct type is one of the most praised features of the language, but is currently unavailable in Objective-C. This poses problems for large legacy codebases that can’t be ported to Swift as quickly but still want to begin using some of the mutability semantics it introduces. As such, I’d like to propose syntax for creating bridged classes that can utilized in Objective-C.

@objc struct Letter {
  var address : String?

  init(withAddress address : String? ) {
    self.address = address
  }
}

I’m generally a fan of anything that can make Swift get exposed back to Objective-C better, but such things generally need implementation work on Clang as well as on Swift (and thus, need Clang community buy-in as well). Further, as other folks have pointed out, as proposed, this has some challenges in terms of design and implementation. Are you planning to lead the implementation effort?

-Chris

···

On Dec 4, 2015, at 2:06 PM, Dan Stenmark <daniel.j.stenmark@gmail.com> wrote:

At compile-time, this would create two bridge classes: Letter and MutableLetter, both conforming to the NSMutableCopying protocol.

Letter *letter = [[Letter alloc] initWithAddress:address]; // equivalent to ‘let letter = Letter(address: address)’
MutableLetter *mutableLetter = letter.mutableCopy; // equivalent to ‘var mutableLetter = letter’

With Objective-C’s lack of namespacing, the @objc decorator would likely need to accept an optional class prefix parameter to help guard against class name collisions.

@objc(US) struct Letter {
  var address : String?

  init(withAddress address : String? ) {
    self.address = address
  }
}

-------

USLetter *letter = [[USLetter alloc] initWithAddress:address]; // equivalent to ‘let letter = Letter(address: address)’
USMutableLetter *mutableLetter = letter.mutableCopy; // equivalent to ‘var mutableLetter = letter’

Nested types would also be represented via this proposal:

@objc(US) class PostalService {
  struct Letter {
    var address : String?

    init(withAddress address : String? ) {
      self.address = address
    }
  }
}

-------

USPostalServiceLetter *letter = [[USPostalServiceLetter alloc] initWithAddress:address]; // equivalent to ‘let letter = PostalService.Letter(address: address)’
USMutablePostalServiceLetter *mutableLetter = letter.mutableCopy; // equivalent to ‘var mutableLetter = letter’

Dan

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


(Dan Stenmark) #4

That’s expected, and there’s not much that can be done about that. Effectively, much like how Swift’s String value type bridges to the NSString class, this proposal would enable a custom arbitrary struct to have an equivalent Obj-C bridge class with a mutable subclass ala NSMutableString. The overall goal here is to be able to use Swift structs in some way from Objective-C.

Dan

···

On Dec 4, 2015, at 3:54 PM, Jean-Daniel Dupas <mailing@xenonium.com> wrote:

How do you deal with the fact that structs have value semantic, while your generated class have reference semantic ?

Le 4 déc. 2015 à 23:06, Dan Stenmark <daniel.j.stenmark@gmail.com <mailto:daniel.j.stenmark@gmail.com>> a écrit :

Swift’s Struct type is one of the most praised features of the language, but is currently unavailable in Objective-C. This poses problems for large legacy codebases that can’t be ported to Swift as quickly but still want to begin using some of the mutability semantics it introduces. As such, I’d like to propose syntax for creating bridged classes that can utilized in Objective-C.

@objc struct Letter {
  var address : String?

  init(withAddress address : String? ) {
    self.address = address
  }
}

At compile-time, this would create two bridge classes: Letter and MutableLetter, both conforming to the NSMutableCopying protocol.

Letter *letter = [[Letter alloc] initWithAddress:address]; // equivalent to ‘let letter = Letter(address: address)’
MutableLetter *mutableLetter = letter.mutableCopy; // equivalent to ‘var mutableLetter = letter’

With Objective-C’s lack of namespacing, the @objc decorator would likely need to accept an optional class prefix parameter to help guard against class name collisions.

@objc(US) struct Letter {
  var address : String?

  init(withAddress address : String? ) {
    self.address = address
  }
}

-------

USLetter *letter = [[USLetter alloc] initWithAddress:address]; // equivalent to ‘let letter = Letter(address: address)’
USMutableLetter *mutableLetter = letter.mutableCopy; // equivalent to ‘var mutableLetter = letter’

Nested types would also be represented via this proposal:

@objc(US) class PostalService {
  struct Letter {
    var address : String?

    init(withAddress address : String? ) {
      self.address = address
    }
  }
}

-------

USPostalServiceLetter *letter = [[USPostalServiceLetter alloc] initWithAddress:address]; // equivalent to ‘let letter = PostalService.Letter(address: address)’
USMutablePostalServiceLetter *mutableLetter = letter.mutableCopy; // equivalent to ‘var mutableLetter = letter’

Dan

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