Proposal: Deprecate optionals in string interpolation

google for swift print optional stackoverflow. I think that kind of speaks

for itself.

I think this is actually an example of why the current behavior is a
*good* thing.
I did just google that and the top comment of the first result explains
what an optional is. That is very good and encourages beginners to
understand how optionals work under the hood. If you hide that from them,
they will only be even more confused when they see just the string "nil"
pop up when it previously was showing the correct value.

···

On Thu, May 19, 2016 at 9:36 PM Krystof Vasa via swift-evolution < swift-evolution@swift.org> wrote:

BTW - google for swift print optional stackoverflow. I think that kind of
speaks for itself.

> On May 19, 2016, at 6:07 PM, Jeremy Pereira via swift-evolution < > swift-evolution@swift.org> wrote:
>
> -1
>
> This seems to me like crippling string interpolation just because
sometimes we make mistakes. 99% of the time, if I interpolate an optional,
it’s because I want it that way. I don’t want to have to put up with a
warning or write the same boilerplate 99% of the time just to flag up the
1% more easily. Sorry.
>
>> On 18 May 2016, at 19:50, Krystof Vasa via swift-evolution < > swift-evolution@swift.org> wrote:
>>
>> The string interpolation is one of the strong sides of Swift, but also
one of its weaknesses.
>>
>> It has happened to me more than once that I've used the interpolation
with an optional by mistake and the result is then far from the expected
result.
>>
>> This happened mostly before Swift 2.0's guard expression, but has
happened since as well.
>>
>> The user will seldomly want to really get the output
"Optional(something)", but is almost always expecting just "something". I
believe this should be addressed by a warning to force the user to check
the expression to prevent unwanted results. If you indeed want the output
of an optional, it's almost always better to use the ?? operator and supply
a null value placeholder, e.g. "\(myOptional ?? "<<none>>")", or use
myOptional.debugDescription - which is a valid expression that will always
return a non-optional value to force the current behavior.
>>
>> Krystof
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
Dan Appel

With this proposal in place:

1) The user would type print(myURL.path).
2) The compiler will immediately issue a warning about printing an optional - the user would hence learn about optionals *before* the code is run.
3) If he ran the code anyway, he'd still get Optional(/iphone/) anyway.
4) Xcode would offer a Fix-It, adding .debugDescription to the optional, getting Optional(/iphone/) on the anyway, yet again.

I'm not saying *removing* the current behavior, but adding a warning for this - you'd get the same result ignoring the warning and applying the Fix-It, but you'd have control over this.

···

On May 20, 2016, at 6:48 AM, Dan Appel via swift-evolution <swift-evolution@swift.org> wrote:

>google for swift print optional stackoverflow. I think that kind of speaks for itself.

I think this is actually an example of why the current behavior is a good thing. I did just google that and the top comment of the first result explains what an optional is. That is very good and encourages beginners to understand how optionals work under the hood. If you hide that from them, they will only be even more confused when they see just the string "nil" pop up when it previously was showing the correct value.

On Thu, May 19, 2016 at 9:36 PM Krystof Vasa via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
BTW - google for swift print optional stackoverflow. I think that kind of speaks for itself.

> On May 19, 2016, at 6:07 PM, Jeremy Pereira via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>
> -1
>
> This seems to me like crippling string interpolation just because sometimes we make mistakes. 99% of the time, if I interpolate an optional, it’s because I want it that way. I don’t want to have to put up with a warning or write the same boilerplate 99% of the time just to flag up the 1% more easily. Sorry.
>
>> On 18 May 2016, at 19:50, Krystof Vasa via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>
>> The string interpolation is one of the strong sides of Swift, but also one of its weaknesses.
>>
>> It has happened to me more than once that I've used the interpolation with an optional by mistake and the result is then far from the expected result.
>>
>> This happened mostly before Swift 2.0's guard expression, but has happened since as well.
>>
>> The user will seldomly want to really get the output "Optional(something)", but is almost always expecting just "something". I believe this should be addressed by a warning to force the user to check the expression to prevent unwanted results. If you indeed want the output of an optional, it's almost always better to use the ?? operator and supply a null value placeholder, e.g. "\(myOptional ?? "<<none>>")", or use myOptional.debugDescription - which is a valid expression that will always return a non-optional value to force the current behavior.
>>
>> Krystof
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution
--
Dan Appel
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

I'm wondering which scenario this is actually wanted behavior:

- strings that are for user interaction? Definitely not.

There would almost certainly be other manipulation going on that renders this moot for user facing strings, for instance, you would never interpolate a date without running it through an NSDateFormatter.

- logs? To be honest, the logs riddled with Optional(value) are pain to read. Following example:

key1: Optional("Value")
key2: nil

vs

key1: Value
key2: nil

Which is more readable in the log?

Which is a ore honest representation of the variable you are logging?

···

On 19 May 2016, at 18:06, Krystof Vasa <kvasa@icloud.com> wrote:

What would be a better alternative is the ability to have a String Format
Token that would unwrap a value, like so

let string = String(format: "http://%?/", url)

None is unwrapped to "http:///"
Some is unwrapped to "http://myurl.com/&quot;

I think this would be a good trade off rather than having to do an awkward
guard dance, make your code unsafe with force-unwraps or end-up with
"Optional()" in your string.

···

*___________________________________*

*James⎥Head of Trolls*

*james@supmenow.com <james@supmenow.com>⎥supmenow.com <http://supmenow.com>*

*Sup*

*Runway East *

*10 Finsbury Square*

*London*

* EC2A 1AF *

On 4 July 2016 at 16:41, Krystof Vasa via swift-evolution < swift-evolution@swift.org> wrote:

