Welche Grenzen setzt Scala der „akzeptablen Komplexität“ der abgeleiteten Typen?

120

Gemäß der Scala-Sprachspezifikation :

... lokale Typinferenz ist zulässig, um die Komplexität der abgeleiteten Grenzen [der Typparameter] zu begrenzen. Minimalität und Maximalität von Typen müssen relativ zu der Menge von Typen mit akzeptabler Komplexität verstanden werden.

Was sind in der Praxis die Grenzen?

Gibt es auch andere Grenzwerte für abgeleitete Ausdruckstypen als für Parametertypgrenzen, und welche Grenzwerte gelten für diese?

Owen
quelle
2
Dieser Blog hat einige interessante Diskussionen zu diesem Thema
Jamil
20
Ich würde vorschlagen, auf der hier erwähnten Mailingliste in Scala-Sprache zu posten
Dave L.
1
Ich bin mir nicht sicher, aber ich denke, es bedeutet zum Beispiel, dass wir eine Liste von Zeichenfolgen haben und dieser ein Int hinzufügen. Die zurückgegebene unveränderliche Liste ist letztendlich vom Typ "Beliebig". Also Maximalität der Typen
Jatin
8
Dies ist tatsächlich ein bewegliches Ziel, da verschiedene Versionen des Scala-Compilers unterschiedliche Grenzen haben. Dies hat sich geändert, und ich gehe davon aus, dass sich dies zumindest in naher Zukunft weiter ändern wird, wenn sich die Sprache weiterentwickelt. Ich stimme diese Frage ab, weil sie nicht beantwortet werden kann, wie es derzeit angegeben ist.
Kevin Sitze
1
@ Kevin True in der Tat. Ich glaube, ich interessiere mich am meisten für Scala 2.9, da es neu, aber stabil ist. Aber ich frage mich, wie viel sich ändern würde.
Owen

Antworten:

10

Beim Ableiten von Typen muss der Compiler häufig die kleinste obere Grenze (Least Upper Bound, LUB) einer Liste von Typen berechnen. Beispielsweise ist der Typ von if (cond) e1 else e1der LUB der Typen von e1und e1.

Diese Typen können sehr groß werden. Versuchen Sie dies beispielsweise in einer 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]...

Dieses Commit führte einige Sanity Checks ein, um die Tiefe solcher abgeleiteten Typen zu begrenzen.

In jüngster Zeit wurden einige Arbeiten zum Einfügen in den Kompilierungsprozess durchgeführt, um abgeleitete Typen zu ermitteln, deren Berechnung lange dauert, und Orte vorzuschlagen, an denen eine explizite Typanmerkung möglicherweise umsichtig ist.

Retronym
quelle