[swift-evolution] Proposal: Deprecate optionals in string interpolation

Charlie Monroe charlie at charliemonroe.net
Thu Jun 16 14:44:46 CDT 2016


Sorry, didn't have time to actually submit the proposal, but it at least gave me some time to think it through a few more times.

After reconsiderations, I suggest the following:

- deprecation of interpolation of optionals.
- extending the Optional type by:
	- var detailedDescription: String - which will return the same value as until now: "nil" for nil and "Optional(value)" for .some(_). This is due to .description and .debugDescription's documentation discouraging direct invocation.

	- func descriptionWithDefaultValue(_ defaultValue: String = "nil") -> String - which would return either the description of the value, or `defaultValue`.

So, when the compiler runs into interpolation of an Optional, it issues a warning with a fix-it, that by default calls .descriptionWithDefaultValue() on the optional.

Person who wants the original behavior can still get it using `.detailedDescription`.

I'll put it into a proper proposal tomorrow.

> On May 27, 2016, at 2:23 PM, Vladimir.S <svabox at gmail.com> wrote:
> 
> I believe the only 'fix' here is to prevent string interpolation for anything that is not base types like String, Integer, Double, Boolean or that is explicitly provides textual(not for debugging) representation.
> 
> For all others like function, Optional etc leave only debug string interpolation, when we should explicitly ask "get debgug info text for this item".
> 
> I.e. in my opinion we shouldn't be able to do "\(url.lowercased)" or "\(op)" (if `op` is optional).
> 
> But, *at least* we need warnings if optional, function or something like this is in string interpolation.
> 
> On 27.05.2016 11:17, Charlie Monroe wrote:
>> That's a good point.
>> 
>> I still recommend having "Uninterpolable" protocol which could be then applied on any type. Unfortunately, this would require to introduce some kind of a reflection API on the function type :-/
>> 
>> I'll think about it further today and will try to submit a final version of the proposal.
>> 
>>> On May 27, 2016, at 8:56 AM, Vladimir.S <svabox at gmail.com> wrote:
>>> 
>>> Just caught another issue with string interpolation:
>>> 
>>> "File \"\(url.lowercased)\" not found."
>>> 
>>> I mistyped the `lowercased` without `()` and got:
>>> File "(Function)" not found.
>>> 
>>> I believe we need a protection for such situations
>>> 
>>> On 24.05.2016 13:01, Charlie Monroe via swift-evolution wrote:
>>>> Hi Nicola, thanks for the feedback.
>>>> 
>>>>> I assume you mean "at runtime" here?
>>>> 
>>>> That's probably my wrong wording. :) The unexpected result is at runtime, but we'd like to catch this at compile time. I've updated it to say
>>>> 
>>>> "in order to prevent unexpected results already at compile time" - hopefully that's a clearer wording.
>>>> 
>>>>> 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.
>>>> 
>>>> Originally, the proposal was simply to emit a warning for interpolation of Optionals, but several people made good points:
>>>> 
>>>> - there may be other types you may not want to use for interpolation - as mentioned in the proposal, e.g. private data structures that would expose something you want to keep private, various enum values, etc. Which is why I've started thinking about making a protocol that would indicate the type is discouraged being "interpoled". I've thought about this and decided to make a more robust and customizable solution.
>>>> 
>>>> An alternative to this would be to use annotations or just drop this customizability completely. But I think with Swift and its protocol-driven development, marking the type with this protocol is the most robust way to go.
>>>> 
>>>> - both .description and .debugDescription are mentioned in alternatives for the Fix-It.
>>>> 
>>>> "as Any" seemed, however, the cleanest and most robust solution to me, since then the Uninterpolable protocol can be applied to any type without forcing the type to conform to CustomStringConvertible as well. I agree that it's kind of a hack, though.
>>>> 
>>>>> 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.
>>>> 
>>>> There are many people oposing this and expecting the Optional() wrap around the value, indicating the actual type. Actually, including me - I agree it can be useful for some types of debugging since in what you wrote further, there'd be no difference between description of [1, 2, 3] (i.e. [Int]) and Optional([1, 2, 3]) (i.e. [Int]?).
>>>> 
>>>> There are legitimate usecases where the current behavior is correct, but in most of cases, having an optional in string interpolation will lead either to unnecessary clutter in the log/console or bugs - in which case even "nil" is not correct to be used for the interpolation. Which is the basis for this proposal.
>>>> 
>>>>> print("\(o)")               // "Optional(1)", why??
>>>> 
>>>> String has several overloads for the init(stringInterpolationSegment:) initiailizer. Optional falls into the generic <T> category, which will call String(optional) - which most likely uses debugDescription.
>>>> 
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> swift-evolution at swift.org
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>> 
>> 
>> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160616/01fdb83e/attachment.html>


More information about the swift-evolution mailing list