This is now being tracked as [SR-1882] String Interpolation of Optionals · Issue #44491 · apple/swift · GitHub -
Chris (Lattner) thought this should not go through the official proposal
process as something more complicated, but just add a warning with
redundant parentheses around it silencing the warning (
http://article.gmane.org/gmane.comp.lang.swift.evolution/20960\).

The latest version of the proposal (that's not going to happen) can be
found here -
string-interpolation.md · GitHub -
and I've implemented it for my own use here:

https://github.com/charlieMonroe/XUCore/blob/master/XUCore/additions/OptionalAdditions.swift

I find it better readable than using ?? or extra parentheses around the
Optional...

On Jul 4, 2016, at 5:31 PM, David Beck via swift-evolution < > swift-evolution@swift.org> wrote:

> The string interpolation is one of the strong sides of Swift, but also
one of its weaknesses.
>
> It has happened to me more than once that I've used the interpolation
with an optional by mistake and the result is then far from the expected
result.
>
> This happened mostly before Swift 2.0's guard expression, but has
happened since as well.
>
> The user will seldomly want to really get the output
"Optional(something)", but is almost always expecting just "something". I
believe this should be addressed by a warning to force the user to check
the expression to prevent unwanted results. If you indeed want the output
of an optional, it's almost always better to use the ?? operator and supply
a null value placeholder, e.g. "\(myOptional ?? "<<none>>")", or use
myOptional.debugDescription - which is a valid expression that will always
return a non-optional value to force the current behavior.
>
> Krystof
>
>
>

I really hope a proposal that solves this problem gets through, but I’m
not sure blocking optionals specifically is the way to go. In particular
there are other types that don’t have a clean string representation. I
think that by default string interpolation (meaning String creation
specifically) should only accept ValuePreservingStringConvertible types and
produce an error for everything else.

But, in addition, we need a way to quickly print out values for debugging.
I think a new string type (DebugString for example) would be useful for
this. print and similar functions could take that as an argument and any
type could be interpolated in it’s argument. Further, if you simply say
`let a = “\(something)”` and something
isn’t ValuePreservingStringConvertible, the type of a should then be
DebugString. Converting to string should be strait forward, but require a
small step to make it obvious that you are using a string that could have
weird characters.

*David Beck*
http://davidbeck.co
http://twitter.com/davbeck
David Beck

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Strong +1 for the (at least) warning in case of optional in string interpolation.

Actually I think `Optional(something)` is a form of text representation for *debugging only*, not for 'production'. It is clear, that by default we need text representation for 'production', so it is logical for me that optional in string interpolation should return text without `Optional(..)`. Probably this means that optional should not have default .description for `production`, but just debugDescription for debugging.

So, for production you'll need to have:

let newURL = NSURL(string: "http://apple.com(originalURL.path!)/help")
(or use ?? etc)

for debugging:
let newURL = NSURL(string: "http://apple.com(originalURL.path.debugDescription)/help")

···

On 19.05.2016 10:39, Krystof Vasa via swift-evolution wrote:

Consider the following example:

let originalURL: NSURL = NSURL(string: "http://apple.com/iphone&quot;\)!
let newURL = NSURL(string: "http://apple.com(originalURL.path)/help")

What's the newURL? Nil, because it was being inited with

http://apple.comOptional(/iphone)/help
<http://apple.comoptional%28/iphone%29/help>

Since the path property is optional.

Which is not something you figure out until runtime, wondering why the URL
is nil. This is very annoying when you run into this issue repeatedly on
several occasions because you forget to unwrap the value.

*This* is IMHO an undesired and unexpected behavior.

If interpolating optionals did become a warning, you'd immediately know
about a potential bug: you don't check if path != nil.

BTW if you still want the original behavior of printing

Optional(my string value),

you can still write

"http://apple.com(originalURL.path.debugDescription)/help"

which invokes debugDescription on the Optional, not the String (since there
is no "?"), and you get the original value anyway. And this could be the
Fix-It for it as well to maintain original behavior.

Krystof

On May 19, 2016, at 9:28 AM, Dan Appel <dan.appel00@gmail.com >> <mailto:dan.appel00@gmail.com>> wrote:

You know what's worse than seeing "Optional(my string value)" in a label?
Seeing "nil". When the optional is there, it is made clear to the
developer that the string they are showing /can be nil/. However, if you
hide that from the users you are less likely to unwrap that optional and
hence more likely to show the user "nil". This behavior really goes
against some of the core ideas of Swift - you want your code to be
expressive but not abstract away potentially useful information.

On Thu, May 19, 2016 at 12:24 AM David Waite >> <david@alkaline-solutions.com <mailto:david@alkaline-solutions.com>> wrote:

    Making string interpolation reject just optional (at compile time)
    when it doesn’t reject any other type sounds tricky to express.

    What if instead Optional just didn’t decorate the wrapped value,
    outputting either the inner value or “nil” in these cases?

    The debugDescription could remain "Optional(data)" style.

    -DW

    On May 19, 2016, at 12:52 AM, Valentin via swift-evolution >>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

    From what I understand of this thread, the argument here is that
    directly using an optional in a string interpolation is almost never
    what you really want to do (except mainly for debugging purposes)
    but you wouldn't see this mistake until much later at runtime.
    And I feel like one of Swift goals is to enable us, imperfect human
    creatures, to detect as many problems or mistakes as possible long
    before runtime.

    On 19 mai 2016, at 00:56, Dan Appel via swift-evolution >>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

    -1.

    Optional(foo) better depicts the actual type (it's an options
    string, after all). If you're not happy with it, just use the nil
    coalescing operator such as "\(foo ?? "")". This is from the same
    series of proposals as implicit casting - there are reasons it's
    done the way it is.
    On Wed, May 18, 2016 at 3:49 PM Jacob Bandes-Storch via >>>> swift-evolution <swift-evolution@swift.org >>>> <mailto:swift-evolution@swift.org>> wrote:

        +1, personally I have taken to using `x+"str"+y` instead of
        `"\(x)str\(y)"`, if x/y are strings, so I can get a
        compile-time error if I do this accidentally.

        But I do see the appeal of being able to print("the data:
        \(data)") for simple use cases. Didn't someone earlier propose
        some modifiers/labels like "\(describing: x)" ?

        On Wed, May 18, 2016 at 11:50 AM, Krystof Vasa via >>>> swift-evolution <swift-evolution@swift.org >>>> <mailto:swift-evolution@swift.org>> wrote:

            The string interpolation is one of the strong sides of
            Swift, but also one of its weaknesses.

            It has happened to me more than once that I've used the
            interpolation with an optional by mistake and the result is
            then far from the expected result.

            This happened mostly before Swift 2.0's guard expression,
            but has happened since as well.

            The user will seldomly want to really get the output
            "Optional(something)", but is almost always expecting just
            "something". I believe this should be addressed by a
            warning to force the user to check the expression to
            prevent unwanted results. If you indeed want the output of
            an optional, it's almost always better to use the ??
            operator and supply a null value placeholder, e.g.
            "\(myOptional ?? "<<none>>")", or use
            myOptional.debugDescription - which is a valid expression
            that will always return a non-optional value to force the
            current behavior.

            Krystof

            _______________________________________________
            swift-evolution mailing list
            swift-evolution@swift.org <mailto:swift-evolution@swift.org>
            https://lists.swift.org/mailman/listinfo/swift-evolution

        _______________________________________________
        swift-evolution mailing list
        swift-evolution@swift.org <mailto:swift-evolution@swift.org>
        https://lists.swift.org/mailman/listinfo/swift-evolution

    --
    Dan Appel
    _______________________________________________
    swift-evolution mailing list
    swift-evolution@swift.org <mailto:swift-evolution@swift.org>
    https://lists.swift.org/mailman/listinfo/swift-evolution

    _______________________________________________
    swift-evolution mailing list
    swift-evolution@swift.org <mailto:swift-evolution@swift.org>
    https://lists.swift.org/mailman/listinfo/swift-evolution

--
Dan Appel

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Yes, I think I agree this should show a warning, and require you to explicitly state that you are happy dealing with an optional.

Possibly you would have to add a ? suffix to make it explicit:

"http://apple.com(originalURL.path?)/help”

This would be compatible with StringInterpolationConvertible, where you may still want the original optional passed, whereas `.debugDescription` would always pass a string.

···

On 19 May 2016, at 5:39 PM, Krystof Vasa via swift-evolution <swift-evolution@swift.org> wrote:

Consider the following example:

let originalURL: NSURL = NSURL(string: "http://apple.com/iphone&quot;\)!
let newURL = NSURL(string: "http://apple.com(originalURL.path)/help <http://apple.com/(originalurl.path)/help&gt;&quot;\)

What's the newURL? Nil, because it was being inited with

http://apple.comOptional(/iphone)/help <http://apple.comoptional(/iphone)/help>

Since the path property is optional.

Which is not something you figure out until runtime, wondering why the URL is nil. This is very annoying when you run into this issue repeatedly on several occasions because you forget to unwrap the value.

*This* is IMHO an undesired and unexpected behavior.

If interpolating optionals did become a warning, you'd immediately know about a potential bug: you don't check if path != nil.

BTW if you still want the original behavior of printing

Optional(my string value),

you can still write

"http://apple.com(originalURL.path.debugDescription)/help <http://apple.com/(originalurl.path.debugdescription)/help&gt;&quot;

which invokes debugDescription on the Optional, not the String (since there is no "?"), and you get the original value anyway. And this could be the Fix-It for it as well to maintain original behavior.

Krystof

On May 19, 2016, at 9:28 AM, Dan Appel <dan.appel00@gmail.com <mailto:dan.appel00@gmail.com>> wrote:

You know what's worse than seeing "Optional(my string value)" in a label? Seeing "nil". When the optional is there, it is made clear to the developer that the string they are showing can be nil. However, if you hide that from the users you are less likely to unwrap that optional and hence more likely to show the user "nil". This behavior really goes against some of the core ideas of Swift - you want your code to be expressive but not abstract away potentially useful information.

On Thu, May 19, 2016 at 12:24 AM David Waite <david@alkaline-solutions.com <mailto:david@alkaline-solutions.com>> wrote:
Making string interpolation reject just optional (at compile time) when it doesn’t reject any other type sounds tricky to express.

What if instead Optional just didn’t decorate the wrapped value, outputting either the inner value or “nil” in these cases?

The debugDescription could remain "Optional(data)" style.

-DW

On May 19, 2016, at 12:52 AM, Valentin via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

From what I understand of this thread, the argument here is that directly using an optional in a string interpolation is almost never what you really want to do (except mainly for debugging purposes) but you wouldn't see this mistake until much later at runtime.
And I feel like one of Swift goals is to enable us, imperfect human creatures, to detect as many problems or mistakes as possible long before runtime.

On 19 mai 2016, at 00:56, Dan Appel via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

-1.

Optional(foo) better depicts the actual type (it's an options string, after all). If you're not happy with it, just use the nil coalescing operator such as "\(foo ?? "")". This is from the same series of proposals as implicit casting - there are reasons it's done the way it is.
On Wed, May 18, 2016 at 3:49 PM Jacob Bandes-Storch via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
+1, personally I have taken to using `x+"str"+y` instead of `"\(x)str\(y)"`, if x/y are strings, so I can get a compile-time error if I do this accidentally.

But I do see the appeal of being able to print("the data: \(data)") for simple use cases. Didn't someone earlier propose some modifiers/labels like "\(describing: x)" ?

On Wed, May 18, 2016 at 11:50 AM, Krystof Vasa via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
The string interpolation is one of the strong sides of Swift, but also one of its weaknesses.

It has happened to me more than once that I've used the interpolation with an optional by mistake and the result is then far from the expected result.

This happened mostly before Swift 2.0's guard expression, but has happened since as well.

The user will seldomly want to really get the output "Optional(something)", but is almost always expecting just "something". I believe this should be addressed by a warning to force the user to check the expression to prevent unwanted results. If you indeed want the output of an optional, it's almost always better to use the ?? operator and supply a null value placeholder, e.g. "\(myOptional ?? "<<none>>")", or use myOptional.debugDescription - which is a valid expression that will always return a non-optional value to force the current behavior.

Krystof

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution
--
Dan Appel
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

--
Dan Appel

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Sure, though not all apps are designed to be localized and can serve for internal purposes or simply the developer can say that he's supporting English (or another language) only - that's entirely his decision.

Also some strings, do not get localized. For example some kinds of string-ified lists, when you put together name of the app + version + build, etc.

···

On May 19, 2016, at 7:41 PM, David Rönnqvist <david.ronnqvist@gmail.com> wrote:

Forget me if I'm wrong, but wouldn't localization requirements make string interpolation unsuitable for user facing strings anyway?

(I remember localization being discussed previously, but don't recall it turning into a proposal)

- David

Sent from my iPhone

On 19 May 2016, at 19:06, Krystof Vasa via swift-evolution <swift-evolution@swift.org> wrote:

I'm wondering which scenario this is actually wanted behavior:

- strings that are for user interaction? Definitely not.
- logs? To be honest, the logs riddled with Optional(value) are pain to read. Following example:

key1: Optional("Value")
key2: nil

vs

key1: Value
key2: nil

Which is more readable in the log?

I just don't see the benefit of the current behavior than perhaps in Xcode's playground where it displays the value on the right and perhaps a few minor cases - but definitely not 99% of the time.

This is IMHO not crippling interpolation, just asking for a non-nil values for it to be interpoled with.

Krystof

On May 19, 2016, at 6:07 PM, Jeremy Pereira via swift-evolution <swift-evolution@swift.org> wrote:

-1

This seems to me like crippling string interpolation just because sometimes we make mistakes. 99% of the time, if I interpolate an optional, it’s because I want it that way. I don’t want to have to put up with a warning or write the same boilerplate 99% of the time just to flag up the 1% more easily. Sorry.

On 18 May 2016, at 19:50, Krystof Vasa via swift-evolution <swift-evolution@swift.org> wrote:

The string interpolation is one of the strong sides of Swift, but also one of its weaknesses.

It has happened to me more than once that I've used the interpolation with an optional by mistake and the result is then far from the expected result.

This happened mostly before Swift 2.0's guard expression, but has happened since as well.

The user will seldomly want to really get the output "Optional(something)", but is almost always expecting just "something". I believe this should be addressed by a warning to force the user to check the expression to prevent unwanted results. If you indeed want the output of an optional, it's almost always better to use the ?? operator and supply a null value placeholder, e.g. "\(myOptional ?? "<<none>>")", or use myOptional.debugDescription - which is a valid expression that will always return a non-optional value to force the current behavior.

Krystof

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

With this proposal in place:

1) The user would type print(myURL.path).
2) The compiler will immediately issue a warning about printing an optional - the user would hence learn about optionals *before* the code is run.
3) If he ran the code anyway, he'd still get Optional(/iphone/) anyway.
4) Xcode would offer a Fix-It, adding .debugDescription to the optional, getting Optional(/iphone/) on the anyway, yet again.

Four questions:
1. If I was printing a protocol type that Optional supports, such as Any, would I get a warning?
2. I believe debugDescription is discouraged from being called directly [from CustomDebugStringConvertible docs]. Perhaps String(reflecting: ) instead, although such debug description behavior could cause different results if you were expecting this fixit to apply to Any types.
3. How would I have the ability to opt into this behavior for my own types (such as Result or Future)?
4. How would I opt in/out of this behavior for my own StringInterpolationConvertible implementations?

-DW

···

On May 19, 2016, at 11:01 PM, Krystof Vasa via swift-evolution <swift-evolution@swift.org> wrote:

I'm not saying *removing* the current behavior, but adding a warning for this - you'd get the same result ignoring the warning and applying the Fix-It, but you'd have control over this.

On May 20, 2016, at 6:48 AM, Dan Appel via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

>google for swift print optional stackoverflow. I think that kind of speaks for itself.

I think this is actually an example of why the current behavior is a good thing. I did just google that and the top comment of the first result explains what an optional is. That is very good and encourages beginners to understand how optionals work under the hood. If you hide that from them, they will only be even more confused when they see just the string "nil" pop up when it previously was showing the correct value.

On Thu, May 19, 2016 at 9:36 PM Krystof Vasa via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
BTW - google for swift print optional stackoverflow. I think that kind of speaks for itself.

> On May 19, 2016, at 6:07 PM, Jeremy Pereira via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>
> -1
>
> This seems to me like crippling string interpolation just because sometimes we make mistakes. 99% of the time, if I interpolate an optional, it’s because I want it that way. I don’t want to have to put up with a warning or write the same boilerplate 99% of the time just to flag up the 1% more easily. Sorry.
>
>> On 18 May 2016, at 19:50, Krystof Vasa via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>
>> The string interpolation is one of the strong sides of Swift, but also one of its weaknesses.
>>
>> It has happened to me more than once that I've used the interpolation with an optional by mistake and the result is then far from the expected result.
>>
>> This happened mostly before Swift 2.0's guard expression, but has happened since as well.
>>
>> The user will seldomly want to really get the output "Optional(something)", but is almost always expecting just "something". I believe this should be addressed by a warning to force the user to check the expression to prevent unwanted results. If you indeed want the output of an optional, it's almost always better to use the ?? operator and supply a null value placeholder, e.g. "\(myOptional ?? "<<none>>")", or use myOptional.debugDescription - which is a valid expression that will always return a non-optional value to force the current behavior.
>>
>> Krystof
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution
--
Dan Appel
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Thats a fair solution. I still disagree, but not as strongly.

···

On Thu, May 19, 2016 at 10:01 PM Krystof Vasa <kvasa@icloud.com> wrote:

With this proposal in place:

1) The user would type print(myURL.path).
2) The compiler will immediately issue a warning about printing an
optional - the user would hence learn about optionals *before* the code is
run.
3) If he ran the code anyway, he'd still get Optional(/iphone/) anyway.
4) Xcode would offer a Fix-It, adding .debugDescription to the optional,
getting Optional(/iphone/) on the anyway, yet again.

