Charlie Monroe via swift-evolution <swift-evolution@...> writes: > > I've jotted up a proposal here: > https://gist.github.com/charlieMonroe/82e1519dd2b57029f69bc7abe99d7385 > > Please let me know if there are any comments to it.
Hi, sorry for arriving late but I had missed this thread. I happen to have submitted a couple PRs related to this problem just last week: https://github.com/apple/swift/pull/2551 https://github.com/apple/swift-corelibs-xctest/pull/110 In this case, the issue is not just with Optional's string interpolation, but with Swift's implicit promotion. XCTAssertEqual()'s signature is: public func XCTAssertEqual<T : Equatable>(_ expression1: @autoclosure () throws -> T?, _ expression2: @autoclosure () throws -> T?, _ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) -> Void so in a test you would call it like XCTAssertEqual(1, 2, "message") but then the values are implicitly promoted to Optional<Int>, and when the test fails you get the confusing message XCTAssertEqual failed: ("Optional(1)") is not equal to ("Optional(2)") - message which is clearly unexpected, since the parameters weren't optionals at all. My proposed solution to this was to add an overload to XCTAssertEqual() where the parameters aren't optionals, to prevent implicit promotion and produce the expected output. It hadn't occurred to me that it might have been desirable to change the Optional string interpolation altogether. Regarding the proposal: > This proposal suggests deprecating string interpolation of Optional in order to prevent unexpected results at compile time. I assume you mean "at runtime" here? I think the detailed design needs some more thought. The "Uninterpolable" protocol, and suggesting to cast "as Any" in a Fix-it both seem hacks. I'm not even sure if the general direction of a compile time warning is the right one, and if the problem wouldn't be better solved by simply not making Optional put "Optional()" around the value in its .description. Arguably, if you do this: print([1, 2, 3]) you get "[1, 2, 3]", not "Array([1, 2, 3])". So why should Optional behave differently? It would seem to me that the most obvious solution would be to make Optional conform to CustomStringConvertible, like this: extension Optional: CustomStringConvertible { public var description: String { switch self { case .some(let x): return "\(x)" case .none: return "nil" } } } interestingly, this doesn't quite seem to work at the moment: let o = Optional(1) print(o.description) // "1", ok print(o.debugDescription) // "Optional(1)", ok print(o) // "1", ok debugPrint(o) // "Optional(1)", ok print("\(o)") // "Optional(1)", why?? Nicola _______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
