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