<html><head><style>body{font-family:Helvetica,Arial;font-size:13px}</style></head><body style="word-wrap:break-word"><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto">Hi Slava,</div><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto"><br></div><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto">Thanks for the insight. This is what I suspected, but I wasn&#39;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.</div><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto"><br></div><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto">E.g., the following code works because it conforms to the signature of the flatMap that the type checker decided to use:</div><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto"><br></div><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto"><div id="bloop_customfont" style="margin:0px">b = a.flatMap { elem in</div><div id="bloop_customfont" style="margin:0px">  print(elem)</div><div id="bloop_customfont" style="margin:0px">  return 1</div><div id="bloop_customfont" style="margin:0px">}</div><div id="bloop_customfont" style="margin:0px"><br></div><div id="bloop_customfont" style="margin:0px">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&#39;t type check with the assumed context, maybe tell the user &quot;Did not infer types, try explicitly declaring them&quot;?</div><div id="bloop_customfont" style="margin:0px"><br></div><div id="bloop_customfont" style="margin:0px">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.</div></div> <br> <div id="bloop_sign_1468002824529006080" class="bloop_sign"><div style="font-family:helvetica,arial;font-size:13px">-- <br>Ross LeBeau<br></div></div> <br><p class="airmail_on">On July 8, 2016 at 2:31:46 PM, Slava Pestov (<a href="mailto:spestov@apple.com">spestov@apple.com</a>) wrote:</p> <blockquote type="cite" class="clean_bq"><span><div><div></div><div>Hi Ross,
<br>
<br>Swift&#39;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.
<br>
<br>So really, this has less to do with closures per se, and more with just the general design and philosophy of the type checker.
<br>
<br>(Please correct me if I&#39;ve mis-represented anything here -- this is my recollection of listening in on various discussions in the past).
<br>
<br>&gt; On Jul 8, 2016, at 10:00 AM, Ross LeBeau via swift-dev &lt;<a href="mailto:swift-dev@swift.org">swift-dev@swift.org</a>&gt; wrote:
<br>&gt;  
<br>&gt; 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:
<br>&gt;  
<br>&gt; let a = [[1,2],[3],[4,5,6]]
<br>&gt; var b: [Int]
<br>&gt; b = a.flatMap { elem in
<br>&gt;   return elem
<br>&gt; }
<br>&gt;  
<br>&gt; But this fails with an error &quot;cannot convert return expression of type &#39;[Int]&#39; to return type &#39;Int?&#39;&quot;:
<br>&gt;  
<br>&gt; b = a.flatMap { elem in
<br>&gt;   print(elem)
<br>&gt;   return elem
<br>&gt; }
<br>&gt;  
<br>&gt; And, of course, if you explicitly type the function, it works again:
<br>&gt;  
<br>&gt; b = a.flatMap { (elem: [Int]) -&gt; [Int] in
<br>&gt;   print(elem)
<br>&gt;   return elem
<br>&gt; }
<br>&gt;  
<br>&gt; 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.
<br>&gt;  
<br>&gt; 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&#39;s going on.
<br>&gt;  
<br>&gt; Also if this has already been brought up, forgive me, I just subscribed to this list and a quick search of the archives didn&#39;t get any hits :)
<br>&gt;  
<br>&gt; --  
<br>&gt; Ross
<br>&gt; _______________________________________________
<br>&gt; swift-dev mailing list
<br>&gt; <a href="mailto:swift-dev@swift.org">swift-dev@swift.org</a>
<br>&gt; <a href="https://lists.swift.org/mailman/listinfo/swift-dev">https://lists.swift.org/mailman/listinfo/swift-dev</a>
<br>
<br></div></div></span></blockquote></body></html>