Omitting unused closure parameters

Is there a reason why unused closure parameters need to be mentioned explicitly? For example:

    func doSomething(completionHandler: (Int, Int) -> Void) { … }
    …
    doSomething { // 'error: Contextual type for closure argument list expects 2 arguments, which cannot be implicitly ignored'
        print("Nobody cares about these parameters") 
    }

You have to do something like:

    doSomething { _,_ in // or actual parameter names, of course
        print("Nobody cares about these parameters") 
    }

I realize there might be a moral reason (about confirming that you know which closure you're writing or reading), but is there any technical reason for this?

4 Likes

I assume this is to disambiguate the function call in case there are different overloads.

Also, how would the solution you propose translate to a scenario where you are only interested in one of many parameters? Would you still need to underscore the ones you don't need there?

1 Like

Sure, but there are other situations like this (e.g. using the name of an overloaded function without specifying which parameters you mean) where this is only an error if it's actually ambiguous.

(I'm not proposing any solution right now, just asking about the "why".)

With multiple parameters, I guess the question gets a bit messier.

If you "acknowledge" the presence of parameters by using names or _ placeholders before in, you would have to acknowledge all of them — otherwise you really wouldn't be able to disambiguate between different closure signatures.

So the question really becomes: if you chose not name any of the closure parameters (use $n instead, or don't use some of them), and there is no ambiguity about the closure signature, is there a good reason to be forced to specify an in clause with a sequence of _ placeholders?

This problem referred as technical reason here in 2016.
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160118/007095.html

Ticket is here.

Fortunately, Douglas say that it will be easy to fix by very recent improvement.

2 Likes

Sounds great!

or here after the thread was imported into Discourse:

I run into this all the time while writing new code in SwiftUI (in part because there's so much trial-and-error involved). I often find myself writing something like:

    View {
        ...
    }
    .someThingToTry {
        print("it happened!")
    }

But then it yells at me because someThingToTry()’s closure takes parameters.

The bug about this hasn't had any love in nearly a year, although there seems to be universal agreement it should be fixed.

Is it true that the function builders work referenced above makes this easy to fix?

See also: Lift limitation that closures must use last shorthand argument. This is a well known issue.

Aside from the general limitation and code completion problem, it seems that APIs are being written to accommodate this by placing "main" or frequently used arguments at the end of method signatures which is both unintuitive and endangers API breakage when arguments are added.

1 Like