Foundation and value types


(Matthew Johnson) #1

I am very happy that Swift 3 is placing a priority on portability, especially including a robust library enabling real work to be done.

Adopting Foundation as the library interface is an obvious choice for many reasons. Despite that I find it rather unfortunate that we are tied to an API designed in a different language without the rich feature set Swift has to offer, especially expressive and highly functional value types.

Many of the types in Foundation would naturally be designed as value types in Swift, evidenced by the fact that String, Array, Dictionary and Set are implemented this way in Swift's standard library. I'm sure it would be out of scope for Swift 3, but I am wondering if there are plans to design Swift-native value types corresponding to the Foundation types where that makes sense (Date, URL, etc).

I am also wondering how this would interact with the decision to drop the NS prefixes from the names of Foundation types. For example, if a hypothetical Date value type exists in a future version of Swift and NSDate is also named Date in Swift any code importing both Foundation and the module containing the Swift-native Date type (would this be in the standard library?) would need to manually resolve the name ambiguity every time it was used. This is obviously less than ideal.

I am guessing there is at least a vague conception of a more Swifty Foundation and a plan to somehow address the issue of conflicting names. If there is I am interested in having some idea of where we are headed.

I ask partly out of a desire to use value types for things that are naturally values and partly because I am wondering if there is anything the community can reasonbly do in the near term to expedite the process of getting to a more Swifty Foundation API beyond helping to complete a robust and well tested corelibs implementation of Foundation.

Thanks,
Matthew


(Dmitri Gribenko) #2

It seems to be an area of the library where value types would make a
lot of sense, so I'd like this conversation to continue. Tony, what
do you think?

Dmitri

···

On Thu, Dec 10, 2015 at 4:09 PM, Matthew Johnson via swift-evolution <swift-evolution@swift.org> wrote:

I am very happy that Swift 3 is placing a priority on portability, especially including a robust library enabling real work to be done.

Adopting Foundation as the library interface is an obvious choice for many reasons. Despite that I find it rather unfortunate that we are tied to an API designed in a different language without the rich feature set Swift has to offer, especially expressive and highly functional value types.

Many of the types in Foundation would naturally be designed as value types in Swift, evidenced by the fact that String, Array, Dictionary and Set are implemented this way in Swift's standard library. I'm sure it would be out of scope for Swift 3, but I am wondering if there are plans to design Swift-native value types corresponding to the Foundation types where that makes sense (Date, URL, etc).

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com>*/


(Tony Parker) #3

Our primary goal for Swift 3 is to achieve API parity with Darwin Foundation.

That said, if we want to talk about value types then the conversation has to start with how the bridging is supposed to work. The vast majority of frameworks on OS X and iOS are implemented in Objective-C and will expect existing Foundation class types in their APIs (e.g. Date and URL).

- Tony

···

On Dec 10, 2015, at 4:38 PM, Dmitri Gribenko <gribozavr@gmail.com> wrote:

On Thu, Dec 10, 2015 at 4:09 PM, Matthew Johnson via swift-evolution > <swift-evolution@swift.org> wrote:

I am very happy that Swift 3 is placing a priority on portability, especially including a robust library enabling real work to be done.

Adopting Foundation as the library interface is an obvious choice for many reasons. Despite that I find it rather unfortunate that we are tied to an API designed in a different language without the rich feature set Swift has to offer, especially expressive and highly functional value types.

Many of the types in Foundation would naturally be designed as value types in Swift, evidenced by the fact that String, Array, Dictionary and Set are implemented this way in Swift's standard library. I'm sure it would be out of scope for Swift 3, but I am wondering if there are plans to design Swift-native value types corresponding to the Foundation types where that makes sense (Date, URL, etc).

It seems to be an area of the library where value types would make a
lot of sense, so I'd like this conversation to continue. Tony, what
do you think?

Dmitri

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com>*/


(Dmitri Gribenko) #4

Bridging definitely has to be an important part of the proposal. But
I want to note that we have existing tools to solve bridging issues
that we use with existing types -- researching how to apply them would
be a good start.

Dmitri

···

On Thu, Dec 10, 2015 at 5:02 PM, Tony Parker <anthony.parker@apple.com> wrote:

Our primary goal for Swift 3 is to achieve API parity with Darwin Foundation.

That said, if we want to talk about value types then the conversation has to start with how the bridging is supposed to work. The vast majority of frameworks on OS X and iOS are implemented in Objective-C and will expect existing Foundation class types in their APIs (e.g. Date and URL).

- Tony

On Dec 10, 2015, at 4:38 PM, Dmitri Gribenko <gribozavr@gmail.com> wrote:

