[Pitch] Opaque parameter types

No, this is not legal. The operand to any must also be a protocol or protocol composition. From SE-0335:

Explicit any can only be applied to protocols and protocol compositions, or metatypes thereof; any cannot be applied to nominal types, structural types, type parameters, and protocol metatypes

Wow. Actually, I didn't expect that. How does that behave inside function? I feel it is a quite strange exception that (some P) -> () is only allowed in argument position of function.

func foo(value: some Any) {
    let a = value             // possible
    let b: some Any = value   // possible
    let c: any Any = value    // possible
}

func foo(closure: (some Any) -> ()) {
    let a = closure                     // possible
    let b: (some Any) -> () = closure   // impossible due to the restriction?
    let c: (any Any) -> () = closure    // possible
}

A reason that some is interesting in return type positions is that the type is decided by the callee instead of the caller. Using View for lack of another concrete example, wouldn't it be nice if this worked?

func passView(action: (some View) -> Void) {
    let view = VStack { HStack { ... } ... }
    action(view)
}

This is not something that you can do today with the regular generic syntax. This would require the closure to be generic and accept any kind of View. I understand that generic closures don't exist and may well never exist, but to me it would be more self-consistent to just not allow some in closure parameters.

We could add first-class generic function values in the future. Opaque parameter types would be no better or worse than their equivalent generic functions with respect to forward compatibility, and I'm fairly certain we could handle it: we'd bind the generic arguments when we can infer them, and leave the result generic when we cannot.

b is ill-formed. The only thing it could really mean would be

let b2: (_) -> () = closure 

I don't know that we need to allow the redundant spelling here.

Note that c is ill-formed, because the closure can't take any Any, it can only take the specific type of the closure (i.e., the synthesized generic parameter).

Doug

1 Like

OK, I'm sorry in that c is ill-formed. But that's not my point. I'm asking that, why a type which cannot appear in let statements can appear in function parameter position. Other types containing some do appear in both parameter position and let statements. The behavior of (some P) -> () is quite strange.

It contains another problem, please read my comment in the proposal review thread :bowing_man: Maybe we should argue in the review thread, in order not to scatter the discussion.