120

According to the Scala Language Spec:

... local type inference is permitted to limit the complexity of inferred bounds [of type parameters]. Minimality and maximality of types have to be understood relative to the set of types of acceptable complexity.

In practice what are the limits?

Also, are there different limits that apply to inferred expression types than to parameter type bounds, and what are those limits?

Owen
  • 38,836
  • 14
  • 95
  • 125
  • 2
    [this blog](http://pchiusano.blogspot.com/2011/05/making-most-of-scalas-extremely-limited.html) has some interesting discussion on this topic – Jamil Jul 11 '12 at 11:50
  • Yes, it mentions one kind of type that scala will refuse to infer: a partially applied type constructor. I wonder if there are others. – Owen Jul 11 '12 at 22:17
  • 20
    I would suggest posting to the scala-language mailing list mentioned here: http://www.scala-lang.org/node/199 – Dave L. Oct 11 '12 at 19:57
  • 1
    I am not sure, but I think it means for example we have a list of strings and we are addign an int to it. The immutable list returned is ultimately of type "Any". So maximality of types – Jatin Dec 02 '12 at 13:12
  • 8
    This is actually a moving target as different versions of the Scala compiler have different limits. This has changed and I expect will continue to change for at least the near term future as the language continues to develop. I'm voting this question down because it cannot be answered as it is currently stated. – Kevin Sitze Dec 21 '12 at 07:08
  • 1
    @kevin True indeed. I suppose I am most interested in scala 2.9, since it is recent but stable. But I wonder how much is would change. – Owen Dec 28 '12 at 19:00
  • 1
    @KevinSitze Either way, I think some explanation would be useful, as this question has come up many times in one form or another on many different sites, mailing lists, and blogs. Scala's inference can be good at best, and terribly frustrating at worst. One example of such can be found in my [question](http://stackoverflow.com/questions/14250561/scala-type-inference-on-an-existential-type) related to inferred expression types. – Alex DiCarlo Jan 10 '13 at 18:44

1 Answers1

10

When inferring types, the compiler often needs to calculate the Least Upper Bound (LUB) of a list of types. For example, the type of if (cond) e1 else e1 is the LUB of the types of e1 and e1.

These types can get quite large, for example try this in a REPL:

:type Map(1 -> (1 to 10), 2 -> (1 to 10).toList)
scala.collection.immutable.Map[Int,scala.collection.immutable.Seq[Int] with scala.collection.AbstractSeq[Int] with Serializable{def reverse: scala.collection.immutable.Seq[Int] with scala.collection.AbstractSeq[Int]{def reverse: scala.collection.immutable.Seq[Int] with scala.collection.AbstractSeq[Int]; def dropRight(n: Int): scala.collection.immutable.Seq[Int] with scala.collection.AbstractSeq[Int]; def takeRight(n: Int): scala.collection.immutable.Seq[Int] with scala.collection.AbstractSeq[Int]; def drop(n: Int): scala.collection.immutable.Seq[Int] with scala.collection.AbstractSeq[Int]; def take(n: Int): scala.collection.immutable.Seq[Int] with scala.collection.AbstractSeq[Int]}; def dropRight(n: Int): scala.collection.immutable.Seq[Int] with scala.collection.AbstractSeq[Int]{def reverse: scala.collection.immutable.Seq[Int] with scala.collection.AbstractSeq[Int]; def dropRight(n: Int): scala.collection.immutable.Seq[Int]...

This commit introduced some sanity checks to limit the depth of such inferred types.

There has been some recent work to plugin to the compilation process to detect inferred types that take a long time to calculate, and suggest places where an explicit type annotation might be prudent.

retronym
  • 54,768
  • 12
  • 155
  • 168