Ability to force the caller to specify a type parameter for a polymorphic method


#21

In my experience most of cases where inferring Nothing is bad comes from flawed Option.fold implementation. Consider following code:

def optionToList[T](option: Option[T]): List[T] =
  option.fold(List.empty[T] /* skipping T here will result in compilation error */)(value => List(value))

We can skip parameter for List.empty if we use Option.map + Option.getOrElse:

def optionToList[T](option: Option[T]): List[T] =
  option.map(value => List(value)).getOrElse(List.empty /* or even: Nil */)

Disclaimer: code wasn’t tested.


#22

Perhaps a dumb idea. If there was another type between Any and Nothing which we call Something, where Something is also a subtype of all other types, except Nothing, then one could create a lower-bound with >: Something, where you don’t want Nothing to be inferred.

So for cases where Nothing is inferred but the lower bound is Something the compiler will generate an error.


#23

Yes, but there it isn’t that Nothing is a choice to avoid, it’s that the compiler is to short-sighted. (Dotty fixes that.)


#24

I’m interested, is there any case with implicit arguments where such algorithm has sence?
In my experience such implicit substitution will cause error in runtime.

 def load[T](id:Long)(implicit t:TypeTag[T]) = {
   sql(s"""
     select * from ${getTabel(t)} where id = $id
   """)
}

load(10) // It has no sence,since table is not defined.

#25

A similar idea is if there were a way to express exclusive type bounds, so you could say, supertype of Nothing except Nothing. Exclusive upper bounds would also be nice, at least for excluding Any.

Except that it would only work on the static type, not the actual value of course. So you couldn’t keep out nulls that way.


#26

If the compiler inferred Something, would that be better than Nothing? Or would it be forbidden from inferring Something? Would there be any use for Something other than being not Nothing?

Besides, Something and Nothing are really identical. Two types are identical if they have the same instances. If Something is subtype of all types, it has no instances, the same as Nothing.

Seems better to have an annotation NotNothing

def doSomething[@NotNothing T](thing: T) = …


#27

Hmm, sounds like a compiler plugin project for someone to do…


#28

I mean that Something is not really something (heh) that can be inferred