[swift-evolution] [Review] SE-0110: Distinguish between single-tuple and multiple-argument function types

Vladimir.S svabox at gmail.com
Sun Jul 3 14:03:01 CDT 2016

On 03.07.2016 19:48, Haravikk wrote:
>> On 3 Jul 2016, at 13:02, Vladimir.S via swift-evolution <swift-evolution at swift.org> wrote:
>> On 02.07.2016 4:20, Daniel Duan via swift-evolution wrote:
>>>> Vladimir.S via swift-evolution <swift-evolution at ...> writes:
>>> Following your conclusion, should this be legal as well?
>>> let f: () -> Void = { x in print(x) } // f() prints "()"
>>> let f: (Int) -> Void = { x in print(x) } // f(5) prints "5"
>>> In other words, "0 argument" is an impossible scenario?
>> I don't see problems here. ()->Void means (Void)->Void, there *is* one parameter of Void type, which we can omitted as it is empty tuple. So, if you want you can write f(()) or or let z = (); f(z); or just f(), so in closure definition you can have one argument or can have 0 defined arguments if the only argument is of type Void.
>> It is not the same as be able to accept non-empty tuple when a list of parameters are expected or vice-versa.
>> I don't think we should move away(if it is possible at all) from representing zero-argument by empty tuple(Void). This looks like good and useful thing in Swift, especially in functional programming and when working with generics (we can pass parameter(of type void) even when call function with 0 defined arguments).
>> I actually wonder what should be a type of such function:
>> func f1() {}
>> print(f1.dynamicType)
>> Now it is `(()) -> ()`. Should it be `() -> ()`? Seems like no - it actually take 1 argument(empty tuple, Void) and returns empty tuple. So the `() -> ()` *declaration* just still be just an alias for real type `(()) -> ()`. IMO.
> I think the issue is that it's unexpected; I would expect () -> Void to
mean no arguments at all, rather than one argument that is Void, as I can't
really envision any cases where I'd need the latter. I think it's
reasonable that for those who can, that they use (()) -> Void to clarify
that this is the case, which I think fits well with Swift's general
philosophy of avoiding mistakes, even if this is probably a minor one, it
removes an area of confusion or inconsistency.

Well.. according to thread "[Pre-proposal] Fix function type grammar" - it 
is decided to *not* allow () as parameter to 0 argument function. You'll 
need to explicitly allow Void argument definition in function if you need 
this. So as I understand this question is closed.

As for use-cases, actually I was thinking about functional programming and 
generics: when you can pass result of previous func to next (in case of 
()->() it is Void as now) or use Void as generic type to be able to call 
()->() func. Otherwise you'll need wrappers f2(())->() {f1(); return ()} 
and so on. But probably this is not a problem and I'm just missing something.

But, then, regarding the consistency and confusion, I have a question: is 
it expected that func f() {..} will *return* `Void` ? I believe it is not 
expected exactly at the same level as Void in parameter for 0 argument 
function. I.e. should `-> ()` still means "returns Void" or "returns nothing" ?

More information about the swift-evolution mailing list