I'm not saying *removing* the current behavior, but adding a warning for
this - you'd get the same result ignoring the warning and applying the
Fix-It, but you'd have control over this.

On May 20, 2016, at 6:48 AM, Dan Appel via swift-evolution < > swift-evolution@swift.org> wrote:

>google for swift print optional stackoverflow. I think that kind of
speaks for itself.

I think this is actually an example of why the current behavior is a
*good* thing. I did just google that and the top comment of the first
result explains what an optional is. That is very good and encourages
beginners to understand how optionals work under the hood. If you hide that
from them, they will only be even more confused when they see just the
string "nil" pop up when it previously was showing the correct value.

On Thu, May 19, 2016 at 9:36 PM Krystof Vasa via swift-evolution < > swift-evolution@swift.org> wrote:

BTW - google for swift print optional stackoverflow. I think that kind of
speaks for itself.

> On May 19, 2016, at 6:07 PM, Jeremy Pereira via swift-evolution < >> swift-evolution@swift.org> wrote:
>
> -1
>
> This seems to me like crippling string interpolation just because
sometimes we make mistakes. 99% of the time, if I interpolate an optional,
it’s because I want it that way. I don’t want to have to put up with a
warning or write the same boilerplate 99% of the time just to flag up the
1% more easily. Sorry.
>
>> On 18 May 2016, at 19:50, Krystof Vasa via swift-evolution < >> swift-evolution@swift.org> wrote:
>>
>> The string interpolation is one of the strong sides of Swift, but also
one of its weaknesses.
>>
>> It has happened to me more than once that I've used the interpolation
with an optional by mistake and the result is then far from the expected
result.
>>
>> This happened mostly before Swift 2.0's guard expression, but has
happened since as well.
>>
>> The user will seldomly want to really get the output
"Optional(something)", but is almost always expecting just "something". I
believe this should be addressed by a warning to force the user to check
the expression to prevent unwanted results. If you indeed want the output
of an optional, it's almost always better to use the ?? operator and supply
a null value placeholder, e.g. "\(myOptional ?? "<<none>>")", or use
myOptional.debugDescription - which is a valid expression that will always
return a non-optional value to force the current behavior.
>>
>> Krystof
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
Dan Appel
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--

