[swift-dev] Type inference of functions with more than one statement

Ross LeBeau ross.lebeau at gmail.com
Fri Jul 8 13:56:59 CDT 2016


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 (spestov at 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 at 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 at swift.org
> https://lists.swift.org/mailman/listinfo/swift-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-dev/attachments/20160708/018360ed/attachment.html>


More information about the swift-dev mailing list