[swift-evolution] Proposal: failable numeric conversion initializers

Matthew Johnson matthew at anandabits.com
Sun Dec 6 13:28:37 CST 2015


Problem:
Swift numeric types all currently have a family of conversion initializers.  In many use cases they leave a lot to be desired.  Initializing an integer type with a floating point value will truncate any fractional portion of the number.  Initializing with an out-of-range value traps.  

Solution:

Sometimes it would be more desirable to convert the runtime value if it can be done without losing information (or possibly with only minimal loss of precision when initializing a floating point type).  This could be easily accomplished if the standard library had a family of failable initializers for all numeric types, either returning an Optional or throwing when the initialization was not successful.  

I prefer the throwing version because failure can be automatically propagated up the call stack and the error could capture value that was provided and the type that failed to initialize which may be useful when debugging.  Also, `try?` allows callers to throw away the error if the detail isn’t necessary.  However, the Optional version would provide the basic functionality that is desired and would be sufficient if the community likes it better.

//  Conversions from all integer types.
init?(_ value: Int8)
init?(_ value: Int16)
init?(_ value: Int32)
init?(_ value: Int64)
init?(_ value: Int)
init?(_ value: UInt8)
init?(_ value: UInt16)
init?(_ value: UInt32)
init?(_ value: UInt64)
init?(_ value: UInt)

//  Conversions from all floating-point types.
init?(_ value: Float)
init?(_ value: Double)
#if arch(i386) || arch(x86_64)
init?(_ value: Float80)
#endif

OR

//  Conversions from all integer types.
init(_ value: Int8) throws
init(_ value: Int16) throws
init(_ value: Int32) throws
init(_ value: Int64) throws
init(_ value: Int) throws
init(_ value: UInt8) throws
init(_ value: UInt16) throws
init(_ value: UInt32) throws
init(_ value: UInt64) throws
init(_ value: UInt) throws

//  Conversions from all floating-point types.
init(_ value: Float) throws
init(_ value: Double) throws
#if arch(i386) || arch(x86_64)
init(_ value: Float80) throws
#endif


More information about the swift-evolution mailing list