Why Can't I Use .Reduce() in a One-Liner Swift Closure with a Variadic, Anonymous Argument

How to use a variadic closure in swift?

Compiler limitation/bug with argument type inference for single-expression closures

I believe the source of this is a current limitation (/bug) in the compiler w.r.t. inferring the argument types in single-line closures using variadic parameters, see e.g. the following Q&A

  1. Why can't I use .reduce() in a one-liner Swift closure with a variadic, anonymous argument?

A similar issue was also present for inout arguments in Swift 2.1 (but no longer in 2.2), as is explained in the following thread


  1. Inline if statement mutating inout parameter in a void return closure, weird error (Error: type 'Int1' does not conform to protocol 'BooleanType')

Looking at thread 1. as well as attempting to find the described bug flagged in Swift JIRA, however, it seems as if the OP of thread 1. never filed a bug for this, after all. Possibly I just haven't found an existing bug report, but if none exists, one should possibly be filed.


Current workarounds

Possible workarounds, until the compiler's closure argument type inference catches up, are

  • Extend the closure beyond single-line body

    // ...

    [1, 2].satisfy { (args) in
    () // dummy
    print (args) // [1, 2, 3]
    }
  • Or, explicitly include type of args, e.g.

    [1, 2].satisfy { (args: Int...) in
    print (args) // [1, 2, 3]
    }

    Note that Generator.Element resolves to Int in this example above.


Current status for Swift 3.0-dev

As mentioned briefly above, curiously enough, this bug

  • inout: is apparently no longer present in Swift 2.2 or Swift 3.0-dev for inout arguments, w.r.t. the issues described in Q&A 2. as linked to above

    • it was possibly fixed as bug [SR-7] was resolved (-> Swift 2.2)
    • however, seems to be regression 2.2->3.0-dev, w.r.t. type inference for inout arguments, as reported in bug report [SR-892]. E.g. the following snippet works in Swift 2.2, but not in 3.0-dev (minimally modified snipper from bug report [SR-7])

      func f(inout a: Int) {}
      let g = { x in f(&x) } // OK 2.2, crashes 3.0-dev
  • variadic: is still present in Swift 2.2 as well as Swift 3.0-dev for variadic arguments (this thread and Q&A 1. above).

    • a more condensed example of the bug:

      let a: (Int...) -> () = { (args) in print(args) }         // bug: crashes
      let b: (Int...) -> () = { (args: Int...) in print(args) } // explicitly state argument type, OK
      let c: (Int...) -> () = { (args) in (); print(args) } // extend to more than single line closure, OK

(For Swift 3.0-dev, tested using the IBM Swift Sandbox running Swift 3.0-dev.

Why does Swift 1.2 reduce force me to use the combine: argument name?

I filed a bug report on this, and Apple replied that the change was intentional. In my view, being able to say reduce(0,+) was elegant and pithy, so the API for reduce should declare the external parameter name unnecessary. In Apple's stated view, the combine: external parameter name clarifies the purpose of the parameter. We have agreed to disagree.

Inline if statement mutating inout parameter in a void return closure, weird error (Error: type 'Int1' does not conform to protocol 'BooleanType')

(Adding this thin answer to close the no-longer-relevant question)

The bug described in the question above is no longer present in Swift 2.2 (Xcode 7.3) nor in the Swift 3.0-dev at IBM Sandbox; so the issue seems to have been fixed in with the release of Swift 2.2.

Optional Parameters in Go?

Go does not have optional parameters nor does it support method overloading:

Method dispatch is simplified if it
doesn't need to do type matching as
well. Experience with other languages
told us that having a variety of
methods with the same name but
different signatures was occasionally
useful but that it could also be
confusing and fragile in practice.
Matching only by name and requiring
consistency in the types was a major
simplifying decision in Go's type
system.



Related Topics



Leave a reply



Submit