> On Jun 16, 2017, at 2:09 PM, Paul Cantrell <cantr...@pobox.com> wrote:
> 
>> 
>> On Jun 16, 2017, at 3:43 PM, Mark Lacey <mark.la...@apple.com 
>> <mailto:mark.la...@apple.com>> wrote:
>> 
>> 
>>> On Jun 16, 2017, at 1:21 PM, Mark Lacey <mark.la...@apple.com 
>>> <mailto:mark.la...@apple.com>> wrote:
>>> 
>>>> 
>>>> On Jun 16, 2017, at 11:13 AM, Paul Cantrell via swift-evolution 
>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>>> 
>>>>> On Jun 15, 2017, at 7:17 PM, Xiaodi Wu via swift-evolution 
>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>> 
>>>>> 
>>>>> On Thu, Jun 15, 2017 at 19:03 Víctor Pimentel <vpimen...@tuenti.com 
>>>>> <mailto:vpimen...@tuenti.com>> wrote:
>>>>> On 16 Jun 2017, at 01:55, Xiaodi Wu via swift-evolution 
>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>> 
>>>>>> On Thu, Jun 15, 2017 at 17:43 David Hart <da...@hartbit.com 
>>>>>> <mailto:da...@hartbit.com>> wrote:
>>>>>> 
>>>>>> By the way, I’m not attempting to deduce that nobody uses this feature 
>>>>>> by the fact I didn’t know about it. But I think it’s one interesting 
>>>>>> datapoint when comparing it to SE-0110.
>>>>>> 
>>>>>> 
>>>>>> SE-0110, **in retrospect**, has had impacts on a lot of users; 
>>>>>> prospectively, it was thought to be a minor change, even after review 
>>>>>> and acceptance.
>>>>>> 
>>>>>> Keep in mind that this proposed change would also eliminate inline tuple 
>>>>>> shuffle. For instance, the following code will cease to compile:
>>>>>> 
>>>>>> let x = (a: 1.0, r: 0.5, g: 0.5, b: 0.5)
>>>>>> func f(color: (r: Double, g: Double, b: Double, a: Double)) {
>>>>>>   print(color)
>>>>>> }
>>>>>> f(color: x)
>>>>>> 
>>>>>> It is an open question how frequently this is used. But like implicit 
>>>>>> tuple destructuring, it currently Just Works(TM) and users may not 
>>>>>> realize they’re making use of the feature until it’s gone.
>>>>> 
>>>>> It's much much less used, by looking at open source projects I doubt that 
>>>>> a significant portion of projects would have to change code because of 
>>>>> this.
>>>>> 
>>>>> The reason that I’m urging caution is because, if I recall correctly, 
>>>>> that is also what we said about SE-0110 on this list. Then, as now, we 
>>>>> were discussing an issue with something left over from the Swift 1 model 
>>>>> of tuples. Then, as now, we believed that the feature in question was 
>>>>> rarely used. Then, as now, we believed that removing that feature would 
>>>>> improve consistency in the language, better both for the compiler and for 
>>>>> users. Then, as now, leaving it in was thought to prevent moving forward 
>>>>> with other features that could improve Swift.
>>>> 
>>>> Data:
>>>> 
>>>> I hacked up a regexp that will catch most uses of labeled tuples in 
>>>> pattern matches, e.g. “let (foo: bar) = baz”. That’s what we’re talking 
>>>> about, right?
>>> 
>>> That’s the obvious example that people find confusing.
>>> 
>>> Less obvious places that labeled tuple patterns show up are ‘case let’ and 
>>> ‘case’ (see below). 
>> 
>> Okay, I should have looked at your regex and read further. It looks like you 
>> were already trying to match these.
> 
> I did walk the grammar for all occurrences of _pattern_.
> 
> I’m only matching named tuple patterns that immediately follow one of the 
> keywords which a pattern follows (for, case, let, var, and catch). As I 
> mentioned, I’m not matching patterns that come later in comma-separated 
> lists. I’m also not matching named tuples inside nested patterns, e.g. let 
> ((a: b), (c: d)).
> 
> But again, if even the most basic form of this construct is so rare, I doubt 
> more robust matching would turn up that much more usage.
> 
>> I’m surprised you’re not seeing any uses of ‘case’ with labels.
> 
> Me too. But I just verified that my pattern does match them.

Are you sure? It doesn’t look like it’s going to match the example I gave due 
to the leading ‘.’ on the enum case.

You might want to try the patch I sent as it will definitely catch any tuple 
pattern that makes it to the verifier and does have labels.

Mark

