Equality of functions

Another thing that I cannot get my head around, is the relation between argument and result types and the protocol. They don't look like associated types, because they are specified from the outside. To me they look more like generic parameters. But Swift currently does not have generic protocols, and, as far as I understood, is not planning to have.

Improving the UI of generics - #125 by anandabits mentions the following syntax, which may somewhat resolve this:

typealias CollectionOf<T> = Collection where Self.Element == T

Should we say that (Int) -> Void is a syntax sugar for Callable where Self.Args == (Int), Self.Result == Void? Or (Int) -> Void is a non-nominal protocol and notions of both generic args and associated types do not apply.

As an example, let's say we want to write a generic middleware that prints all the args and result of a function call.

With generic arguments, it would look something like this (variadic keyword is from swift-evolution/XXXX-variadic-generics.md at variadic-generics · technicated/swift-evolution · GitHub):

struct FunctionLogger<variadic Args, Result, F: (Arg) -> Result = any (Args) -> Result>: (Args) -> Result {
    var base: F

    func callAsFunction(_ args: Args) -> Result {
        print(args)...
        let result = base(args)
        print(result)
        return result
    }
}

And with associated types:

struct FunctionLogger<F: Callable>: Callbable {
    typealias Args = F.Args
    variadic typealias Result = F.Result

    var base: F

    func callAsFunction(_ args: Args) -> Result {
        print(args)...
        let result = base(args)
        print(result)
        return result
    }
}

Can the same struct conform to multiple function protocols? With generic arguments - yes, because (Int) -> Void and (Float) -> Void are different protocols. With associated types, there is only one protocol Callable and there can be only one conformance.