#2077 issue with type interference when using eachWhile

tcolar Sat 5 Jan 2013

There seem to be an issue with type interference with eachWhile:

index := itemList.items.eachWhile |item, index -> Int?|
{
  return item.file == file ? index : null
}
index += 2 

Compiler error:

No operator method found: sys::Obj? + sys::Int

Index should be inferred as Int? right ?

brian Mon 7 Jan 2013

No, it is purposely that it returns any Obj? you want. You probably want to use findIndex in that case

tcolar Mon 7 Jan 2013

I'm not sure I follow, in my example the eachWhile signature specifically says it will return an Int

In fact the compiler will not let me return anything but an Int from the eachWhile closure, that's why i would have thought it would/should be inferred as an Int.

brian Mon 7 Jan 2013

In fact the compiler will not let me return anything but an Int from the eachWhile closure

Your closure is typed to return an Int, but you can just as easily type your closure to return a Str or any other type. For example it is typical to use that method to lookup some object and get a field off it:

Str? name := users.eachWhile |u| { u.id == x ? u.name : null }

KevinKelley Mon 7 Jan 2013

Inferred types don't flow across module (pod) boundaries... at the time when sys pod is compiled, the only generic type that is allowed for is T, the element-type of the list. Later when your pod is being compiled, there's no mechanism to flow the return type of your closure through the AST of the pre-compiled sys::List.eachWhile and back, to the declaration site of your index variable.

I think this would require either: a full generics system; or a whole-program-compile step, where the dependent pods' ASTs are still available; or maybe some kind of special-casing for this particular function.

Login or Signup to reply.