[swift-evolution] Revisiting SE-0110

rintaro ishizaki fs.output at gmail.com
Fri Jun 16 02:41:03 CDT 2017


My guess is that core team is planning to accept *patterns* in closure
parameter clause. e.g.:

  let dict = ["foo": 1, "bar": 2]
  let result = dict.map { ((k, v) : (key: String, value: Int)) in ... }
                           ^^^^^^ pattern

When the compiler see this expression:

  dict.map { k, v -> R in ... }

1) Always complement () for bare parameters:

  dict.map { (k, v) -> R in ... }

2) If
  a) the context type of the closure has only one parameter with tuple
type; and
  b) closure has the same number of parameters as that tuple type; and
  c) each parameter doesn't have type annotation
treat it as a tuple patten for binding:

  dict.map { ((k, v)) -> R in ... }
              ^^^^^^ pattern

3) of that tuple type:

  dict.map { ((k, v): (key: String, value: Int)) -> R in ... }

The important thing here is step 2-c. If the parameters have type
annotations:

  dict.map { (key: String, value: Int) -> R in ... }

We can't use this as a tuple pattern because of the problem we are
discussing right now. In this case, the migrator should rewrite this to:

  dict.map { ((key, value) : (key: String, value: Int)) -> R in ... }

Also, because of that, compiler should reject this confusing tuple pattern.

  dict.map { ((key: String, value: Int)) -> R in ... }
              ^^^^^^^^^^^^^^^^^^^^^^^^^




2017-06-16 14:17 GMT+09:00 David Hart via swift-evolution <
swift-evolution at swift.org>:

