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

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.

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.

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.)

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.

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.

1 Like

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) = ā€¦

Hmm, sounds like a compiler plugin project for someone to doā€¦

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

Note that while Nothing will be avoided, Null will not. Having a common subtype for an unknown hierarchy of actual, randomly created types is hardly possible.

Probably, not actual anymore, but: Scastie - An interactive playground for Scala.

import shapeless.=:!=

def foo[T]()(implicit forceT: T =:!= Nothing): Unit = {}

// foo() // Does not compile

foo[String]() // Compiles
2 Likes