Pourquoi est-Scala, à la syntaxe pour les tuples si inhabituel?
En mathématiques et en informatique, un tuple est une liste ordonnée d'éléments. Dans la théorie des ensembles, un (ordonnée) n-n-uplet est une séquence (ou de la liste ordonnée) des éléments n, où n est un entier positif.
Ainsi, par exemple, en Python le 2ème élément d'un tuple serait accessible via t[1]
.
En Scala, l'accès n'est possible que via des noms étranges t._2
.
La question est donc, pourquoi ne puis-je pas accéder aux données de n-uplets d'une Séquence ou d'une Liste si elle est par définition? Est-il une sorte d'idée ou tout simplement pas encore inspecté?
Vous devez vous connecter pour publier un commentaire.
Scala sait l'arité de la n-uplets et est donc en mesure de fournir des accesseurs comme
_1
,_2
, etc., et produire une erreur de compilation si vous sélectionnez_3
sur une paire, par exemple. En outre, le type de ces champs est exactement ce que le type utilisé comme paramètre pourTuple
(par exemple_3
sur unTuple3[Int, Double, Float]
sera de retour d'uneFloat
).Si vous souhaitez accéder à la n-ième élément, vous pouvez écrire
tuple.productElement(n)
, mais le type de retour de ce qui ne peut êtreAny
, donc vous perdez les informations de type.productIterator
afin qu'il puisse utiliser un type spécifique dans certains cas. Cela pourrait être à venir pour 2.10, mais quelqu'un me corrige si je me trompe.t[1]
et de garder toutes les informations de type, et tout simplementt[exp]
(où le résultat de l'exp est inconnu au moment de la compilation) ont un type de retour deAny
, droit? Il semblerait donc que la syntaxe est différente en plus de conduire à la maison le point pour le programmeur d'un Tuple n'est pas une Liste.t[exp]
est exactement ce que t.productElement(exp)` ne. Notez que les crochets sont utilisés dans Scala pour les paramètres de type uniquement.-Xexperimental
dans la version 2.10 du tronc, mais uniquement pour les classes de cas, pas pour les n-uplets. Aucune idée de pourquoi.productElement
car vous perdez les informations de type...Je crois que l'extrait suivant, tiré de "Programming in Scala: Un plan Étape par Guide pas à pas" (Martin Odersky, Lex Cuillère et Bill Venners) répond directement à vos deux questions:
Scala tuples très peu d'un traitement préférentiel autant que la syntaxe de la langue est, au-delà des expressions
'(' a1, ..., an ')'
traité par le compilateur comme un alias pour scala.Tuplen(a1, ..., an) de l'instanciation de classe. Sinon les tuples ne se comportent comme tous les autres Scala objets, en fait, ils sont écrit en Scala comme cas des classes qui vont de Tuple2 à Tuple22. Tuple2 et Tuple3 sont également connu sous l'alias de la Paire et le Triple respectivement:Tuple1
a été ajouté.Une grande différence entre
List
,Seq
ou des éventuelles collectes et n-uplet est que dans tuple chaque élément possède son propre type de où la Liste de tous les éléments ont le même type.Et par voie de conséquence, à la Scala, vous trouverez des classes comme
Tuple2[T1, T2]
ouTuple3[T1, T2, T3]
, donc, pour chaque élément, vous avez également le type de paramètre. Collections accepter seulement 1 type de paramètre:List[T]
. La syntaxe comme("Test", 123, new Date)
est juste sucre syntaxique pourTuple3[String, Int, Date]
. Et_1
,_2
, etc. sont des champs sur tuple que le retour de correspondant à l'élément.Vous pouvez facilement réaliser qu'avec informes:
Beaucoup de méthodes disponibles pour la collection standard sont également disponibles pour les tuples de cette façon (
head
,tail
,init
,last
,++
et:::
pour la concaténation,+:
et:+
pour ajouter des éléments,take
,drop
,reverse
,zip
,unzip
,length
,toList
,toArray
,to[Collection]
, ...)Avec la normale de l'indice d'accès, de toute expression peut être utilisée, et il faudra un certain effort sérieux pour vérifier à l'compile-time si le résultat de l'expression d'index, il est garanti pour être dans la gamme. En faire un attribut, et une erreur de compilation pour
(1, 2)._3
suit "gratuitement". Des choses comme ne permettant que des constantes entières à l'intérieur de l'élément d'accès sur les tuples serait un cas très spécial (moches et inutiles, certains pourraient dire ridicule) et encore un peu de travail à mettre en œuvre dans le compilateur.Python, par exemple, peuvent s'en tirer avec cela, car il ne serait pas (ne pouvait pas les) chèque (à l'compile-time, qui est) si l'indice est dans la gamme de toute façon.
Je pense que c'est pour une vérification de type. Comme delnan dit, si vous avez un n-uplet
t
et un indexe
(une expression arbitraire),t(e)
donnerait le compilateur aucune informations à propos de l'élément est en cours d'accès (ou même si c'est un élément valide pour un tuple de cette taille). Lorsque vous accédez à des éléments par nom de champ (_2
est un identificateur valide, ce n'est pas une syntaxe spéciale), le compilateur sait que le champ dans lequel vous souhaitez accéder et de quel type il est. Des langages comme Python n'ont pas vraiment de types, de sorte que ce n'est pas nécessaire pour eux.Mis à part les avantages Jean-Philippe Pellet déjà mentionné cette notation est également très commun en mathématiques (voir http://en.wikipedia.org/wiki/Tuple). Beaucoup de professeurs d'ajouter des index de n-uplet de variables, si elles veulent se référant aux éléments d'un tuple. Et la commune (LaTeX) notation pour l'écriture de "avec index n" (allusion à la n-ème élément du tuple) est
_n
. Donc, je trouve ça effectivement très intuitive.