Why this can't compile


(Wang LiMing) #1

import Cocoa

var numbers = [12, 14, 15, 21]

// This is OK
numbers.map({
    (number:Int) -> Int in
        let result = 3 * number
        return result
})

// This is OK
numbers.map({
    (number: Int) in
        return 3 * number

})

//Report Error: Ambiguous reference to member ‘map’
//
numbers.map({
    (number: Int) in
        var ret = 3 * number
        return ret
})


(Neil Faiman) #2

//Report Error: Ambiguous reference to member ‘map’
//
numbers.map({
    (number: Int) in
        var ret = 3 * number
        return ret
})

I asked the same question a few months ago; the answer was that it is a deliberate design choice that you can only omit the return type from a single-expression closure (and that the error message is less than helpful). For example, Jordan Rose offered this explanation:

Swift very deliberately does not infer types across multiple statements in closure bodies. This is mostly an implementation restriction (our type-checking system can't handle it very well), but it's also a simple rule that explains the implementation restriction, rather than having type inference in closure bodies working some of the time but not all.

As Chris pointed out, the compiler could definitely do a better job communicating the problem, but actually changing the behavior here would require significant implementation work. So this is not considered a "bug", just an implementation-driven design choice.

Regards,

  Neil Faiman

···

On Jun 29, 2016, at 11:03 PM, boris via swift-users <swift-users@swift.org> wrote:


(Wang LiMing) #3

Thanks for you help!

在 2016年6月30日,上午11:58,Neil Faiman <neil.swift@faiman.org<mailto:neil.swift@faiman.org>> 写道:

···

On Jun 29, 2016, at 11:03 PM, boris via swift-users <swift-users@swift.org<mailto:swift-users@swift.org>> wrote:

//Report Error: Ambiguous reference to member ‘map’
//
numbers.map({
    (number: Int) in
        var ret = 3 * number
        return ret
})

I asked the same question a few months ago; the answer was that it is a deliberate design choice that you can only omit the return type from a single-expression closure (and that the error message is less than helpful). For example, Jordan Rose offered this explanation:

Swift very deliberately does not infer types across multiple statements in closure bodies. This is mostly an implementation restriction (our type-checking system can't handle it very well), but it's also a simple rule that explains the implementation restriction, rather than having type inference in closure bodies working some of the time but not all.

As Chris pointed out, the compiler could definitely do a better job communicating the problem, but actually changing the behavior here would require significant implementation work. So this is not considered a "bug", just an implementation-driven design choice.

Regards,

Neil Faiman