[swift-evolution] The state and the future of function types in Swift 4

Vladimir.S svabox at gmail.com
Fri Jun 16 16:20:39 CDT 2017


On 16.06.2017 19:29, Douglas Gregor wrote:
> 
>> On Jun 14, 2017, at 3:29 PM, Vladimir.S via swift-evolution <swift-evolution at 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
> 
> 


More information about the swift-evolution mailing list