Que limites a scala coloca na "complexidade aceitável" dos tipos inferidos?

120

De acordo com o Scala Language Spec :

... a inferência de tipo local é permitida para limitar a complexidade de limites inferidos [dos parâmetros de tipo]. Minimalidade e maximalidade de tipos devem ser entendidas em relação ao conjunto de tipos de complexidade aceitável.

Na prática, quais são os limites?

Além disso, existem limites diferentes que se aplicam aos tipos de expressão inferidos e aos limites do tipo de parâmetro, e quais são esses limites?

Owen
fonte
2
este blog tem alguma discussão interessante sobre este tema
Jamil
20
Eu sugeriria postagem para a lista de discussão de língua scala mencionados aqui: scala-lang.org/node/199
Dave L.
1
Não tenho certeza, mas acho que isso significa, por exemplo, que temos uma lista de strings e estamos adicionando um int a ela. A lista imutável retornada é basicamente do tipo "Qualquer". Então maximalidade de tipos
Jatin
8
Na verdade, esse é um alvo em movimento, pois diferentes versões do compilador Scala têm limites diferentes. Isso mudou e espero que continue a mudar pelo menos no futuro próximo, à medida que o idioma continuar se desenvolvendo. Estou votando esta questão para baixo, porque ela não pode ser respondida como está atualmente declarada.
22612 Kevin Sitze
1
@ Kevin True, de fato. Suponho que estou mais interessado no scala 2.9, pois é recente, mas estável. Mas eu me pergunto o quanto isso mudaria.
Owen

Respostas:

10

Ao inferir tipos, o compilador geralmente precisa calcular o LUB (Least Upper Bound) de uma lista de tipos. Por exemplo, o tipo de if (cond) e1 else e1é o LUB dos tipos de e1e e1.

Esses tipos podem ficar muito grandes, por exemplo, tente isso em um 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]...

Esse commit introduziu algumas verificações de sanidade para limitar a profundidade desses tipos inferidos.

Houve algum trabalho recente para conectar ao processo de compilação para detectar tipos inferidos que demoram muito para serem calculados e sugerir locais onde uma anotação explícita de tipo pode ser prudente.

retrônimo
fonte