Qu'est-ce qui est derrière la restriction de taille Numericrange Int sur la compréhension de Scala for-boucle? Est-il possible (sans trop de mal à la tête) pour prolonger "pour / SQS", numericrange pour utiliser de longues (ou quelque chose de plus grand que INT.MAXValue)?
scala> code> b>
pour (i: long p>
java.lang.IllegalArgumentException: 0 to 10000000000L by 1: "seqs cannot contain more than Int.MaxValue elements."
at scala.collection.immutable.NumericRange$.count(NumericRange.scala:227)
at scala.collection.immutable.NumericRange.numRangeElements(NumericRange.scala:53)
at scala.collection.immutable.NumericRange.length(NumericRange.scala:55)
at scala.collection.immutable.NumericRange.foreach(NumericRange.scala:73)
at .<init>(<console>:19)
at .<clinit>(<console>)
at .<init>(<console>:11)
at .<clinit>(<console>)
at $print(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:704)
at scala.tools.nsc.interpreter.IMain$Request$$anonfun$14.apply(IMain.scala:920)
at scala.tools.nsc.interpreter.Line$$anonfun$1.apply$mcV$sp(Line.scala:43)
at scala.tools.nsc.io.package$$anon$2.run(package.scala:25)
at java.lang.Thread.run(Thread.java:680)
4 Réponses :
in Scala Il n'y a pas de boucle, mais une compréhension. Cela fonctionne différent d'une boucle. En fait, votre compréhension est traduite en:
var i = 0L while(i < 10000000000) { // do stuff i+=1 }
Merci pour le repli, je suis tout à fait au courant du sucre de la syntaxe de compréhension. Mais le point était "pourquoi" SEQ est restreint (comme indiqué dans la question) et si SEQ est très extensible?
Donc, ce que vous signifiez fondamentalement, c'est que la compréhension n'est pas suffisamment mature pour être utilisée dans la production? Est-ce une faille de conception de bibliothèque ou une question de langage?
Non, cela signifie seulement que pour code> la construction nécessite une séquence d'éléments et la construction d'une telle construction ne peut pas être effectuée avec la taille que vous attendez, en raison de la limitation de la mémoire (voir la dernière version de ma réponse).
Non, les compréhensions sont tout simplement bien pour les sections de votre application à la non-performance. Il est plus lent qu'une boucle, mais aussi plus puissante. Si vous travaillez avec MONADS FOR-COMPRENSIONS, mais pas pour itération sur de grandes collections.
@Nicolas pour ne nécessite pas de séquence, mais une monade.
Ni un SEQ, ni une monade, comme Monad n'est pas un trait code> à Scala. En fait, je pense que cela nécessite quelque chose qui peut être transféré dans un
itérateur code> (à vérifier)
@Drexin: Cette citation va directement dans nos lignes de guide de conception. Merci! IMO - Cela devrait également être adressé dans une sorte de "Guide de conception Scala" officiel "
@Nicolas Vous avez raison, Monad n'est pas un type de scala, mais un rendement pour (...) code> prend tout ce qui a
mappe code> et
plattmap code > Mise en œuvre, un simple
pour code> sans le rendement
code> prend n'importe quoi, qui a pour objectif de mettre en œuvre. Vous voudrez peut-être lire cet article sur Monads à Scala: James-iry.Blogspot.de/2007/09/monads-are-Elesphanpes-part--.ht ml
Hum oui, ça marche, je suis à peu près sûr que cela n'a pas été mis en œuvre grâce aux types de structure.
réponse courte - il semble être une "fonctionnalité" - au moins, il fonctionne comme conçu. P>
Comme @Drexin a souligné, la mise en œuvre de "to" est limitée à avoir une plage int. Cependant ... p>
Le problème est que Numericrange [t] .Count (), .numrangselements et .length () renvoie un INT - peu importe ce que T est. Dans ce cas, c'est un Numericrange [long], où il semble un peu faux d'avoir compté () limité à 31 bits, IMHO.
Cependant ... p>
Parcourir les problèmes de JIRA, cela semble fonctionner comme conçu. Voir, E.G., SI-4370 . Mais juste pour être sûr que cela a été pensé à cette perspective, j'ai entré SI-5619 A >. P>
Il n'est pas limité à une gamme, c'est-à-dire ce que vous créez. Vous pouvez transmettre n'importe quelle monade à une compréhension.
@Ed Staub - C'est exactement mon point c'est-à-dire pourquoi. Pourquoi le nombre de gammes () limité à int! IMHO c'est assez étrange mais la grande question reste: est-ce un bug ou une fonctionnalité ;-)
@Drexin: une idée de la raison pour laquelle la plage compte par défaut sur INT?
Peut-être à cause de la compatibilité avec la JVM 32bit. Mais c'est juste une supposition.
@IDev Votre mise à jour n'est également pas entièrement vraie, car vous pouvez avoir une gamme de longs, tant que vous n'avez pas plus d'éléments d'int.maxValue. Par exemple, 0L à 100000000000L par 1000000 code> fonctionne juste bien.
@Drexin - Je fais référence à l'erreur spécifique iodev dans. Il est possible d'utiliser une monade avec une boucle avec plus de 2 gigaitères - c'est juste ce particulier (numericrange) qui a la limitation - ne pas dire qu'il n'y a pas d'autres personnes avec la même limite.
Toutes les idées / réflexions de GRENRAL: La limitation de l'int.maxvalue est-elle si numericrange une "défaute" de conception doit être améliorée?
C'est définitivement une faille. Puisque vous pouvez construire une telle gamme, mais il échoue dès que vous appelez une méthode qui nécessite de vérifier sa longueur.
@Nicolas, ce n'est certainement pas une faille. 0L à 100000000000L code> n'est pas valide, mais
0L à 100000000000L par 1000000 code> est valide, aucune exception ne peut être lancée dans le premier cas ou le second cas ne serait pas possible. La limite
int code> est liée à la performance,
Taille code>,
Appliquer code> sur
SEQ code> et les propres limitations de Java, en particulier la taille de
tableau code>.
@Daniel Une exection peut être lancée si nous n'agissons pas paresseux eval comptent code>. Sinon, nous pouvons aussi bien essayer de limiter l'utilisation de la limite de
de longueur code> (surtout dans le cas de Teach)
@Nicolas c'est le point. Une exception sera lancée si Nombre code> n'est pas évalué paresseusement, mais ce qui ne va pas pour
0L à 100000000000L par 1000000 code>. Et tandis que
longueur code> peut se comporter un peu différemment (et fait, pour les collections infinies),
appliquer code> ne peut pas. Bien que pour être sûr, on pourrait théoriquement dépasser
int.maxvalue code> avec un flux infini
code>, donc il y a certainement une contradiction là-bas.
@ DanielC.Sobral Non, ce n'est pas le cas: (0L à 100000000000L par 1000000) .Length code> fonctionne comme un charme et appelle
numericrange.count code>.
En fait, il semble vraiment que l'échec de l'initialisation de numericrange.count code> effectue exactement ce que nous attendons. Mais à coup sûr, cela ne résout pas le problème de consistance que nous disposons avec un flux infini
code>.
@Nicolas bien, allez-y et écrivez le patch.
@ DanielC.Sobral Pensez-vous que la pénalité de performance d'évaluation de la longueur pendant l'initialisation est acceptable? C'est le dernier doute que j'en ai à ce sujet.
@Nicolas - J'ai bien peur de ne pas comprendre ce que le correctif proposé est. Mais la pénalité de performance: je ne m'inquiéterais pas à ce sujet, car le nombre () / longueur () est utilisé de manière omniprésente dans la classe. Equals (), Tostring, Foreach () ... Il est difficile d'imaginer que quelqu'un voulant utiliser un objet si fragile, il suffit d'attendre que la mauvaise méthode soit appelée à décomposer à l'hystérie ;-).
@Nicolas la pénalité de performance d'un paresseux val code> loin dépasse i> la pénalité de performance de précompouver la taille, de sorte que ce serait plus rapide i> de ne pas en faire un
Lazy Val code>.
J'ai détaillé quel est le problème selon moi et certaines alternatives là-bas: Problèmes.scala-Lang. Org / Browse / SI-5622
Les méthodes taille code> et
longueur code> renvoient un
int code>, il ne serait donc pas possible de retourner une valeur supérieure à
Int.maxvalue code>. Sur
SEQ code>, aussi, la méthode
appliquer code> prend un
int code>, souffrant du même problème. Les collections Scala, comme les collections Java em> sont donc limitées à
int.maxvalue code> éléments. P>
Donc, pour faire face aux collections SEQ plus grandes que Int.Maxsize, nous avons besoin d'un BigSeq? ;-)
@Iodev Il y a une question pratique d'utilité des collections qui grandes. Je pense que le vrai problème est que, peut-être, les gammes ne devraient pas être des collections, ont simplement des conversions dans i> collections.
Vous ne pouvez pas compter les éléments aussi longtemps que leur compte ne correspond pas à int code>, car
longueur code> est déclaré pour retourner
int code>, mais ici est le raccourci: vous pouvez créer itérateurs em> avec toute taille réelle em>, tant que vous n'essayez pas de les compter.
scala> def longRange(first: Long, last: Long) = new Iterator[Long] {
private var i = first
def hasNext = i < last
def next = {val r = i; i += 1; r}
}
longRange: (from: Long, to: Long)java.lang.Object with Iterator[Long]
scala> val lol = longRange(0, Long.MaxValue) map (x => x * x)
lol: Iterator[Long] = non-empty iterator
scala> lol drop 5 take 5 foreach println
25
36
49
64
81
Fonctionne bien sur Scala 2.9, Scala 2.10 crie les points suivants: Scala> Def Longrange (à partir de: Long, à: Long) = Nouveau Itérateur [LONG] {| Var i: long = de | def hasnext = i <à | DEF NEXTE = {VAL R = I; i + = 1; r} | }
On dirait que Scala Compiler est confondu par à code> mot, car il existe une méthode avec ce nom. Peut-être que quelque chose s'est mal passé dans leur définition de syntaxe. BTW, j'ai commencé à penser que cette partie de Scala Syntaxe (permet de permettre des appels de méthode "style space" au lieu de "style de points" pour tous les noms, non seulement "symboles spéciaux" comme
+ code>,
+ + code>,
:: code>, etc.) est diabolique. Ici y a l'exemple de travail: ideone.com/z5989q , et si nous renommerons
fin code> à
à CODE>, il ne compile pas: ideone.com/6fadfe . Peut-être que c'est un sujet juridique de signaler un bogue.