[swift-evolution] [Pre-proposal] Fix function type grammar

Vladimir.S svabox at gmail.com
Sun Jul 3 15:59:29 CDT 2016

On 03.07.2016 22:56, Anton Zhilin via swift-evolution wrote:
> Vladimir.S via swift-evolution <swift-evolution at ...> writes:
>> OK.. could you clarify, so, after the changes, we will not be able to
> pass
>> `func f()->()` as parameter where parameter of type `typealias
> MyFunc<T> =
>> (T) -> Void` is expected, right?
> Right. But the change is not as dramatic as you suppose.
> Consider this example:
> func async<T>(with: T, do: (T) -> Void)
> async(with: (), do: { ... })
> With this change, it will become:
> async(with: (), do: { _ in ... })
> This is what will change in practise. With enough luck, even the first
> version will typecheck.

If we are separating () and (()) in function call/declaration, then if 
SE-0110 will be accepted, I believe first should not be allowed for 
argument defined as (T)->Void.
As I understand, in case you have a code that relies on current 
syntax/behavior and uses functions(not closures), you'll need a lot of 
wrappers like `{_ in funcThatWasUsedAsIs()}`

>> And what about the result type? What does `-> ()` now will mean? still
>> "implicitly returns Void" or "returns nothing"? Or in case you want to
>> return Void you'll need to write `-> Void` ?
> Parameter part will become a list of types; result will still be a
> single type, including unit type and closure types. So no changes on
> this part.

Got it. OK, so when reading '()->()' we should now read 'emtpy list of 
parameters(0 parameters) to Void'. And only `(())->()` as '1 explicit Void 
argument to Void'.

Btw, in case of 'func f(())->() {}', will call without explicit Void 
parameter be allowed? I.e. `f()` or only `f(())`?

>> And most likely I'm missing something, but I don't see where SE-0066
>> mentions this aspect (disallow implicit Void argument in function
> which is
>> defined as '()->()'), as I understand it is only about requirement of
>> parentheses in declaration like Int->Int. Could you point me please?
> Citation:
> Allowing this sugar introduces ambiguities in the language that require
> special rules to disambiguate. For example:
> () -> Int // Takes zero arguments, or one zero-argument parameter?

Hm.. I do understand exactly this example as ambiguity *in case* we are not 
require parentheses. But not after.

I.e. in case we can have `Int->Int` it is not clear if in `()->()` there is 
a zero parameters or explicit `Void` parameter.
After we decided to require parentheses, `()->()` clearly means empty list 
of parameters.
*But*, I feel like implicit Void parameter for function with empty list of 
parameters - is an implementation detail which is currently used and 
changing this will produce much more problems for current code than "Just 
require parentheses on function types" as stated in the proposal in 
"Proposed solution and Impact on existing code".

I really feel like I've missed something or don't understand :-) and this 
is why only I is warring about this change(disallowing Void parameter for 
func with empty argument list in declaration)

> This syntactic sugar reduces consistency with other parts of the
> language, since declarations always require parentheses, and calls
> requires parentheses as well.
> Finally, while it is straight-forward to remove this in Swift 3 (given
> the other migration that will be necessary to move Swift 2 code to Swift
> 3), removing this after Swift 3 will be much harder since we won't want
> to break code then. It is now or never.
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

More information about the swift-evolution mailing list