Dan Appel

Sorry, my previous example didn't use the string interpolation, it should be

print("http://apple.com(myURL.path)").

···

On May 20, 2016, at 7:04 AM, Dan Appel <dan.appel00@gmail.com> wrote:

Thats a fair solution. I still disagree, but not as strongly.

On Thu, May 19, 2016 at 10:01 PM Krystof Vasa <kvasa@icloud.com <mailto:kvasa@icloud.com>> wrote:
With this proposal in place:

1) The user would type print(myURL.path).
2) The compiler will immediately issue a warning about printing an optional - the user would hence learn about optionals *before* the code is run.
3) If he ran the code anyway, he'd still get Optional(/iphone/) anyway.
4) Xcode would offer a Fix-It, adding .debugDescription to the optional, getting Optional(/iphone/) on the anyway, yet again.

I'm not saying *removing* the current behavior, but adding a warning for this - you'd get the same result ignoring the warning and applying the Fix-It, but you'd have control over this.

On May 20, 2016, at 6:48 AM, Dan Appel via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

>google for swift print optional stackoverflow. I think that kind of speaks for itself.

I think this is actually an example of why the current behavior is a good thing. I did just google that and the top comment of the first result explains what an optional is. That is very good and encourages beginners to understand how optionals work under the hood. If you hide that from them, they will only be even more confused when they see just the string "nil" pop up when it previously was showing the correct value.

On Thu, May 19, 2016 at 9:36 PM Krystof Vasa via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
BTW - google for swift print optional stackoverflow. I think that kind of speaks for itself.

> On May 19, 2016, at 6:07 PM, Jeremy Pereira via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>
> -1
>
> This seems to me like crippling string interpolation just because sometimes we make mistakes. 99% of the time, if I interpolate an optional, it’s because I want it that way. I don’t want to have to put up with a warning or write the same boilerplate 99% of the time just to flag up the 1% more easily. Sorry.
>
>> On 18 May 2016, at 19:50, Krystof Vasa via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>
>> The string interpolation is one of the strong sides of Swift, but also one of its weaknesses.
>>
>> It has happened to me more than once that I've used the interpolation with an optional by mistake and the result is then far from the expected result.
>>
>> This happened mostly before Swift 2.0's guard expression, but has happened since as well.
>>
>> The user will seldomly want to really get the output "Optional(something)", but is almost always expecting just "something". I believe this should be addressed by a warning to force the user to check the expression to prevent unwanted results. If you indeed want the output of an optional, it's almost always better to use the ?? operator and supply a null value placeholder, e.g. "\(myOptional ?? "<<none>>")", or use myOptional.debugDescription - which is a valid expression that will always return a non-optional value to force the current behavior.
>>
>> Krystof
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution
--
Dan Appel
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

