> On Dec 4, 2015, at 10:26 PM, Dmitri Gribenko <griboz...@gmail.com> wrote:
>
> On Fri, Dec 4, 2015 at 10:21 PM, Andrew Trick <atr...@apple.com
> <mailto:atr...@apple.com>> wrote:
>>
>>> On Dec 4, 2015, at 10:05 PM, Dmitri Gribenko <griboz...@gmail.com> wrote:
>>>
>>> On Fri, Dec 4, 2015 at 10:00 PM, Andrew Trick <atr...@apple.com> wrote:
>>>> I’m adding runtime functionality to support optional casts and ran into
>>>> some Optional to String conversion behavior that is currently somewhat
>>>> accidental—it will break when I add functionality. I want to understand
>>>> the desired behavior before doing extra work to fix it.
>>>>
>>>> Currently swift does this:
>>>>
>>>>> print(Int?(3))
>>>> Optional(3)
>>>>> print(String?("meow"))
>>>> Optional("meow")
>>>>
>>>> I think swift should do this:
>>>>
>>>>> print(Int?(3))
>>>> 3
>>>>> print(String?("meow"))
>>>> "meow"
>>>>> debugPrint(Int?(3))
>>>> Optional(3)
>>>>> debugPrint(String?("meow"))
>>>> Optional("meow")
>>>>
>>>> When a value already knows how to represent itself as a string, I don't
>>>> think that the string "Optional" belongs in the textual representation.
>>>>
>>>> When debugging data structures, it makes sense to include the "Optional"
>>>> indicator.
>>>>
>>>> What was the intention here and what do people think is the desired
>>>> behavior?
>>>
>>> This behavior was not accidental. Here's the rationale:
>>>
>>> If an Optional is nil, it should somehow indicate that. Whatever the
>>> representation is, it would be engineer-oriented and not suitable for
>>> end users. Thus, Optional should never be printed to users, it would
>>> only ever be presented to engineers, and thus its print() and
>>> debugPrint() representations should be the same.
>>>
>>> Dmitri
>>
>> I think you're saying that it's the programmer's responsibility not to
>> construct a user-visible String from an Optional.
>
> No, the responsibility is not to display it to users. It is OK to e.g., log
> it.
>
>> By accidental, I mean that Optional does not conform to
>> CustomStringConvertible. If we want "Optional" to be part of the string
>> conversion, then this conformance needs to exist, or I need to add some
>> special handling of Optional. Do you see any problem with me adding that
>> conformance?
>
> Yes, the same behavior should also apply to any user-defined type: if
> there is only CustomDebugStringConvertible conformance, it should be
> used for String(x) initialization.
>
>> Incidentally, when *do* we want debug string conversion to deviate? Or is it
>> just a customization point we anticipate to be useful?
>
> For example, in String: the user-presentable representation is the
> string itself, the engineer-oriented representation shows all special
> characters as escape sequences.
>
> Dmitri
I understand, thanks for the explanation. But Optionals are not like
other user-defined types in this respect. Let me clarify with an
example...
class A : CustomStringConvertible, CustomDebugStringConvertible {
init() {}
var description: String { get { return "Apple" } }
var debugDescription: String { get { return "Swift" } }
}
print(A?(A()) is CustomStringConvertible)
// true
// Now, Optional does not conform to CustomStringConvertible, but as
// you can see above it is convertible to CustomStringConvertible.
// As print_unlocked is currently written, the behavior should be:
print(String(A?(A())))
Apple
// But as you explained, that is not the behavior we want. We could fix
// it by making Optional counter-intuitively conform to
// CustomStringConvertible. This prevents down conversion to the wrapped
// type, instead printing "Optional" and the payload's debug string.
extension Optional : CustomStringConvertible {
/// A textual representation of `self`, suitable for debugging.
///
/// Optional has no representation suitable for an output
/// stream. Consequently, String conversion should always produce a
/// debug string indicating the Optional type and including the
/// debug representation of the wrapped type.
///
/// Optional must conform to CustomStringConvertible to avoid
/// automatic conversion to its wrapped type during String
/// conversion.
public var description: String {
return debugDescription
}
}
print(String(A?(A())))
Optional(Swift)
I think this is the way to go.
Andy
_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev