Hi Slava, Thanks for the insight. This is what I suspected, but I wasn't sure about how set the team was on this concept. Currently, it seems that if the types cannot be inferred, the type checker picks an implementation and checks against that.
E.g., the following code works because it conforms to the signature of the flatMap that the type checker decided to use: b = a.flatMap { elem in print(elem) return 1 } Given that adding multi-statement type inference is off the table, perhaps you could consider adding a helpful message when this situation arises? Like if type inference of a closure fails, and the closure doesn't type check with the assumed context, maybe tell the user "Did not infer types, try explicitly declaring them"? Just trying to think of a way to guide a less advanced user, since this error could arise from many functions and also from genuine errors, so it may be hard to google/ask for help with. -- Ross LeBeau On July 8, 2016 at 2:31:46 PM, Slava Pestov (spes...@apple.com) wrote: Hi Ross, Swift's type inference operates at the level of a single statement. This is why we can infer parameter and return types for single-expression closures. While conceptually, it would not be a huge change to the type checker algorithm to support global type inference for closures and other functions consisting of multiple statements, we feel that philosophically, this is not a direction the language should take. Global type inference will further exacerbate performance problems with type checking, as well as make it harder to produce good diagnostics. So really, this has less to do with closures per se, and more with just the general design and philosophy of the type checker. (Please correct me if I've mis-represented anything here -- this is my recollection of listening in on various discussions in the past). > On Jul 8, 2016, at 10:00 AM, Ross LeBeau via swift-dev < swift-dev@swift.org> wrote: > > It seems that the compiler fails to infer the type of an anonymous function if the function contains more than one statement. For example, this works: > > let a = [[1,2],[3],[4,5,6]] > var b: [Int] > b = a.flatMap { elem in > return elem > } > > But this fails with an error "cannot convert return expression of type '[Int]' to return type 'Int?'": > > b = a.flatMap { elem in > print(elem) > return elem > } > > And, of course, if you explicitly type the function, it works again: > > b = a.flatMap { (elem: [Int]) -> [Int] in > print(elem) > return elem > } > > Greg Titus informed me that this is due to a heuristic in the compiler where it only imports the outer context when type-checking anonymous functions with a single statement. Before we knew this, I and others, found it perplexing that out of two functions that return the same value, one will compile and the other will not. > > Are there any plans to extend the context of type-checking in the case of a failure like this? If not, is it something to consider? It seems like a difficult problem to solve without rather advanced knowledge of what's going on. > > Also if this has already been brought up, forgive me, I just subscribed to this list and a quick search of the archives didn't get any hits :) > > -- > Ross > _______________________________________________ > swift-dev mailing list > swift-dev@swift.org > https://lists.swift.org/mailman/listinfo/swift-dev
_______________________________________________ swift-dev mailing list swift-dev@swift.org https://lists.swift.org/mailman/listinfo/swift-dev