On Thu, Dec 10, 2015 at 4:09 PM, Matthew Johnson via swift-evolution >> <swift-evolution@swift.org> wrote:

I am very happy that Swift 3 is placing a priority on portability, especially including a robust library enabling real work to be done.

Adopting Foundation as the library interface is an obvious choice for many reasons. Despite that I find it rather unfortunate that we are tied to an API designed in a different language without the rich feature set Swift has to offer, especially expressive and highly functional value types.

Many of the types in Foundation would naturally be designed as value types in Swift, evidenced by the fact that String, Array, Dictionary and Set are implemented this way in Swift's standard library. I'm sure it would be out of scope for Swift 3, but I am wondering if there are plans to design Swift-native value types corresponding to the Foundation types where that makes sense (Date, URL, etc).

It seems to be an area of the library where value types would make a
lot of sense, so I'd like this conversation to continue. Tony, what
do you think?

Dmitri

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com>*/

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com>*/


(Philippe Hausler) #5

I think some may have a more persuasive argument than others: NSDate for example seems much more cut and dry since it is basically just a simple wrapper around a Double. It is worth mentioning that one of the distinct advantages of the class versions is that they are subclassable. Granted that may not apply to all users but it is a pretty useful thing to have a good concrete base class to derive from that works well with other APIs. NSOperation for example probably would not be a good candidate since most all cases of it’s usage is a subclass. URL I am on the fence because one of the major issues with going to a struct type is that it would likely loose the functionality granted by lower level APIs like CFURLRef which some of that nuances I would hope would be developed in one canonical location.

···

On Dec 10, 2015, at 5:02 PM, Tony Parker via swift-evolution <swift-evolution@swift.org> wrote:

Our primary goal for Swift 3 is to achieve API parity with Darwin Foundation.

That said, if we want to talk about value types then the conversation has to start with how the bridging is supposed to work. The vast majority of frameworks on OS X and iOS are implemented in Objective-C and will expect existing Foundation class types in their APIs (e.g. Date and URL).

- Tony

On Dec 10, 2015, at 4:38 PM, Dmitri Gribenko <gribozavr@gmail.com> wrote:

On Thu, Dec 10, 2015 at 4:09 PM, Matthew Johnson via swift-evolution >> <swift-evolution@swift.org> wrote:

I am very happy that Swift 3 is placing a priority on portability, especially including a robust library enabling real work to be done.

Adopting Foundation as the library interface is an obvious choice for many reasons. Despite that I find it rather unfortunate that we are tied to an API designed in a different language without the rich feature set Swift has to offer, especially expressive and highly functional value types.

Many of the types in Foundation would naturally be designed as value types in Swift, evidenced by the fact that String, Array, Dictionary and Set are implemented this way in Swift's standard library. I'm sure it would be out of scope for Swift 3, but I am wondering if there are plans to design Swift-native value types corresponding to the Foundation types where that makes sense (Date, URL, etc).

It seems to be an area of the library where value types would make a
lot of sense, so I'd like this conversation to continue. Tony, what
do you think?

Dmitri

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com>*/

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


(Tony Parker) #6

I’m not particularly happy with the existing bridging.

First, it’s not available on all platforms.