--
Dan Appel

Four questions:
1. If I was printing a protocol type that Optional supports, such as Any, would I get a warning?

This was my bad, I wrote an incorrect example, print("http://apple.com(myURL.path)") was what I meant - which will print

http://apple.comOptional(/iphone/).

Putting an optional directly into print(_:) should be fine with no warning. Only within the string interpolation.

2. I believe debugDescription is discouraged from being called directly [from CustomDebugStringConvertible docs]. Perhaps String(reflecting: ) instead, although such debug description behavior could cause different results if you were expecting this fixit to apply to Any types.

This is not invoked on the value within the Optional, but directly *on* the Optional. As declared here (part of Swift):

extension Optional : CustomDebugStringConvertible {
    /// A textual representation of `self`, suitable for debugging.
    public var debugDescription: String { get }
}

Example:

let stringOptional: String? = "Hello"

// Notice no ? is used - the optional is not unwrapped
stringOptional.debugDescription // Optional(Hello)

// Unwrapping the optional
stringOptional!.debugDescription // Hello

Not sure what would be the impact of making Optional CustomStringConvertible (i.e. instead of using debugDescription, one would use just description).

3. How would I have the ability to opt into this behavior for my own types (such as Result or Future)?
4. How would I opt in/out of this behavior for my own StringInterpolationConvertible implementations?

This is not about customizing the interpolation but about warning the user when using optionals in string interpolation to prevent from such mistakes as above with the URL. This is more common than one would think and sometimes is hard to spot. I'm sorry if I misunderstood you questions.

···

-DW

I'm not saying *removing* the current behavior, but adding a warning for this - you'd get the same result ignoring the warning and applying the Fix-It, but you'd have control over this.

On May 20, 2016, at 6:48 AM, Dan Appel via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

>google for swift print optional stackoverflow. I think that kind of speaks for itself.

I think this is actually an example of why the current behavior is a good thing. I did just google that and the top comment of the first result explains what an optional is. That is very good and encourages beginners to understand how optionals work under the hood. If you hide that from them, they will only be even more confused when they see just the string "nil" pop up when it previously was showing the correct value.

On Thu, May 19, 2016 at 9:36 PM Krystof Vasa via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
BTW - google for swift print optional stackoverflow. I think that kind of speaks for itself.

> On May 19, 2016, at 6:07 PM, Jeremy Pereira via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>
> -1
>
> This seems to me like crippling string interpolation just because sometimes we make mistakes. 99% of the time, if I interpolate an optional, it’s because I want it that way. I don’t want to have to put up with a warning or write the same boilerplate 99% of the time just to flag up the 1% more easily. Sorry.
>
>> On 18 May 2016, at 19:50, Krystof Vasa via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>
>> The string interpolation is one of the strong sides of Swift, but also one of its weaknesses.
>>
>> It has happened to me more than once that I've used the interpolation with an optional by mistake and the result is then far from the expected result.
>>
>> This happened mostly before Swift 2.0's guard expression, but has happened since as well.
>>
>> The user will seldomly want to really get the output "Optional(something)", but is almost always expecting just "something". I believe this should be addressed by a warning to force the user to check the expression to prevent unwanted results. If you indeed want the output of an optional, it's almost always better to use the ?? operator and supply a null value placeholder, e.g. "\(myOptional ?? "<<none>>")", or use myOptional.debugDescription - which is a valid expression that will always return a non-optional value to force the current behavior.
>>
>> Krystof
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution
--
Dan Appel
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

I would suggest something like the following (yeah I would URLComponents
for this but this is just an example)... basically a short hand of some
type for (a != nil ? a : b) to deal with optional in string construction.

"http://\(self.username + "@" : "default")@
my.host.com/pictures/\(self.pictureId : "")

···

On Tue, Jul 5, 2016 at 7:14 AM James Campbell via swift-evolution < swift-evolution@swift.org> wrote:

What would be a better alternative is the ability to have a String Format
Token that would unwrap a value, like so

let string = String(format: "http://%?/", url)

None is unwrapped to "http:///"
Some is unwrapped to "http://myurl.com/&quot;

I think this would be a good trade off rather than having to do an awkward
guard dance, make your code unsafe with force-unwraps or end-up with
"Optional()" in your string.

*___________________________________*

*James⎥Head of Trolls*

*james@supmenow.com <james@supmenow.com>⎥supmenow.com
<http://supmenow.com>*

*Sup*

*Runway East *

*10 Finsbury Square*

*London*

* EC2A 1AF *

On 4 July 2016 at 16:41, Krystof Vasa via swift-evolution < > swift-evolution@swift.org> wrote:

