[swift-evolution] guard let x = x

Pyry Jahkola pyry.jahkola at iki.fi
Thu Nov 3 03:17:27 CDT 2016


As pleasing as it sounds*), the idea of type narrowing breaks down badly if:

– the binding is implicit (without explicit extra syntax involved) and
– what is bound happens to be mutable.

An example being:

    // var message: String?
    if message != nil { // magic turns 'message' into a non-optional 'String' here
      handleMessage(message)
      message = nil // 'String' is not 'ExpressibleByNilLiteral'
    }

What magic would we require to still allow access to the Optional interface of 'message' in that block? In other words, I'm afraid type narrowing for Swift's enums (including Optional) isn't quite as simple as that.

— Pyry

*) OTOH, I could see much benefit from being able to narrow down enums of all kinds, e.g. `Result<T>` such that in the `else` branch of a failing `guard case let .success(value) = result`, the `error` value of `case failure(error)` were guaranteed by the compiler to be readily available, something like:

    enum Result<T> { case success(T); case failure(Error) }
    // ...
    // let result: Result<String>
    guard case let .success(string) = result
    else case let .failure(error) = result {
      // ^
      // Guaranteed to succeed because 'result' was proven to be of 'case failure(Error)'
      throw error
    }
    print(string)

> On 3 Nov 2016, at 6.37, Hooman Mehr via swift-evolution <swift-evolution at swift.org> wrote:
> 
> 
>> On Nov 2, 2016, at 2:02 PM, Matthew Johnson via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>> On Nov 2, 2016, at 3:47 PM, Sean Heber via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>> 
>>> For what it’s worth, I concur. I think type narrowing makes it feel more like the language is actually doing some work *for* me rather than me having to babysit the language with some new syntax or keyword.
>> 
>> I’ve been staying out of the discussion because it doesn’t seem particularly relevant to Swift 4 phase 1, but +1.  Type narrowing is by far the most general and scalable solution which could be applied in other ways in the future.
>> 
> 
> Same as me, I was staying out as well. 
> +1 for type narrowing instead of the original proposal. Thank you Haravikk for bringing this up.
> 
>>> 
>>> l8r
>>> Sean
>>> 
>>>> On Nov 2, 2016, at 3:25 PM, Haravikk via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>>> 
>>>> I still think that type narrowing is the right way to handle this like so:
>>>> 
>>>> 	if x != nil {
>>>> 		// x is definitely not nil inside this block (implicitly unwrapped)
>>>> 	} // x remains optional outside of it
>>>> 
>>>> 	if (x != nil) || (x == y) {
>>>> 		// if y's type is non-optional, then x is definitely not nil inside this block also
>>>> 		// i.e- if all conditions narrow to the same result, the type is narrowed inside the block
>>>> 	}
>>>> 
>>>> 	if x is Foo {
>>>> 		x.someMethodSpecificToFoo()
>>>> 	}
>>>> 
>>>> Personally I'm very much against the use of shadowing in the first place, and never use it myself. I tend to precede unwrapped value with "this" like so:
>>>> 
>>>> 	if let thisFoo = foo {
>>>> 		// Do something with thisFoo
>>>> 	}
>>>> 
>>>> I know it's maybe down to personal preference but I'd prefer to discourage shadowing entirely, and focus on type-narrowing, as it's a much more natural, and more generally useful, way to handle this "problem", as it doesn't actually require a specific syntax at all; if your condition narrows the type, then you can use the variable as whatever it is known to be.
> _______________________________________________
> 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/20161103/03336ab1/attachment.html>


More information about the swift-evolution mailing list