> 
> P
> 
>> 
>> Mark
>> 
>>> Fortunately we do not appear to allow shuffling in these cases. I’m not 
>>> sure if the human disambiguation is easier here because of the context 
>>> (‘case let’ and ‘case’), but I don’t recall seeing complain about these 
>>> being confusing (having said that it’s entirely possible they are very 
>>> confusing the first time someone sees them, in particular ‘cast let’ and 
>>> the binding form of ‘case’.
>>> 
>>> enum X {
>>>   case e(i: Int, f: Float)
>>> }
>>> 
>>> let x = X.e(i: 7, f: 12)
>>> 
>>> if case let X.e(i: hi, f: bye) = x {
>>>   print("(i: \(hi), f: \(bye))")
>>> }
>>> 
>>> func test(_ x: X, _ a: Int, _ b: Float) {
>>>   switch x {
>>>   case .e(i: a, f: b):
>>>     print("match values")
>>>   case .e(i: let _, f: let _):
>>>     print("bind values")
>>>   default:
>>>     break
>>>   }
>>> }
>>> 
>>> test(X.e(i: 1, f: 2), 1, 2)
>>> test(X.e(i: 1, f: 2), 3, 4)
>>> 
>>> 
>>>> 
>>>> I ran that against all 55 projects in swift-source-compat-suite, 
>>>> comprising about over 400,000 lines of Swift code, and found … drumroll … 
>>>> exactly one match:
>>>> 
>>>> 
>>>> neota (swift-source-compat-suite)$ find project_cache -name '*.swift' 
>>>> -print0 | xargs -0 pcregrep -M 
>>>> '(for|case|let|var|catch)\s+\([a-zA-Z0-9_]+\s*:'
>>>> project_cache/RxSwift/RxExample/RxExample-iOSTests/TestScheduler+MarbleTests.swift:
>>>>                 let (time: _, events: events) = segments.reduce((time: 0, 
>>>> events: [RecordedEvent]())) { state, event in
>>>> 
>>>> 
>>>> Caveats about this method:
>>>> 
>>>> • My regexp won’t match second and third patterns in a comma-separated let 
>>>> or case, e.g.:
>>>> 
>>>>    let a = b, (c: d) = e
>>>> 
>>>> • It doesn’t match non-ascii identifiers.
>>>> 
>>>> • This experiment only considers labeled tuples in pattern matches, what I 
>>>> took Chris’s original puzzler to be about. Label-based tuple shuffling is 
>>>> a separate question.
>>>> 
>>>> Still, even if it’s undercounting slightly, one breakage in half a million 
>>>> lines of code should put to rest concerns about unexpected widespread 
>>>> impact.
>>>> 
>>>> (Anything else I’m missing?)
>>>> 
>>>> • • •
>>>> 
>>>> Aside for those who know the tools out there: what would it take to run 
>>>> inspections like this against ASTs instead of using a regex? Could we 
>>>> instrument the compiler as Brent suggested?
>>> 
>>> If you want to catch *all* of these cases then the patch below will do it 
>>> by failing the AST verifier when it hits a pattern with labels. If you only 
>>> want to find the plain let-binding versions of this and not the ‘case let’ 
>>> and ‘case’ ones, I’d suggest looking at the parser to see if there’s an 
>>> easy place to instrument (I don’t know offhand).
>>> 
>>> Mark
>>> 
>>> diff --git a/lib/AST/ASTVerifier.cpp b/lib/AST/ASTVerifier.cpp
>>> index b59a7ade23..ba4b2a245d 100644
>>> --- a/lib/AST/ASTVerifier.cpp
>>> +++ b/lib/AST/ASTVerifier.cpp
>>> @@ -2772,6 +2772,13 @@ public:
>>>      }
>>>  
>>>      void verifyParsed(TuplePattern *TP) {
>>> +      for (auto &elt : TP->getElements()) {
>>> +        if (!elt.getLabel().empty()) {
>>> +          Out << "Labeled tuple patterns are offensive!\n";
>>> +          abort();
>>> +        }
>>> +      }
>>> +
>>>        PrettyStackTracePattern debugStack(Ctx, "verifying TuplePattern", 
>>> TP);
>>>        verifyParsedBase(TP);
>>>      }
>>> 
>>> 
>>> 
>>> 
>>>> Or can SourceKit / SourceKitten give a full AST? Or has anybody written a 
>>>> Swift parser in Swift?
>>>> 
>>>> Cheers,
>>>> 
>>>> Paul
>>>> 
>>>> _______________________________________________
>>>> 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>
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to