On 16.06.2017 19:29, Douglas Gregor wrote:

On Jun 14, 2017, at 3:29 PM, Vladimir.S via swift-evolution 
<swift-evolution@swift.org> wrote:

I do understand that core team is very busy, but I hope they'll find a minute to reply in 
couple of words to this message. Even "we are still thinking about this" would 
be great. Of course any other's opinion is also very welcome.

It’s going to take a whole lot more than a minute to reply, but I’ll try!

Douglas, thank you for the valuable and detailed reply. Actually, I was hoping for exactly such reply from core team for my question :-)

It's sad that we'll not have correct implementation/representation for these function types in Swift 4 release, I believe Swift 4 is the right moment to "done it right" with some source breaking, but I understand and now it is clear what is the state and future plans for these function types.

Vladimir.



I think we all need some clarification about function types in Swift 4, 
especially in light of recent hot discussion of reverting of SE-0110, which 
raised a couple of questions that IMO should be answered before Swift 4 is 
released or is in final stage, and I can't see any clear answer from core team 
regarding the subject.
(If I missed something - sorry, please point me)

The main question I have : Will *type* of function taking a list of arguments 
be the same as type of function taking one tuple argument?

The intent is “no”. Swift only ever had a poor approximation of this model, and 
has been moving away from it because lots of things we want for function 
parameters—inout parameters, ownership-related calling convention, 
autoclosures, non escaping function parameters, separate argument 
label/parameter names, different argument-label-matching rules, default 
arguments, variadic parameters—don’t really make sense for tuples. You can 
sorta squint at some of those and find a way to make them work generally with 
tuples, but it’s never all going to fit. They’re different notions, and they 
don’t belong together.

Then, what code can prove/show that these *types* are different and not the 
same ?

Here’s a simple case based on your example below:

        func f(_: Int, _: Int) { } // #1
        func f(_: (Int, Int)) { } // #2

        f(1, 2)    // calls #1
        f((1, 2)) // calls #2

Amusingly, this changed behavior from Swift 3.1 to Swift 3.2 (!). Swift 3.1 
would call #1 for both cases! IIRC, earlier versions of Swift would reject the 
overloading of “f” and crash.

There are numerous other ways to show this, but calling an overloaded function 
is an easy one.

Answers to these question can show what situation we'll have with function 
types in Swift 4 and for very long period after Swift 4.
Seems like strange question as we know obvious answer, but as I understand, the 
answer is not so obvious.

As I understand, if we'll still have
'type(of: funcOfOneTuple) == type(of: funcOfArgList)' == true

The underlying implementation model of the compiler still makes this true, yes.

(as we have even in current snapshot of Swift 4) - we are going to have broken 
type system for function types for very long time(when we'll be allowed for 
source breaking changes after Swift 4?)

I was told that Swift can have some bugs in this area currently and after Swift 
4 release, but don't worry, they'll be just fixed in some point of time after 
Swift 4.

The Swift compiler *will* have bugs in this area. Yes, they will need to be 
fixed.

But I insist, we are not talking about _bugs_, but about allowed syntax and code 
behavior, that can't be 'just' fixed without breaking some sources(and again probably in 
places where was not expected). Also, it's weird that these long-running "bugs" 
will still exists in Swift 4(and so, for long period after it) while SE-0066 and SE-0110 
was accepted to be implemented in *Swift 3*.

Yes, fixing these bugs can affect source compatibility. Compatibility modes (like 
Swift 3.2 in the Swift 4.0 compiler) and migration tools (as with 3.2 -> 4.0) 
make it possible to make improvements over time. Swift 3.2 emulates Swift 3 quite 
well, given that the compiler saw some major representational changes internally.


I'll try to illustrate what I mean and why asking exactly that question.

Given:
        func fooParam(_ x: Int, _ y: Int){}
        func fooTuple(_ x: (Int, Int)) {}

        func fooEmpty() {}
        func fooVoid(_: Void) {}

currently, in Swift 4 snapshot we have this:

* type(of: fooTuple)                            // (Int,Int)->()
* type(of:fooParam) == type(of:fooTuple)        // true
* fooParam is ((Int,Int))->()                        // true
* fooTuple is (Int,Int)->()                  // true

* let foo : (Int,Int)->() = fooTuple
  foo(1,2)                                      // fooTuple called with 2 
arguments

* let bar : ((Int,Int))->() = fooParam
  bar((1,2))                                    // fooParam called with 1 tuple 
arg

* type(of: fooEmpty) == type(of: fooVoid)       // true
* fooVoid is ()->()                          // true
* fooEmpty is (_: Void)->()                  // true

* let foo : ()->() = fooVoid
  foo()                                         // fooVoid called with no () arg

* let bar : (_: Void)->() = fooEmpty
  bar(())                                       // fooEmpty called with () arg 
sent

While in some cases you can't use fooParam where fooTuple is expected, but seems like 
underlying type of each is the same, so in other cases you can and this _will_ be used in 
code and can't be "fixed" without breaking some sources.

As noted above, the types are the same deep in the compiler. That will change, 
and the code you write above will behind differently (correctly) in Swift N+1, 
with some source compatibility work to maintain source compatibility and 
migrate forward.

Also, this raises a question : if the type is the same, why we can't freely use 
closure of type fooParam if fooTuple is expected. And how SE-0066 and SE-0110 
in this case could be considered as fully implemented in Swift 4.


SE-0066 and SE-0110 aren’t fully implemented; we’ll be pulling them back to a 
“partially implemented” state to try to better reflect that.

        - Doug


_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to