[swift-evolution] Revisiting SE-0110

Vladimir.S svabox at gmail.com
Thu Jun 1 14:54:21 CDT 2017

On 01.06.2017 21:52, John McCall wrote:
>> On Jun 1, 2017, at 3:25 AM, Vladimir.S <svabox at gmail.com> wrote:
>> On 01.06.2017 0:42, John McCall wrote:
>>>> On May 31, 2017, at 2:02 PM, Stephen Celis <stephen.celis at gmail.com> wrote:
>>>>> On May 28, 2017, at 7:04 PM, John McCall via swift-evolution 
>>>>> <swift-evolution at swift.org> wrote: Yes, I agree.  We need to add back
>>>>> tuple destructuring in closure parameter lists because this is a serious
>>>>> usability regression.  If we're reluctant to just "do the right thing" to
>>>>> handle the ambiguity of (a,b), we should at least allow it via unambiguous
>>>>> syntax like ((a,b)).  I do think that we should just "do the right thing",
>>>>> however, with my biggest concern being whether there's any reasonable way
>>>>> to achieve that in 4.0.
>>>> Closure parameter lists are unfortunately only half of the equation here.
>>>> This change also regresses the usability of point-free expression.
>>> The consequences for point-free style were expected and cannot really be 
>>> eliminated without substantially weakening SE-0110.  Closure convenience seems
>>> to me to be a much more serious regression.
>> John, do you also want to say "and without weakening SE-0066"? Because, if I
>> understand correctly, in this case:
> No.  SE-0066 was ultimately just a syntax proposal.  SE-0110 clarified the

Hmm. Could you please comment this(below) part of SE-0066? :

Proposed solution

Parentheses will be required in *function types*. Examples:

Int -> Int           // error
(Int) -> Int         // function from Int to Int
((Int)) -> Int       // also function from Int to Int

Int, Int -> Int      // error
(Int, Int) -> Int    // function from Int and Int to Int
((Int, Int)) -> Int  // function from tuple (Int, Int) to Int

> intended type-system behavior of function types for both calls and conversions.
> Removing tuple destructuring from parameter clauses was an incidental consequence
> of that, which in my opinion was pursued out of enthusiasm and without adequately
> understanding the impact on closures.

Well, I still believe SE-0110 was inspired by SE-0066 in a way how function types 
were described in the latter.

Do you want to say, that if SE-0110 was not accepted(but SE-0066 is accepted), 
function that takes one tuple parameter for example func foo(_ x: (Int, Int)){} will 
still be of *type* (Int,Int)->Void and not ((Int,Int))->Void ?

And I'd still ask, if you have some time, please answer the question regarding the 
closure type and allowed code(in the same email you replied just below) in case we 
revisit SE-0110 *or* SE-0110 was not ever be proposed&accepted.
(I'm afraid I'm missing something very important about SE-0066 and function type 
differences we should have in Swift 4). Thank you.


> I understand that there are developers who dislike SE-0110's impact on certain
> kinds of functional programming, but that is a very broad complaint that is
> unlikely to reach consensus or acceptance, especially for Swift 4.  In contrast, I
> think we may be able to gain consensus on a more targeted proposal that just
> re-admits tuple destructuring in closures, assuming we can find an acceptable
> implementation.
> John.
>> func add(_ x: Int, _ y: Int) -> Int { return x + y }
>> zip([1, 2, 3], [4, 5, 6]).map(add)
>> .. we have a clear function type mismatch situation, when map() expects function
>> of type ((Int, Int))->Int, but function of type (Int,Int)->Int is provided ? So
>> probably the additional 'reason' of the 'problem' in this case is SE-0066, no? 
>> Or I don't understand the SE-0066 correctly.. Do we want to allow implicit
>> conversions between function type ((Int,Int))->Int and (Int,Int)->Int?
>> Quote from SE-0066: --- (Int, Int) -> Int    // function from Int and Int to
>> Int ((Int, Int)) -> Int  // function from tuple (Int, Int) to Int ---
>> During this discussion I see a wish of some group of developers to just return
>> back tuple splatting for function/closure arguments, so they can freely send
>> tuple to function/closure accepting a list of parameters(and probably
>> vise-versa). Is it worth to follow SE-0066 and SE-0110 as is, i.e. disallow
>> tuple deconstructing and then, as additive change improve the situation with
>> tuple splatting/deconstructing later with separate big proposal?
>> Btw, about the SE-0110 proposal. It was discussed, formally reviewed and
>> accepted. I expect that its revision also should be formally
>> proposed/reviewed/accepted to collect a wide range of opinions and thoughts, and
>> attract the attention of developers in this list to the subject.
>> Also, if we revisit SE-0110, will this code be allowed?:
>> func foo(_ callback: ((Int,Int))->Void) {} let mycallback = {(x:Int,
>> y:Int)->Void in } foo(mycallback)
>> and
>> func foo(_ callback: (Int,Int)->Void) {} let mycallback = {(x: (Int, Int))->Void
>> in } foo(mycallback)
>> If so, what will be result of this for both cases? :
>> print(type(of:mycallback)) // (Int,Int)->Void or ((Int,Int))->Void
>> If allowed, do we want to allow implicit conversion between types
>> (Int,Int)->Void and ((Int,Int))->Void in both directions?  (Hello tuple
>> splatting?)
>>> John.
>>>> func add(_ x: Int, _ y: Int) -> Int { return x + y } zip([1, 2, 3], [4, 5,
>>>> 6]).map(add) // error: nested tuple parameter '(Int, Int)' of function
>>>> '(((_.Element, _.Element)) throws -> _) throws -> [_]' does not support
>>>> destructuring This may not be a common pattern in most projects, but we
>>>> heavily use this style in the Kickstarter app in our functional and FRP
>>>> code. Definitely not the most common coding pattern, but a very expressive
>>>> one that we rely on. Our interim solution is a bunch of overloaded helpers,
>>>> e.g.: func tupleUp<A, B, C>(_ f: (A, B) -> C) -> ((A, B)) -> C { return } 
>>>> zip([1, 2, 3], [4, 5, 6]).map(tupleUp(add)) Stephen
>>> .

More information about the swift-evolution mailing list