This is now being tracked as [SR-1882] String Interpolation of Optionals · Issue #44491 · apple/swift · GitHub -
Chris (Lattner) thought this should not go through the official proposal
process as something more complicated, but just add a warning with
redundant parentheses around it silencing the warning (
http://article.gmane.org/gmane.comp.lang.swift.evolution/20960\).

The latest version of the proposal (that's not going to happen) can be
found here -
https://gist.github.com/charlieMonroe/82e1519dd2b57029f69bc7abe99d7385 -
and I've implemented it for my own use here:

https://github.com/charlieMonroe/XUCore/blob/master/XUCore/additions/OptionalAdditions.swift

I find it better readable than using ?? or extra parentheses around the
Optional...

On Jul 4, 2016, at 5:31 PM, David Beck via swift-evolution < >> swift-evolution@swift.org> wrote:

> The string interpolation is one of the strong sides of Swift, but also
one of its weaknesses.
>
> It has happened to me more than once that I've used the interpolation
with an optional by mistake and the result is then far from the expected
result.
>
> This happened mostly before Swift 2.0's guard expression, but has
happened since as well.
>
> The user will seldomly want to really get the output
"Optional(something)", but is almost always expecting just "something". I
believe this should be addressed by a warning to force the user to check
the expression to prevent unwanted results. If you indeed want the output
of an optional, it's almost always better to use the ?? operator and supply
a null value placeholder, e.g. "\(myOptional ?? "<<none>>")", or use
myOptional.debugDescription - which is a valid expression that will always
return a non-optional value to force the current behavior.
>
> Krystof
>
>
>

I really hope a proposal that solves this problem gets through, but I’m
not sure blocking optionals specifically is the way to go. In particular
there are other types that don’t have a clean string representation. I
think that by default string interpolation (meaning String creation
specifically) should only accept ValuePreservingStringConvertible types and
produce an error for everything else.

But, in addition, we need a way to quickly print out values for
debugging. I think a new string type (DebugString for example) would be
useful for this. print and similar functions could take that as an argument
and any type could be interpolated in it’s argument. Further, if you simply
say `let a = “\(something)”` and something
isn’t ValuePreservingStringConvertible, the type of a should then be
DebugString. Converting to string should be strait forward, but require a
small step to make it obvious that you are using a string that could have
weird characters.

*David Beck*
http://davidbeck.co
http://twitter.com/davbeck
David Beck

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Oops remove the duplicate "@" in my example.

···

On Tue, Jul 5, 2016 at 7:27 AM Shawn Erickson <shawnce@gmail.com> wrote:

I would suggest something like the following (yeah I would URLComponents
for this but this is just an example)... basically a short hand of some
type for (a != nil ? a : b) to deal with optional in string construction.

"http://\(self.username + "@" : "default")@
my.host.com/pictures/\(self.pictureId
<http://my.host.com/pictures/\\(self.pictureId> : "")
On Tue, Jul 5, 2016 at 7:14 AM James Campbell via swift-evolution < > swift-evolution@swift.org> wrote:

What would be a better alternative is the ability to have a String Format
Token that would unwrap a value, like so

let string = String(format: "http://%?/", url)

None is unwrapped to "http:///"
Some is unwrapped to "http://myurl.com/&quot;

I think this would be a good trade off rather than having to do an
awkward guard dance, make your code unsafe with force-unwraps or end-up
with "Optional()" in your string.

*___________________________________*

*James⎥Head of Trolls*

*james@supmenow.com <james@supmenow.com>⎥supmenow.com
<http://supmenow.com>*

*Sup*

*Runway East *

*10 Finsbury Square*

*London*

* EC2A 1AF *

On 4 July 2016 at 16:41, Krystof Vasa via swift-evolution < >> swift-evolution@swift.org> wrote:

This is now being tracked as [SR-1882] String Interpolation of Optionals · Issue #44491 · apple/swift · GitHub -
Chris (Lattner) thought this should not go through the official proposal
process as something more complicated, but just add a warning with
redundant parentheses around it silencing the warning (
http://article.gmane.org/gmane.comp.lang.swift.evolution/20960\).

The latest version of the proposal (that's not going to happen) can be
found here -
https://gist.github.com/charlieMonroe/82e1519dd2b57029f69bc7abe99d7385 -
and I've implemented it for my own use here:

https://github.com/charlieMonroe/XUCore/blob/master/XUCore/additions/OptionalAdditions.swift

I find it better readable than using ?? or extra parentheses around the
Optional...

On Jul 4, 2016, at 5:31 PM, David Beck via swift-evolution < >>> swift-evolution@swift.org> wrote:

> The string interpolation is one of the strong sides of Swift, but also
one of its weaknesses.
>
> It has happened to me more than once that I've used the interpolation
with an optional by mistake and the result is then far from the expected
result.
>
> This happened mostly before Swift 2.0's guard expression, but has
happened since as well.
>
> The user will seldomly want to really get the output
"Optional(something)", but is almost always expecting just "something". I
believe this should be addressed by a warning to force the user to check
the expression to prevent unwanted results. If you indeed want the output
of an optional, it's almost always better to use the ?? operator and supply
a null value placeholder, e.g. "\(myOptional ?? "<<none>>")", or use
myOptional.debugDescription - which is a valid expression that will always
return a non-optional value to force the current behavior.
>
> Krystof
>
>
>

I really hope a proposal that solves this problem gets through, but I’m
not sure blocking optionals specifically is the way to go. In particular
there are other types that don’t have a clean string representation. I
think that by default string interpolation (meaning String creation
specifically) should only accept ValuePreservingStringConvertible types and
produce an error for everything else.

But, in addition, we need a way to quickly print out values for
debugging. I think a new string type (DebugString for example) would be
useful for this. print and similar functions could take that as an argument
and any type could be interpolated in it’s argument. Further, if you simply
say `let a = “\(something)”` and something
isn’t ValuePreservingStringConvertible, the type of a should then be
DebugString. Converting to string should be strait forward, but require a
small step to make it obvious that you are using a string that could have
weird characters.

*David Beck*
http://davidbeck.co
http://twitter.com/davbeck
David Beck

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

I think displaying a warning instead of deprecation would suffice.

A down vote for deprecation.

···

On 19 May 2016, 4:06 PM +0800, Patrick Smith via swift-evolution<swift-evolution@swift.org>, wrote:

Yes, I think I agree this should show a warning, and require you to explicitly state that you are happy dealing with an optional.

Possibly you would have to add a ? suffix to make it explicit:

"http://apple.com(originalURL.path?)/help(http://apple.com/(originalurl.path?)/help\)”

This would be compatible withStringInterpolationConvertible, where you may still want the original optional passed, whereas `.debugDescription` would always pass a string.

> On 19 May 2016, at 5:39 PM, Krystof Vasa via swift-evolution<swift-evolution@swift.org(mailto:swift-evolution@swift.org)>wrote:
> Consider the following example:
>
> let originalURL: NSURL = NSURL(string: "http://apple.com/iphone&quot;\)!
> let newURL = NSURL(string: "http://apple.com(originalURL.path)/help(http://apple.com/(originalurl.path)/help\)")
>
> What's the newURL? Nil, because it was being inited with
>
> http://apple.comOptional(/iphone)/help(http://apple.comoptional(/iphone)/help)
>
> Since the path property is optional.
>
> Which is not something you figure out until runtime, wondering why the URL is nil. This is very annoying when you run into this issue repeatedly on several occasions because you forget to unwrap the value.
>
> *This* is IMHO an undesired and unexpected behavior.
>
> If interpolating optionals did become a warning, you'd immediately know about a potential bug: you don't check if path != nil.
>
> BTW if you still want the original behavior of printing
>
> Optional(my string value),
>
> you can still write
>
> "http://apple.com(originalURL.path.debugDescription)/help(http://apple.com/(originalurl.path.debugdescription)/help\)"
>
> which invokes debugDescription on the Optional, not the String (since there is no "?"), and you get the original value anyway. And this could be the Fix-It for it as well to maintain original behavior.
>
> Krystof
>
> > On May 19, 2016, at 9:28 AM, Dan Appel<dan.appel00@gmail.com(mailto:dan.appel00@gmail.com)>wrote:
> > You know what's worse than seeing "Optional(my string value)" in a label? Seeing "nil". When the optional is there, it is made clear to the developer that the string they are showingcan be nil. However, if you hide that from the users you are less likely to unwrap that optional and hence more likely to show the user "nil". This behavior really goes against some of the core ideas of Swift - you want your code to be expressive but not abstract away potentially useful information.
> > On Thu, May 19, 2016 at 12:24 AM David Waite<david@alkaline-solutions.com(mailto:david@alkaline-solutions.com)>wrote:
> > > Making string interpolation reject just optional (at compile time) when it doesn’t reject any other type sounds tricky to express.
> > >
> > > What if instead Optional just didn’t decorate the wrapped value, outputting either the inner value or “nil” in these cases?
> > >
> > > The debugDescription could remain "Optional(data)" style.
> > >
> > > -DW
> > >
> > > > On May 19, 2016, at 12:52 AM, Valentin via swift-evolution<swift-evolution@swift.org(mailto:swift-evolution@swift.org)>wrote:
> > > > From what I understand of this thread, the argument here is that directly using an optional in a string interpolation is almost never what you really want to do (except mainly for debugging purposes) but you wouldn't see this mistake until much later at runtime.
> > > > And I feel like one of Swift goals is to enable us, imperfect human creatures, to detect as many problems or mistakes as possible long before runtime.
> > > >
> > > > On 19 mai 2016, at 00:56, Dan Appel via swift-evolution<swift-evolution@swift.org(mailto:swift-evolution@swift.org)>wrote:
> > > >
> > > > > -1.
> > > > >
> > > > > Optional(foo) better depicts the actual type (it's an options string, after all). If you're not happy with it, just use the nil coalescing operator such as "\(foo ?? "")". This is from the same series of proposals as implicit casting - there are reasons it's done the way it is.
> > > > > On Wed, May 18, 2016 at 3:49 PM Jacob Bandes-Storch via swift-evolution<swift-evolution@swift.org(mailto:swift-evolution@swift.org)>wrote:
> > > > > > +1, personally I have taken to using `x+"str"+y` instead of `"\(x)str\(y)"`, if x/y are strings, so I can get a compile-time error if I do this accidentally.
> > > > > >
> > > > > > But I do see the appeal of being able to print("the data: \(data)") for simple use cases. Didn't someone earlier propose some modifiers/labels like "\(describing: x)" ?
> > > > > >
> > > > > >
> > > > > > On Wed, May 18, 2016 at 11:50 AM, Krystof Vasa via swift-evolution<swift-evolution@swift.org(mailto:swift-evolution@swift.org)>wrote:
> > > > > > > The string interpolation is one of the strong sides of Swift, but also one of its weaknesses.
> > > > > > >
> > > > > > > It has happened to me more than once that I've used the interpolation with an optional by mistake and the result is then far from the expected result.
> > > > > > >
> > > > > > > This happened mostly before Swift 2.0's guard expression, but has happened since as well.
> > > > > > >
> > > > > > > The user will seldomly want to really get the output "Optional(something)", but is almost always expecting just "something". I believe this should be addressed by a warning to force the user to check the expression to prevent unwanted results. If you indeed want the output of an optional, it's almost always better to use the ?? operator and supply a null value placeholder, e.g. "\(myOptional ?? "<<none>>")", or use myOptional.debugDescription - which is a valid expression that will always return a non-optional value to force the current behavior.
> > > > > > >
> > > > > > > Krystof
> > > > > > >
> > > > > > > _______________________________________________
> > > > > > > swift-evolution mailing list
> > > > > > > swift-evolution@swift.org(mailto:swift-evolution@swift.org)
> > > > > > > https://lists.swift.org/mailman/listinfo/swift-evolution
> > > > > >
> > > > > > _______________________________________________
> > > > > > swift-evolution mailing list
> > > > > > swift-evolution@swift.org(mailto:swift-evolution@swift.org)
> > > > > > https://lists.swift.org/mailman/listinfo/swift-evolution
> > > > > --
> > > > > Dan Appel
> > > > > _______________________________________________
> > > > > swift-evolution mailing list
> > > > > swift-evolution@swift.org(mailto:swift-evolution@swift.org)
> > > > > https://lists.swift.org/mailman/listinfo/swift-evolution
> > > > _______________________________________________
> > > > swift-evolution mailing list
> > > > swift-evolution@swift.org(mailto:swift-evolution@swift.org)
> > > > https://lists.swift.org/mailman/listinfo/swift-evolution
> > >
> > --
> > Dan Appel
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org(mailto:swift-evolution@swift.org)
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

I've been bit by this many times. A warning would really have helped me.

···

On 20 May 2016, at 07:06, Krystof Vasa via swift-evolution <swift-evolution@swift.org> wrote:

Sorry, my previous example didn't use the string interpolation, it should be

print("http://apple.com(myURL.path)").

On May 20, 2016, at 7:04 AM, Dan Appel <dan.appel00@gmail.com> wrote:

Thats a fair solution. I still disagree, but not as strongly.

On Thu, May 19, 2016 at 10:01 PM Krystof Vasa <kvasa@icloud.com> wrote:

With this proposal in place:

1) The user would type print(myURL.path).
2) The compiler will immediately issue a warning about printing an optional - the user would hence learn about optionals *before* the code is run.
3) If he ran the code anyway, he'd still get Optional(/iphone/) anyway.
4) Xcode would offer a Fix-It, adding .debugDescription to the optional, getting Optional(/iphone/) on the anyway, yet again.

I'm not saying *removing* the current behavior, but adding a warning for this - you'd get the same result ignoring the warning and applying the Fix-It, but you'd have control over this.

On May 20, 2016, at 6:48 AM, Dan Appel via swift-evolution <swift-evolution@swift.org> wrote:

>google for swift print optional stackoverflow. I think that kind of speaks for itself.

I think this is actually an example of why the current behavior is a good thing. I did just google that and the top comment of the first result explains what an optional is. That is very good and encourages beginners to understand how optionals work under the hood. If you hide that from them, they will only be even more confused when they see just the string "nil" pop up when it previously was showing the correct value.

On Thu, May 19, 2016 at 9:36 PM Krystof Vasa via swift-evolution <swift-evolution@swift.org> wrote:
BTW - google for swift print optional stackoverflow. I think that kind of speaks for itself.

> On May 19, 2016, at 6:07 PM, Jeremy Pereira via swift-evolution <swift-evolution@swift.org> wrote:
>
> -1
>
> This seems to me like crippling string interpolation just because sometimes we make mistakes. 99% of the time, if I interpolate an optional, it’s because I want it that way. I don’t want to have to put up with a warning or write the same boilerplate 99% of the time just to flag up the 1% more easily. Sorry.
>
>> On 18 May 2016, at 19:50, Krystof Vasa via swift-evolution <swift-evolution@swift.org> wrote:
>>
>> The string interpolation is one of the strong sides of Swift, but also one of its weaknesses.
>>
>> It has happened to me more than once that I've used the interpolation with an optional by mistake and the result is then far from the expected result.
>>
>> This happened mostly before Swift 2.0's guard expression, but has happened since as well.
>>
>> The user will seldomly want to really get the output "Optional(something)", but is almost always expecting just "something". I believe this should be addressed by a warning to force the user to check the expression to prevent unwanted results. If you indeed want the output of an optional, it's almost always better to use the ?? operator and supply a null value placeholder, e.g. "\(myOptional ?? "<<none>>")", or use myOptional.debugDescription - which is a valid expression that will always return a non-optional value to force the current behavior.
>>
>> Krystof
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
Dan Appel
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
Dan Appel

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

I've jotted up a proposal here:

Please let me know if there are any comments to it.

Charlie

···

On May 20, 2016, at 9:11 AM, Krystof Vasa via swift-evolution <swift-evolution@swift.org> wrote:

Four questions:
1. If I was printing a protocol type that Optional supports, such as Any, would I get a warning?

This was my bad, I wrote an incorrect example, print("http://apple.com(myURL.path) <http://apple.com/(myurl.path)&gt;&quot;\) was what I meant - which will print

http://apple.comOptional(/iphone/) <http://apple.comoptional(/iphone/)>.

Putting an optional directly into print(_:) should be fine with no warning. Only within the string interpolation.

2. I believe debugDescription is discouraged from being called directly [from CustomDebugStringConvertible docs]. Perhaps String(reflecting: ) instead, although such debug description behavior could cause different results if you were expecting this fixit to apply to Any types.

This is not invoked on the value within the Optional, but directly *on* the Optional. As declared here (part of Swift):

extension Optional : CustomDebugStringConvertible {
    /// A textual representation of `self`, suitable for debugging.
    public var debugDescription: String { get }
}

Example:

let stringOptional: String? = "Hello"

// Notice no ? is used - the optional is not unwrapped
stringOptional.debugDescription // Optional(Hello)

// Unwrapping the optional
stringOptional!.debugDescription // Hello

Not sure what would be the impact of making Optional CustomStringConvertible (i.e. instead of using debugDescription, one would use just description).

3. How would I have the ability to opt into this behavior for my own types (such as Result or Future)?
4. How would I opt in/out of this behavior for my own StringInterpolationConvertible implementations?

This is not about customizing the interpolation but about warning the user when using optionals in string interpolation to prevent from such mistakes as above with the URL. This is more common than one would think and sometimes is hard to spot. I'm sorry if I misunderstood you questions.

-DW

I'm not saying *removing* the current behavior, but adding a warning for this - you'd get the same result ignoring the warning and applying the Fix-It, but you'd have control over this.

On May 20, 2016, at 6:48 AM, Dan Appel via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

>google for swift print optional stackoverflow. I think that kind of speaks for itself.

I think this is actually an example of why the current behavior is a good thing. I did just google that and the top comment of the first result explains what an optional is. That is very good and encourages beginners to understand how optionals work under the hood. If you hide that from them, they will only be even more confused when they see just the string "nil" pop up when it previously was showing the correct value.

On Thu, May 19, 2016 at 9:36 PM Krystof Vasa via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
BTW - google for swift print optional stackoverflow. I think that kind of speaks for itself.

> On May 19, 2016, at 6:07 PM, Jeremy Pereira via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>
> -1
>
> This seems to me like crippling string interpolation just because sometimes we make mistakes. 99% of the time, if I interpolate an optional, it’s because I want it that way. I don’t want to have to put up with a warning or write the same boilerplate 99% of the time just to flag up the 1% more easily. Sorry.
>
>> On 18 May 2016, at 19:50, Krystof Vasa via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>
>> The string interpolation is one of the strong sides of Swift, but also one of its weaknesses.
>>
>> It has happened to me more than once that I've used the interpolation with an optional by mistake and the result is then far from the expected result.
>>
>> This happened mostly before Swift 2.0's guard expression, but has happened since as well.
>>
>> The user will seldomly want to really get the output "Optional(something)", but is almost always expecting just "something". I believe this should be addressed by a warning to force the user to check the expression to prevent unwanted results. If you indeed want the output of an optional, it's almost always better to use the ?? operator and supply a null value placeholder, e.g. "\(myOptional ?? "<<none>>")", or use myOptional.debugDescription - which is a valid expression that will always return a non-optional value to force the current behavior.
>>
>> Krystof
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution
--
Dan Appel
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

I’m still unclear what the answers to my questions below would be. I’ll restate them below.

1. If I was printing a protocol type that Optional supports, such as Any, would I get a warning?

Since this may have been misunderstood, let me phrase it a different way.

If the URL path property was defined not to return ‘String?' but to return ‘Any’ (which can of course hold an Optional just like it can hold any other type) what would the proposed compiler behavior be?

2. I believe debugDescription is discouraged from being called directly [from CustomDebugStringConvertible docs]. Perhaps String(reflecting: ) instead, although such debug description behavior could cause different results if you were expecting this fixit to apply to Any types.

The actual definition of debugDescription is discouraged from being called by user code. This method also only coincidentally provides the identical text as string interpolation today. Are you proposing to change the standard library documentation to say that users should be calling debugDescription in this scenario, and change optional to define what its implementation of debugDescription returns?

3. How would I have the ability to opt into this behavior for my own types (such as Result or Future)?
4. How would I opt in/out of this behavior for my own StringInterpolationConvertible implementations?

This is not about customizing the interpolation but about warning the user when using optionals in string interpolation to prevent from such mistakes as above with the URL. This is more common than one would think and sometimes is hard to spot. I'm sorry if I misunderstood you questions.

If I have a type which I don’t want used in String interpolation, I would like to mark it as giving a warning. Examples would be a Result type for representing success or error from a function call, or a future type to represent a task dispatched to another thread that may or may not have finished and returned a result yet. Do you propose a way for me to have the compiler warn if I accidentally have these types used in string interpolation as well, or do I only benefit from optional as a special case.

And finally, I can have my own type which implements StringInterpolationConvertible. Examples might be
- LocalizableString type which maps the provided string to correct user output through a localization table
- DebugString for debug logging that uses CustomDebugStringConvertible when available to represent types
- an HtmlEscapedString which deals with making values that don’t implement the HtmlEscaped protocol HTML-safe, including Strings

How would I get the optional usage defined for String type interpolation for these cases. DebugString would like to represent optionals as today, LocalizableString would like to capture optionals so that it can switch to a specific internationalized message in this case, and HtmlEscapedString would like the same behavior you are proposing for String.

-DW

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:

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

If the URL path property was defined not to return ‘String?' but to return ‘Any’ (which can of course hold an Optional just like it can hold any other type) what would the proposed compiler behavior be?

No warning. Since you cast Optional to Any, no warning can even be issued since that will eventually be determined during runtime, there's not much the compiler can do here.

Only if you returned `Any?` - which then Optional<Any>, anyway.

The actual definition of debugDescription is discouraged from being called by user code. This method also only coincidentally provides the identical text as string interpolation today. Are you proposing to change the standard library documentation to say that users should be calling debugDescription in this scenario, and change optional to define what its implementation of debugDescription returns?

What about adding .description (i.e. comply to CustomStringConvertible) and calling .description instead? I'll update the proposal to match this.

If I have a type which I don’t want used in String interpolation, I would like to mark it as giving a warning. Examples would be a Result type for representing success or error from a function call, or a future type to represent a task dispatched to another thread that may or may not have finished and returned a result yet. Do you propose a way for me to have the compiler warn if I accidentally have these types used in string interpolation as well, or do I only benefit from optional as a special case.

I'd prefer to leave the Optional as a special case handled by the language, but you can deprecate interpolation for custom types yourself - see below.

And finally, I can have my own type which implements StringInterpolationConvertible. Examples might be
- LocalizableString type which maps the provided string to correct user output through a localization table
- DebugString for debug logging that uses CustomDebugStringConvertible when available to represent types
- an HtmlEscapedString which deals with making values that don’t implement the HtmlEscaped protocol HTML-safe, including Strings

How would I get the optional usage defined for String type interpolation for these cases. DebugString would like to represent optionals as today, LocalizableString would like to capture optionals so that it can switch to a specific internationalized message in this case, and HtmlEscapedString would like the same behavior you are proposing for String.

The deprecation doesn't necessarily need to be handled by the compiler itself, but can be enforced by the following code:

extension String {
  
  @available(*, deprecated, message="Interpolation of optionals is deprecated.")
  init<T>(stringInterpolationSegment segment: Optional<T>) {
    // fatalError()
  }
  
}

With this kind of implementation, you get the warnings, however, without the compiler support you won't get the Fix-It for adding .description - I'm not sure the renamed= part of the attribute can be abused to do this, but I don't think it can be.

And in a similar fashion, you can deprecate the Optional or any other kind on your other strings and keep them on DebugString.

Charlie

···

-DW

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.