Proposal Link: 
https://github.com/apple/swift-evolution/blob/master/proposals/0089-rename-string-reflection-init.md

The review of "SE-0089: Renaming String.init<T>(_: T)" ran from May 17…23, 
2016. The proposal has been *returned for revision* and another round of 
discussion - the core team would love to see the revised proposal make it into 
Swift 3.

The community and core team both want to remove this “footgun” from the 
standard library, where someone could write "String(x)” with the intention of 
getting a value-preserving conversion to String, but may instead get a 
potentially lossy and potentially expensive reflection-based conversion to a 
String.  After extensive discussion, the core team recommends that the 
community consider a somewhat more elaborate design:

- Rename the existing reflection-based "String.init<T>(_: T)” initializer to 
"String.init<T>(describing: T)” as recommend by the community.  This 
initializer would rarely be invoked in user code directly.

- Introduce a new protocol (for sake of discussion, call it 
“ValuePreservingStringConvertible") that refines CustomStringConvertible but 
that adds no new requirements.  Conformance to this protocol indicates that the 
“description” requirement produces a value-preserving representation in String 
form.

- Introduce a new unlabeled initializer on String: "init<T: 
ValuePreservingStringConvertible>(_ v: T) { return v.description }".  This 
permits the “String(x)” syntax to be used on all values of types that can be 
converted to string in a value-preserving way.

 - Audit important standard library types (e.g. the integer and floating point 
types), and make them explicitly conform to ValuePreservingStringConvertible 
with an explicitly implemented “description” property.

- As a performance optimization, change the implementation of the string 
literal interpolation syntax to prefer the unlabeled initializer when 
interpolating a type that is ValuePreservingStringConvertible or that has 
otherwise has an unlabeled String initializer, but use the 
"String.init<T>(describing: T)” initializer if not.


The expected advantages of this design are:

- Swift encourages the T(x) syntax for value preserving conversions, and this 
design ensures that String(x) continues to work for the value preserving cases.

- This ensures that the String(x) syntax does not accidentally fall off a 
performance cliff by using the extremely-dynamic reflection mechanism 
unintentionally.

- The preferred “I don’t care how you do it, just convert this value to a 
string somehow” syntax remains string interpolation syntax.  This syntax is 
efficient in the cases where the String(x) syntax is allowed, but fully general 
to the other cases where custom convert-to-string code has not been provided.


Some remaining open questions:

- Exactly what types should conform to ValuePreservingStringConvertible.  It 
seems clear that integer, floating point types, and Character can and should 
conform.  What other types should?

- Do we need the ValuePreservingStringConvertible at all, or is the existing 
CustomStringConvertible enough?  We already have a few protocols for handling 
string convertibility, it would be great to avoid adding another one.

Thank you to Austin Zheng for driving this proposal forward!

-Chris Lattner
Review Manager


_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to