Bug report filed with warning emitting request: https://bugs.swift.org/browse/SR-4174 <https://bugs.swift.org/browse/SR-4174>
-- E > On Mar 1, 2017, at 1:58 PM, Pyry Jahkola <pyry.jahk...@iki.fi> wrote: > > I guess I should also include the example where the user actually wanted the > oldValue to be "x": > > if case let .two(newValue, value) = example, value == oldValue { ... } > > No surprises there, even if another conditional is required. > > — Pyry > >> On 1 Mar 2017, at 22.53, Pyry Jahkola via swift-evolution >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >> >> Erica, >> >> Instead of going into all these lengths introducing new syntax, why not >> simply turn it into a warning when a `case let` binding shadows an existing >> variable with the exact same type (which supposedly also conforms to >> Equatable)? >> >> Examples, including how to silence the said warning: >> >> enum Value<T> { case one(T), two(T, T), three(T, T, T) } >> >> let example: Value<String> = .two("a", "b") >> let oldValue = "x" >> // (Besides, you probably intended `oldValue` to be a `Character` in your >> // example. Well, it's a `String` in mine.) >> >> if case let .two(newValue, oldValue) = example { ... } >> // ~~~~~~~~ >> // warning: 'oldValue' shadows an existing variable of same type 'String' >> >> if case let .two(newValue, (oldValue)) = example { assert(oldValue == >> "b") } >> // Ok, adding extra parentheses silences the warning. >> >> if case let .one(example) = example { ... } >> // Ok, because there's no way the author would equate the `example: >> String` >> // in the LHS to the `example: Value<String>` of the RHS. >> >> let maybe: Optional = "perhaps" >> if case let maybe? = maybe { ... } >> if case let .some(maybe) = maybe { ... } >> // Again, none of these examples would be affected by the warning, >> because >> // the `maybe: String` bound in the `case let` has a different type than >> // the `maybe: String?` in the outer scope. >> >> Personally, I do like the convenience that I can bind several variables with >> one `let` keyword in a case expression. And I can't see the appeal to making >> `~=`, let alone a completely new special-syntax assignment operator, more >> prominent in Swift. >> >> — Pyry >> >>> On 28 Feb 2017, at 21.01, Erica Sadun via swift-evolution >>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >>> >>> The following draft proposal addresses one matter of substance (eliminating >>> edge case errors by adopting at-site conditional binding) and one of style >>> (using the pattern match operator consistently). Its discussion was >>> deferred from Phase 1 and remains in a fairly early stage. Your feedback >>> will help me decide whether this is a proposal I want to keep developing or >>> one that I should set aside and focus on other matters. Thank you. -- E >>> >>> The work-in-progress gist is here: >>> https://gist.github.com/erica/06dad9bbe1a70290fe6b89a64f73bc0c >>> <https://gist.github.com/erica/06dad9bbe1a70290fe6b89a64f73bc0c> >>> >>> Simplifying case syntax >>> >>> Proposal: TBD >>> Author: Erica Sadun <https://github.com/erica> >>> Status: TBD >>> Review manager: TBD >>> >>> <https://gist.github.com/erica/06dad9bbe1a70290fe6b89a64f73bc0c#introduction>Introduction >>> >>> This proposal re-architects case syntax grammar to reduce potential errors >>> and simplify unwrapping enumerations. >>> >>> Swift-evolution thread: [Pitch] Reimagining guard case/if case >>> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20161024/tbd.html> >>> >>> <https://gist.github.com/erica/06dad9bbe1a70290fe6b89a64f73bc0c#motivation>Motivation >>> >>> In its current design, Swift case binding suffers from two weaknesses. >>> >>> Mixed external and internal let/var binding may introduce errors from >>> uncommon edge cases. >>> Real-world users may not consider the parallel construction between if >>> case/guard case with switchstatements or naturally connect the two layouts. >>> >>> <https://gist.github.com/erica/06dad9bbe1a70290fe6b89a64f73bc0c#internal-case-binding>Internal >>> Case Binding >>> >>> When pattern matching, it's common to bind a variable or constant. It's >>> uncommon but legal to use a bound value as an argument. Adopting an "always >>> explicit, always within the parentheses" rule adds consistency and safety >>> to Swift. >>> >>> Consider the following enumeration and values: >>> >>> // An enum with one, two, or three associated values >>> enum Value<T> { case one(T), two(T, T), three(T, T, T) } >>> >>> // An example with two associated values >>> let example2: Value<Character> = .two("a", "b") >>> >>> // A bound symbol >>> let oldValue = "x" >>> This code's goal is to conditionally bind newValue and pattern match the >>> value stored in the oldValue symbol. The first example succeeds. The second >>> example compiles and runs but does not match the coder's intent. Using an >>> external letcreates a new oldValue shadow instead of pattern matching >>> oldValue's stored value. >>> >>> // Safe >>> if case .two(let newValue, oldValue) = example2 { >>> ... >>> } >>> >>> // Syntactically legal but incorrect >>> if case let .two(newValue, oldValue) = example2 { >>> ... >>> } >> (…) >> >> _______________________________________________ >> swift-evolution mailing list >> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >> https://lists.swift.org/mailman/listinfo/swift-evolution >> <https://lists.swift.org/mailman/listinfo/swift-evolution> > -- > Pyry Jahkola > pyry.jahk...@iki.fi <mailto:pyry.jahk...@iki.fi>
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution