#2509 Implicit Function Return Types

SlimerDude Sun 7 Feb 2016

I'll start by saying programmers are lazy. Often this is a good thing, as you end up automating some tasks and simplifying others. It also means we want to type less, which is where type inference and implicit casts come in. It's one of the many reasons why Fantom is a joy to program. It's also why I proposed the enhancement to it-blocks.

Whilst trying other ways to reduce my typing I noticed something scary with List.map(). It has the following signature:

Obj?[] map(|V item, Int index->Obj?| c)

But note the output from these valid incantations:

list := [1, 2, 3]

list.map                  { it.toStr }          // --> [1, 2, 3]
list.map |int|            { int.toStr }         // --> [1, 2, 3]
list.map |Int int|        { int.toStr }         // --> [null, null, null]
list.map |int|            { return int.toStr }  // --> [1, 2, 3]
list.map |Int int|        { return int.toStr }  // --> [null, null, null] (Fantom 1.0.68 only)
list.map |Int int -> Str| { int.toStr }         // --> [1, 2, 3]
list.map |Int int -> Str| { return int.toStr }  // --> [1, 2, 3]

I would have expected [1, 2, 3] to be returned from all the calls.

I know that technically the signature |Int int| defines a Void function, but it's a single statement with an (implicit) return value. Further more, it's being handed to a method that expects a function with a return value, not a Void func.

Could the function's return type be coerced to what the method signature expects? I can't think of a scenario where this would not be wanted.

(Side note: I've mentioned this before, but I believe a lot of the knarly messiness around reflection stems from Void being considered the same as null whereas really they should be 2 very different objects. Shame we're stuck to handling what Java and other platforms give us.)

andy Mon 8 Feb 2016

Yeah thats bitten me before a few times - might be nice - but not sure I've run into it enough to change personally.

brian Mon 8 Feb 2016

I agree its non-ideal, but sort of have to pick the lesser of various evils. Right now introducing a hard type into a closure signature means its explicit typed. There isn't any notion of "mixed type inference" were you let compiler infer some parameter/return types and you explicitly type others. When the return type is not void, that actually makes the best sense. One thing we could evaluate is saying that a function map which expects a return Obj like that doesn't allow Void

brian Wed 10 Feb 2016

Ticket promoted to #2509 and assigned to brian

Still thinking about this, but I think at the very least the existing behavior is incorrect - even if we just need to add a compile time error

Login or Signup to reply.