>
>
> On 16 Jun 2017, at 01:55, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>
> On Thu, Jun 15, 2017 at 17:43 David Hart <david at hartbit.com> wrote:
>
>> On 16 Jun 2017, at 00:41, David Hart <david at hartbit.com> wrote:
>>
>>
>> On 15 Jun 2017, at 19:28, Chris Lattner <sabre at nondot.org> wrote:
>>
>>
>> On Jun 15, 2017, at 9:41 AM, Xiaodi Wu via swift-evolution <
>> swift-evolution at swift.org> o
>>
>> >
>>>> >   let (a : Int, b : Float) = foo()
>>>>
>>>>
>>>> I think it would be better if the compiler raised a warning whenever
>>>> you tried to redefine a builtin type.
>>>
>>>
>>> That’s essentially my preferred solution as well, as it gets to the root
>>> of the confusion.
>>>
>>> Naming a variable the same as a type should be similar to naming a
>>> variable the same as a reserved keyword and require backticks. (A previous
>>> suggestion to enforce capitalization falls down with full Unicode support
>>> and complicates interop where imported C structures might be lowercase and
>>> constants might be all caps.) No need to treat built-in types specially;
>>> it’s equally a problem with types imported from other libraries, which can
>>> be shadowed freely today. For full source compatibility this can be a
>>> warning instead of an error–should be sufficient as long as it’s brought to
>>> the user’s attention. In fact, probably most appropriate as a warning,
>>> since the _compiler_ knows exactly what’s going on, it’s the human that
>>> might be confused.
>>>
>>>
>>> I kind of agree with all you say. But I also feel that tuple element
>>> names in patterns are very rarely used and not worth the added complexity
>>> and confusing. Going back to the old: “Would be add it to Swift if it did
>>> not exist?”, I would say no.
>>>
>>
>> That was the standard for removing features before Swift 3, but with
>> source compatibility the bar is now much higher.
>>
>>
>> Completely agreed.  My belief on this is that it is a legacy Swift 1 type
>> system capability that no one uses.  I have no data to show that though.
>>
>> Is the feature harmful?
>>
>>
>> Yes, absolutely.  The shadowing isn't the thing that bothers me, it is
>> that swift has a meaning for that very syntax in other contexts, and that
>> this is completely different meaning.  People absolutely would get confused
>> by this if they encountered it in real code that they themselves didn't
>> write, and I'm not aware of any good (non theoretical) use for it.
>>
>> My point is, not on its own it isn’t: warning on variables shadowing
>> types is sufficient to resolve the problems shown here.
>>
>>
>> Again, my concern is that this is a confusing and misleading feature
>> which complicates and potentially prevents composing other features in the
>> future.
>>
>>
>>
>> How strange that we’re talking about this issue in a thread about
>> SE-0110.
>>
>>
>> This came up in the discussion about 110 because we were exploring
>> whether it was plausible to expand the function parameter grammar to
>> support destructuring in the position where a name goes.  There are many
>> concerns about whether this is a good idea, but he existence of this in the
>> tuple destructuring pattern grammar is pretty much a showstopper.
>>
>> If anything, the response to that proposal should be a cautionary tale
>> that users can take poorly to removing features, sometimes in unanticipated
>> ways.
>>
>>
>> Agreed, it may be too late to correct this (certainly we can't outright
>> remove it in Swift 4 if someone is using it for something important).
>> However if it turns out that it really isn't used, then warning about it in
>> 4 and removing it shortly after may be possible.
>>
>>
>> And I think its difficult to make the parallel between the two. SE-0110
>> basically impacted everybody calling higher-order functions on Dictionary
>> (+ more users from libraries like RxSwift), which makes an enormous
>> proportion of the Swift community. On the other hand, despite the enormous
>> amount of time I have sinked into learning, discussing and enjoying Swift,
>> I never come upon the tuple element name syntax in patterns until Robert
>> pointed to it out on twitter several weeks ago.
>>
>>
>> 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.
>
>
> Xiaodi, can you explain to me what makes you think that your example piece
> of code would be concerned by Chris' suggestion to remove tuple element
> names from the pattern grammar? That's not what I understood.
>
>
>> -Chris
>>
>>
>> `let (a : Int, b : Float) = foo()` is confusing but if you were to use
>>>> your own type (e.g., `struct S {}` and replace Int and Float with S) you
>>>> would get a compiler error. If the compiler warned you that you were
>>>> reassigning Int and Float, you’d probably avoid that problem. Or, for a
>>>> more extreme fix, we could make reassigning builtin types illegal since
>>>> there is pretty much no valid reason to do that.
>>>>
>>>>
>>>> > On Jun 15, 2017, at 8:10 AM, Matthew Johnson via swift-evolution <
>>>> swift-evolution at swift.org> wrote:
>>>> >
>>>> >
>>>> >
>>>> > Sent from my iPad
>>>> >
>>>> >> On Jun 14, 2017, at 11:01 PM, Chris Lattner via swift-evolution <
>>>> swift-evolution at swift.org> wrote:
>>>> >>
>>>> >>
>>>> >>> On Jun 12, 2017, at 10:07 PM, Paul Cantrell <cantrell at pobox.com>
>>>> wrote:
>>>> >>>
>>>> >>> What’s the status of this Chris’s double parens idea below? It
>>>> garnered some positive responses, but the discussion seems to have fizzled
>>>> out. Is there something needed to help nudge this along?
>>>> >>>
>>>> >>> What’s the likelihood of getting this fixed before Swift 4 goes
>>>> live, and the great wave of readability regressions hits?
>>>> >>
>>>> >> We discussed this in the core team meeting today.  Consensus seems
>>>> to be that a change needs to be made to regain syntactic convenience here.
>>>> Discussion was leaning towards allowing (at least) the parenthesized form,
>>>> but more discussion is needed.
>>>> >>
>>>> >>
>>>> >> One (tangential) thing that came up is that tuple element names in
>>>> tuple *patterns* should probably be deprecated and removed at some point.
>>>> Without looking, what variables does this declare?:
>>>> >>
>>>> >>   let (a : Int, b : Float) = foo()
>>>> >
>>>> > Another option would be to require let to appear next to each name
>>>> binding instead of allowing a single let for the whole pattern.  I
>>>> personally find that much more clear despite it being a little bit more
>>>> verbose.
>>>> >
>>>> >>
>>>> >> ?
>>>> >>
>>>> >> -Chris
>>>> >>
>>>> >> _______________________________________________
>>>> >> swift-evolution mailing list
>>>> >> swift-evolution at swift.org
>>>> >> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>> >
>>>> > _______________________________________________
>>>> > swift-evolution mailing list
>>>> > swift-evolution at swift.org
>>>> > https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> swift-evolution at swift.org
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>
>>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>>
> _______________________________________________
> 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/20170616/7aedfb09/attachment.html>


More information about the swift-evolution mailing list