Second, it’s often inefficient (c.f. https://github.com/apple/swift/blob/master/stdlib/public/core/String.swift#L476, https://github.com/apple/swift/blob/master/stdlib/public/core/ArrayCast.swift#L159, others).

Third, it causes confusing API discrepancies. e.g. here: (https://github.com/apple/swift-corelibs-foundation/blob/master/Foundation/NSError.swift#L47)

    /// - Experiment: This is a draft API currently under consideration for official import into Foundation
    /// - Note: This API differs from Darwin because it uses [String : Any] as a type instead of [String : AnyObject]. This allows the use of Swift value types.
    private var _userInfo: [String : Any]?

On Darwin this is [String: AnyObject] - but then, why does it accept Swift.String, which is clearly not an object? Because of magic stuff happening behind your back (which, because of #1, does not happen on Linux).

I don’t have any silver bullet proposal, but before we go head first into expanding this pattern across many more class/value types, I believe we need a much better answer.

- Tony

···

On Dec 10, 2015, at 5:05 PM, Dmitri Gribenko <gribozavr@gmail.com> wrote:

Bridging definitely has to be an important part of the proposal. But
I want to note that we have existing tools to solve bridging issues
that we use with existing types -- researching how to apply them would
be a good start.

Dmitri

On Thu, Dec 10, 2015 at 5:02 PM, Tony Parker <anthony.parker@apple.com> wrote:

Our primary goal for Swift 3 is to achieve API parity with Darwin Foundation.

That said, if we want to talk about value types then the conversation has to start with how the bridging is supposed to work. The vast majority of frameworks on OS X and iOS are implemented in Objective-C and will expect existing Foundation class types in their APIs (e.g. Date and URL).

- Tony

On Dec 10, 2015, at 4:38 PM, Dmitri Gribenko <gribozavr@gmail.com> wrote:

On Thu, Dec 10, 2015 at 4:09 PM, Matthew Johnson via swift-evolution >>> <swift-evolution@swift.org> wrote:

I am very happy that Swift 3 is placing a priority on portability, especially including a robust library enabling real work to be done.

Adopting Foundation as the library interface is an obvious choice for many reasons. Despite that I find it rather unfortunate that we are tied to an API designed in a different language without the rich feature set Swift has to offer, especially expressive and highly functional value types.

Many of the types in Foundation would naturally be designed as value types in Swift, evidenced by the fact that String, Array, Dictionary and Set are implemented this way in Swift's standard library. I'm sure it would be out of scope for Swift 3, but I am wondering if there are plans to design Swift-native value types corresponding to the Foundation types where that makes sense (Date, URL, etc).

It seems to be an area of the library where value types would make a
lot of sense, so I'd like this conversation to continue. Tony, what
do you think?

Dmitri

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com>*/

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com>*/


(Dmitri Gribenko) #7

I’m not particularly happy with the existing bridging.

First, it’s not available on all platforms.

Second, it’s often inefficient (c.f.
https://github.com/apple/swift/blob/master/stdlib/public/core/String.swift#L476,

This is not an issue with bridging. String needs a different hash
code because it implements == differently, and hash code and equality
semantics have to match.

https://github.com/apple/swift/blob/master/stdlib/public/core/ArrayCast.swift#L159,

In this case, the user explicitly asked to check whether a cast is
possible using 'as?', there is no other way to implement this. When
it is possible to do a cast lazily, we do it lazily.

others).

Third, it causes confusing API discrepancies. e.g. here:
(https://github.com/apple/swift-corelibs-foundation/blob/master/Foundation/NSError.swift#L47)

    /// - Experiment: This is a draft API currently under consideration for
official import into Foundation
    /// - Note: This API differs from Darwin because it uses [String : Any]
as a type instead of [String : AnyObject]. This allows the use of Swift
value types.
    private var _userInfo: [String : Any]?

On Darwin this is [String: AnyObject] - but then, why does it accept
Swift.String, which is clearly not an object? Because of magic stuff
happening behind your back (which, because of #1, does not happen on Linux).

Yes, we need to make it consistent.

Dmitri

···

On Thu, Dec 10, 2015 at 5:19 PM, Tony Parker <anthony.parker@apple.com> wrote:

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com>*/


(David Smith) #8

There's certainly plenty of room for optimization in bridging of specific types, which could help these general cases (e.g. an Array<NSString> being cast to Array<String> would be sped up by improvements to NSString->String bridging performance, and so on). I've identified various improvements that could be made over the last year or so, and I'm sure profiling would turn up more in short order.

  David

···

On Dec 10, 2015, at 5:24 PM, Dmitri Gribenko via swift-evolution <swift-evolution@swift.org> wrote:

On Thu, Dec 10, 2015 at 5:19 PM, Tony Parker <anthony.parker@apple.com <mailto:anthony.parker@apple.com>> wrote:

I’m not particularly happy with the existing bridging.

First, it’s not available on all platforms.

Second, it’s often inefficient (c.f.
https://github.com/apple/swift/blob/master/stdlib/public/core/String.swift#L476,

This is not an issue with bridging. String needs a different hash
code because it implements == differently, and hash code and equality
semantics have to match.

https://github.com/apple/swift/blob/master/stdlib/public/core/ArrayCast.swift#L159,

In this case, the user explicitly asked to check whether a cast is
possible using 'as?', there is no other way to implement this. When
it is possible to do a cast lazily, we do it lazily.

others).

Third, it causes confusing API discrepancies. e.g. here:
(https://github.com/apple/swift-corelibs-foundation/blob/master/Foundation/NSError.swift#L47)

   /// - Experiment: This is a draft API currently under consideration for
official import into Foundation
   /// - Note: This API differs from Darwin because it uses [String : Any]
as a type instead of [String : AnyObject]. This allows the use of Swift
value types.
   private var _userInfo: [String : Any]?

On Darwin this is [String: AnyObject] - but then, why does it accept
Swift.String, which is clearly not an object? Because of magic stuff
happening behind your back (which, because of #1, does not happen on Linux).

Yes, we need to make it consistent.

Dmitri

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com <mailto:gribozavr@gmail.com>>*/
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution