Rust: Problème de suivi pour les plages inclusives `..=` (RFC #1192) -- à l'origine `...`

Créé le 4 sept. 2015  ·  331Commentaires  ·  Source: rust-lang/rust

Statut actuel

Nous prévoyons de changer la syntaxe des plages et des modèles inclusifs en ..= . La syntaxe ... dans les motifs est stable et restera (silencieusement) dépréciée pour le moment ; rustfmt peut réécrire ... en ..= . Cela vient après de nombreuses discussions. Voir ce commentaire pour justification.

Plus aucune discussion de syntaxe ne devrait avoir lieu dans ce fil . Toute proposition différente de syntaxe de gamme exclusive doit avoir lieu sur le forum de l' le forum des internes , après avoir lu tous les commentaires existants et leur justification ici. Notamment, la rupture de la compatibilité descendante est un non-démarreur.

Étapes à suivre

B-RFC-implemented B-unstable C-tracking-issue E-mentor T-lang T-libs disposition-merge finished-final-comment-period

Commentaire le plus utile

L'équipe lang a de nouveau discuté de cette fonctionnalité lors de notre réunion d'aujourd'hui et est arrivée à peu près à la matrice suivante :

  • La prise en charge de ... dans les modèles et de .. dans les expressions, et rien d'autre, est une conception intenable ; cela amène les utilisateurs à s'attendre à ce que la syntaxe fonctionne qui ne fonctionnera pas.

  • Autoriser ... et .. aux deux endroits aiderait, mais le problème du décalage par un est un réel problème ; aucun d'entre nous n'est impatient de recevoir des rapports de personnes passant des heures à traquer une période errante.

  • Passer à ..= et .. est moins esthétique, mais évite les problèmes pratiques très réels ci-dessus. Nous pouvons également le déployer de manière très douce : introduisez d'abord ..= comme syntaxe alternative (que rustfmt peut réécrire), et seulement après qu'elle soit devenue idiomatique, dépréciez ... .

Au cas où vous ne le sauriez pas, l'équipe pense que ..= et .. est notre meilleure voie à suivre. Ce problème a également été discuté au point qu'il est très peu probable que de nouveaux arguments soient soulevés, nous sommes donc prêts à franchir le pas : nous recherchons quelqu'un qui aimerait implémenter la notation ..= pour les deux modèles et expressions, et par la suite nous irons à FCP !

Tous les 331 commentaires

Peut-être a..b| ou a..b]

Je pense que cela ouvrira la voie à un nouveau type d'erreurs imprévisibles à l'avenir à cause d'une simple faute de frappe (.. vs ...). Mieux si c'était .... (4 périodes). De cette façon, le facteur humain est moins sujet aux erreurs, imo.

Je pense que https://github.com/rust-lang/rfcs/pull/1592 et https://github.com/rust-lang/rfcs/pull/1582 combinés ..= syntaxe à la place. À moins que quelqu'un puisse penser à une meilleure syntaxe que (head..., tail) pour développer un tuple au début d'un tuple plus grand.

J'ai trouvé ce problème parce que j'avais une erreur _off-by-one- dot _ dans mon code alors que je voulais utiliser une plage exclusive.

👎 pour la syntaxe ... . Je pense qu'avoir une syntaxe facile à taper qui provoque des erreurs une par une serait une arme à feu.

La fonctionnalité est cependant utile, donc je serais heureux de l'avoir avec une syntaxe différente, par exemple ..=

La syntaxe de cette question est-elle ouverte ? Étant donné que ... est déjà dans les déclarations de correspondance, j'ai supposé que le navire avait navigué.

Personnellement, je préférerais la gamme ... inclusive, mais comme il existe déjà la version exclusive .. , je vois le potentiel de problèmes. Après avoir regardé #23635, je préfère déprécier .. et n'autoriser que ... .

J'utilise beaucoup des plages inclusives pour l'équivalent de C-like pour les boucles for i in 0..foo.len() où elles s'intègrent parfaitement, donc je préférerais que celle-ci reste (j'en ai besoin, car les itérateurs de Rust sont "unidimensionnels" et souvent trop difficile à utiliser avec des tableaux 2D ou une itération non linéaire).

Le problème de débordement pour les plages inclusives semble idiot, mais en pratique, je n'ai jamais rencontré ce problème, car Rust est ennuyeux à utiliser avec tout type autre que usize . Si je n'ai pas lancé lors de la création de la plage for i in 0..(len as usize) , alors je devrais quand même utiliser i as usize une demi-douzaine de fois dans la boucle.

Étant donné que cette syntaxe est toujours basée sur les fonctionnalités, j'espère que le navire n'a pas navigué.

Considérant que Swift utilise ... pour les plages inclusives et ..< pour les plages exclusives, l'utilisation de ..= pour les plages inclusives semble assez raisonnable.

Je n'ai pas d'informations utiles, mais j'aimerais que les plages inclusives quittent le statut "expérimental". Alors que je parcourais Rust By Example, j'ai trouvé un extrait qui pourrait en bénéficier :

fn fizzbuzz_to(n: u32) {
    for n in 1..n + 1 {
        fizzbuzz(n);
    }
}

En haut ? ??

Je veux écrire une RFC pour la syntaxe a ..= b et les plages généralisées. J'ai lancé un fil de

IMHO ..= semble bizarre. L'approche de Swift de ... et ..< me semble meilleure, car je préfère les points de suspension à deux points - les points de suspension représentent l'omission et nous omettons les chiffres entre le début et la fin de la plage.

Je pense toujours ... et .. était assez bon. Vous avez une différence de caractère, donc l'erreur est plus difficile à faire que +/- ou x/y ou autre.

Puisque j'ai mal compris cela moi-même plus tôt (et j'ai donc supprimé mon commentaire):

Selon le processus RFC de Rust, cette proposition a déjà été examinée, discutée et approuvée dans la demande d'extraction RFC 1192 . Le présent numéro retrace la mise en œuvre de ce qui y a été précédemment décidé. La discussion a couvert de nombreux points soulevés ici : la syntaxe alternative (y compris pas de nouvelle syntaxe), le contraste avec les opérateurs similaires de Ruby, etc.

Si vous pensez fermement que la fonctionnalité devrait être différente, je pense que vous devez la suivre dans le même processus RFC, car c'est ainsi que les modifications de la langue sont apportées. Mais ce problème n'est pas le lieu pour cela.

@jimblandy, nous devrions peut-être demander à @nikomatsakis de modifier ce rappel poli et ces conseils dans le premier commentaire de Really Big Print. ??

@shepmaster Ce serait probablement une bonne chose à ajouter à un modèle utilisé pour classer _tous_ les problèmes de suivi.

Nomination pour discussion/FCP possible

Nous en avons discuté lors de la réunion @rust-lang/lang. Il y avait un sentiment général de mécontentement avec cette fonctionnalité - nous avons envisagé de passer à la dépréciation, mais avons décidé de ne pas en tenir compte pour le moment. Il y a deux objections majeures à ... dans sa forme actuelle :

  • la facilité de confusion entre .. et ... ;
  • @aturon a pensé qu'il serait préférable d'avoir une syntaxe de plage plus "complètement capable" - cela pourrait également être utilisé dans des API comme l'itération btree et ainsi de suite.

À cette fin, nous nous demandions si quelqu'un serait prêt à faire avancer une RFC qui permettrait une syntaxe plus générale comme celle-ci permettant aux gens de spécifier précisément si les limites inférieures et supérieures seraient inclusives ou exclusives. Je pense que @aturon serait heureux de travailler avec quelqu'un sur un tel RFC.

Je sais que j'ai bloqué pendant un certain temps, mais j'ai récemment ouvert un fil de discussion sur la façon de représenter ces plages entièrement capables dans libstd (lié ci-dessus ), mais personne n'a commenté :(

Avec quelques commentaires sur ce qui précède, je serais heureux d'aider avec un nouveau RFC.

J'ai récemment ouvert un fil de discussion sur la façon de représenter ces plages entièrement capables dans libstd (lié ci-dessus), mais personne n'a commenté :(

Cela reflète un peu leur utilité.
Bien que le fait d'avoir des plages arbitraires inclusives-exclusives semble être une bonne idée, je suis presque sûr que tout sauf .. et dans une bien moindre mesure ... ne sera jamais utilisé.

@durka

Je sais que j'ai calé pendant un moment, mais j'ai ouvert un fil de discussion sur la façon de représenter ces plages entièrement capables dans libstd (lié ci-dessus), mais personne n'a commenté :(

Cela ressemble à peu près à l'approche que nous avions en tête, oui.


@petrochenkov

Bien que le fait d'avoir des plages arbitraires inclusives-exclusives semble être une bonne idée, je suis à peu près sûr que tout sauf .. et dans une moindre mesure ... ne sera jamais utilisé.

Pour être honnête, je suis d'accord, mais je pense toujours que cela peut valoir la peine de poursuivre une syntaxe plus générale. En particulier, je pense que ... est sous-optimal, mais si nous passons à ..= ou quelque chose de plus explicite, cela ne fait probablement pas de mal de faire quelque chose d'un peu plus général, même si c'est rarement utilisé. C'est-à-dire que si nous le rendons systématique, cela ne semble pas beaucoup plus difficile à apprendre, et c'est sûrement le cas qu'il n'y aurait aucune confusion quant à savoir si .. ou ... signifie "plus de nombres ".

Cela ressemble à peu près à l'approche que nous avions en tête, oui.

Lequel? J'ai suggéré plusieurs alternatives dans mon message.

Je veux souvent parcourir des plages inclusives et j'ai vraiment aimé taper 0...x au lieu de 0..(x + 1) . Je comprends que cela puisse introduire des erreurs ponctuelles, mais quelles alternatives avons-nous ?

En supposant que la syntaxe de Rust puisse être librement modifiée sans effets secondaires, je ne vois que quelques modèles évidents :

Le prendre tel qu'il est

1..4 // 1, 2, 3
1...4 // 1, 2, 3, 4

qui est une solution correcte à mon humble avis et également utilisée dans la correspondance de modèles.

Emprunter aux mathématiques

[1, 4] // 1, 2, 3, 4
[1, 4[ // 1, 2, 3
]1, 4] // 2, 3, 4
]1, 4[ // 2, 3

qui est la syntaxe la plus complète, mais enfreint la même règle d'accolades ouvrantes et fermantes et est visuellement plus difficile à analyser.

Emprunter à Python

1:1:=5 // 1, 2, 3, 4, 5
1:1:<5 // 1, 2, 3, 4

qui est un modèle connu et pourrait également incorporer une taille de pas. Je ne sais pas comment fonctionne le processus RFC, mais je pense qu'un pas doit également être pris en compte lorsque l'on parle de plages.

Lorsque le pas ne fait pas partie de cette discussion (ou d'une future), ..= et ..< semblent très raisonnables !

Mise à jour : Je pense que ..= et ..< seraient une très bonne solution. Garder le pas en tant qu'adaptateur est beaucoup plus logique.

Cette discussion devrait-elle inclure des fourchettes décroissantes ? La solution actuelle consistant à inverser la plage est assez déroutante (mais peut-être pas si nous avions des plages inclusives).

Par exemple, pouvez-vous lire et comprendre cela sans plisser les yeux ?

for i in (1..l.len()).rev() { ... }

EDIT : et avec la police de GitHub, c'est encore plus déroutant car l ressemble à 1

Je pense qu'un pas négatif suffirait.

Nous pourrions utiliser la syntaxe Matlab, a:b et a:step:b .

Le 4 novembre 2016 00:50, "Ott" [email protected] a écrit :

Je pense qu'un pas négatif suffirait.

-
Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/rust-lang/rust/issues/28237#issuecomment-258344460 ,
ou couper le fil
https://github.com/notifications/unsubscribe-auth/AAC3n3kwnGH6POQb4dGwCwJ8yOGqPSBQks5q6rmDgaJpZM4F4LbW
.

@durka Alors quel serait l'équivalent du .. actuel, où il n'y a pas de a ou b ? Juste : ?

Quelque chose que je n'ai pas vu noté dans la RFC : des noms différents ont-ils été pris en compte pour les champs ?

S'il existe différents types, il peut être utile d'avoir des noms de champ différents lorsqu'ils ont des significations différentes. Par exemple, "range.start" est "la limite inclusive inférieure" sur tous les types. Mais "range.end" est parfois inclusif et parfois exclusif. Une distinction entre « fin » et (de l'homme de paille) « dernier » rend cela plus clair.

(Ceci est bien entendu sans importance si les différents types sont abandonnés au profit de Range>...)

Je pense que la plage inclusive devrait toujours implémenter std::collections::range::RangeArgument.

pub trait RangeArgument<T> {
    fn start(&self) -> Option<&T> { ... }
    fn end(&self) -> Option<&T> { ... }
}

Puis

impl RangeArgument<T> for RangeToInclusive<T> {
   fn end(&self) {
     Some(self.end+1)
   }
}

Ainsi, fn foo<T, R: RangeArgument<T>>(arg: R) peut prendre des plages inclusives ou semi-ouvertes.

@durka Le problème avec la syntaxe a:b est qu'elle est ambiguë avec l'attribution de type. Demandez-vous une variable b , ou un type b ? Évidemment, en tant que bons programmeurs Rust, nous capitalisons nos types, mais le compilateur ne peut pas en déduire cela.

.. opérateur avec définitions mathématiques (basé sur le commentaire @duesee ) :

[1..4] // 1, 2, 3, 4
[1..4[ // 1, 2, 3
]1..4] // 2, 3, 4
]1..4[ // 2, 3

Utilisation (basée sur l'exemple @0tt ) :

fn fizzbuzz_to(n: u32) {
    for n in [1..n + 1] {
        fizzbuzz(n);
    }
}

Dans ce cas, nous utilisons .. juste comme indice, mais les limites sont données par [ et ]

@adelarsq : Dans Rust, nous n'avons pas besoin de plages qui n'incluent pas le début. Mais la syntaxe des crochets n'a de sens que lorsque ceux-ci sont autorisés. De plus, la syntaxe des crochets est déjà utilisée.

Je pense que ..= est le choix le plus raisonnable pour les gammes inclusives.
Facile à distinguer visuellement de .. , ce que ... n'est pas. La chance de taper ... en signifiant .. ou vice versa et de ne pas le remarquer est plus élevée qu'avec ..= .
(C'est comparable à taper accidentellement if(a = b) au lieu de if(a == b) en C, à la fois en termes de visibilité visuelle et de potentiel de bogue).
Et ..= est facile à mémoriser car il est symbolique pour sa signification ( i ..= j signifie la plage i .. j et où i = j ).

Il semble que la principale plainte est que ... est trop similaire à .. . J'ai remarqué que lorsque d'autres suggestions sont faites qui impliquent plus de caractères, personne ne se plaint du nombre de caractères, seulement des choses comme la correspondance des crochets et l'utilisation à certains endroits.
Alors, qu'en est-il des .... pour les plages inclusives ? Cela devrait toujours ressembler à une plage, et comme je l'ai dit, personne ne semble se soucier d'une solution qui prend un caractère supplémentaire. On peut se demander si c'est plus ou moins bancal que ..= .
for i in 0....10 { println!("just a thought"); }

Si le comportement par défaut était inclusif, le ..! opérateur serait utilisé (presque comme une négation).

Le problème avec .... est qu'il y aurait une certaine confusion si ... existe vraiment.

Je n'aime vraiment pas non plus ... , car c'est exactement l'inverse de Ruby .

La meilleure option jusqu'à présent est ..= je pense.

@adelarsq , l'opérateur .... remplacerait l'opérateur ... , donc si vous essayiez de faire .. et que vous ajoutiez un . supplémentaire, ce serait une compilation erreur de temps, si vous avez essayé de faire .... et avez oublié un point, ce serait également une erreur.

Étant donné que dans la correspondance de modèle, ... est utilisé pour faire correspondre la plage inclusive, il est donc logique d'utiliser également ... pour l'expression de plage inclusive.
Pour la plage avec pas, je préfère la syntaxe Haskell, par exemple 1,3..9 => [1,3,5,7]

Pour les plages avec pas/retour, etc. Je préférerais une bonne fonction à l'ancienne (une sorte de constructeur Range ) au lieu d'un littéral complexe.

Je serais d'accord avec le quad-dot .... (bien que ..= soit aussi bien à mon humble avis). Cela pourrait également être autorisé dans la correspondance de modèles pour des raisons de cohérence (et éventuellement, ... dans les modèles pourraient être dépréciés).

Pour moi ..= comme une signification visuelle que .... n'a pas.

Je viens de remarquer quelque chose :

En mathématiques, vous pourriez écrire ∀ i: 0 ≤ i < 10 qui se traduirait par

for i in 0 ..< 10 { }

C'est cohérent.

Cependant, la déclaration ∀ i: 0 ≤ i ≤ 10 se traduirait par

for i in 0 ..= 10 { }

Ici, ≤ se traduit par =, ce qui semble incohérent.

C'est peut-être du bikeshedding, mais

for x in 0 ..<= 10 { }

se sent plus correct. Cela peut être dû à mon expérience en C où

for (unsigned int i = 0; i <= 10; ++i) { }

se traduit par "tant que i est inférieur ou égal à 10 faire quelque chose". En CI, préférez ne pas utiliser == dans des conditions de boucle, en raison de la possibilité de sauter par-dessus la valeur et de se retrouver dans une boucle infinie. Cela ne peut pas arriver dans Rust, mais traduire for i in 1 ..= 10 en C pourrait suggérer exactement cela.

En allant plus loin,

for i in 0 <..<= 10 { }

serait explicite.

Edit: voici un mauvais exemple inversé destiné à montrer comment utiliser seulement = peut être déroutant. Supprimé, car il était plus confus que constructif.

@duesee Comment >=..> -il explicite ? Ne devrait-il pas être <=..> (<= 10 et > 0) ?
OMI, ce n'est pas explicite, c'est cryptique et trop long en tant qu'opérateur.
(Aucun opérateur ne doit être plus long que 3 caractères IMO).
Au fait, nous avons déjà un moyen d'exprimer le sens d'itération inverse : .rev()
Nous n'avons besoin que d'opérateurs pour les plages inclusives et peut-être de .step_by() .
Pour l'étape, la syntaxe pourrait être a .. b | s (et pour les plages inclusives : a ..= b | s ).

@norru : Votre exemple for i in (1..l.len()).rev() { ... } est très irréaliste, car la plupart du temps vous utiliseriez des tranches ( for x in arr[1..].rev() { ... } ), mais même si vous êtes obligé d'utiliser le style index de l'itération (essentiellement seulement lorsque vous modifiez des éléments de tableau qui ne sont pas à i ), je ne trouve pas du tout difficile à lire. (Mais je laisse généralement des espaces autour de .. lorsque les arguments ne sont pas des nombres littéraux : (1 .. arr.len()).rev() )

>=..> plus d'espèces de poissons dans les opérateurs de Rust !

Mais j'aime beaucoup ..<= (edit: euhh, sauf dans match où ça ressemble à <= 0 => :()

  • Il est très différent du simple .. ,
  • il n'a pas la connotation += de ..= ,
  • c'est logiquement cohérent même avec le ..< Swift. Il est possible que les deux langues convergent !
  • et plus important encore, il est assez clair que vous obtenez des nombres dans la plage inférieurs ou égaux à la valeur supérieure.

@pornel : >=..> more species of fish in Rust operators! Héhé :-)

@Boscop : cela se passe d'explications si vous le lisez comme une définition mathématique : 10 >= i > 2 . Pour le reste de votre réponse : je suis tout à fait d'accord. La deuxième partie était conçue comme une motivation pour repenser ..= vs ..<= afin de ne pas introduire de bloqueurs pour les extensions futures. Je modifierai ma réponse en conséquence.

peut également obtenir un indicateur d'avertissement ou d'erreur sur la notation ..

Je ne veux pas que .. apparaisse n'importe où dans ma base de code

Je voudrais mettre un autre vote pour ..=

L'inconvénient de ..< et ..<= est qu'ils sont déjà du code valide (une plage exclusive ouverte à droite est comparée à une autre valeur).

@thepowersgang

L'inconvénient de ..< et ..<= est qu'ils sont déjà du code valide (une plage exclusive ouverte à droite est comparée à une autre valeur).

bien que cela soit vrai, il semble peu probable que cela pose un problème dans la pratique, non ?

Je préfère largement ... aux autres suggestions ici .. mais si je devais choisir une syntaxe alternative, ce serait ..=

@nikomatsakis

Je suis contre les options ..< et ..<= uniquement au motif qu'elles compliquent de manière disproportionnée le processus d'acquisition d'un modèle intuitif de la grammaire de la langue.

Sur une note plus personnelle, je les trouve au moins aussi laids et inélégants que le turbofish.

J'opterais pour .. pour droit-exclusif et ..= pour inclusif comme le meilleur équilibre entre l'élégance visuelle, des règles de grammaire faciles à saisir intuitivement et rendant les deux difficiles à confondre.

Est-ce que ... vraiment si différent de .. ? Pourquoi je l'aime tant ?

@tshepang

J'aime ... parce que c'est esthétiquement attrayant... mais je m'y oppose parce que je crains qu'il puisse potentiellement causer des bogues difficiles à remarquer, similaires à l'écriture de if (x = 2) { plutôt que de if (x == 2) { en C/C++. (Et il est bien établi quel danger cela s'est avéré être.)

@ssokolow

OMI qui est mieux résolu par des drapeaux linting ou d'option. Je ne vois pas beaucoup d'utilité pour mélanger des notations dans un seul fichier/projet.

Préférez également .... aux autres options, le fait d'avoir le double de la largeur/de l'espacement devrait le rendre suffisamment évident, d'autant plus qu'ils seront flanqués des deux côtés de symboles qui rendront cet espace négatif plus prononcé que isolément.

@ssokolow

J'opterais pour .. pour right-exclusive et ..= pour inclusive comme le meilleur équilibre entre l'élégance visuelle, des règles de grammaire faciles à saisir intuitivement et rendant les deux difficiles à confondre.

Ça marche pour moi. Le principal point d'achoppement est de savoir si nous voulons également une syntaxe pour d'autres cas (par exemple, <..<= ). Personnellement, je pense que .. et ..= couvrent drain , et nous avons actuellement adopté une approche distincte là-bas .

cc @rust-lang/libs

On peut laisser les cas rares à la construction directe des plages en utilisant
struct littéraux.

Le mercredi 22 février 2017 à 16h50, Niko Matsakis [email protected]
a écrit:

@ssokolow https://github.com/ssokolow

J'irais avec .. pour droit exclusif et ..= pour inclus comme meilleur
équilibre entre élégance visuelle, règles de grammaire faciles à comprendre intuitivement
saisir, et rendant les deux difficiles à confondre.

Ça marche pour moi. Le principal point d'achoppement est de savoir si nous voulons également un
syntaxe pour les autres cas (par exemple, <..<=). Personnellement, je pense que .. et ..=
couvre comme 99,5% des cas. Je pense que le principal cas d'utilisation est celui des API comme drain,
et nous avons actuellement adopté une approche distincte là-bas
https://doc.rust-lang.org/std/collections/struct.BTreeMap.html#method.range
.

cc @rust-lang/libs https://github.com/orgs/rust-lang/teams/libs

-
Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/rust-lang/rust/issues/28237#issuecomment-281815665 ,
ou couper le fil
https://github.com/notifications/unsubscribe-auth/AAC3n-aKwYKFq4VI9RizL0GkzXXSjTPwks5rfK2ngaJpZM4F4LbW
.

Je suppose que ..= sera également disponible dans les modèles ? Que deviendra la syntaxe ... existante là-bas ?

Il peut être obsolète. Mais son existence est un précédent assez solide pour
l'utiliser, au moins comme un raccourci.

Le mercredi 22 février 2017 à 18h02, andrewtj [email protected] a écrit :

Je suppose que ..= sera également disponible dans les modèles ? Que va-t-il devenir
la syntaxe existante ... là-bas?

-
Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/rust-lang/rust/issues/28237#issuecomment-281834007 ,
ou couper le fil
https://github.com/notifications/unsubscribe-auth/AAC3nw_DaOMNxuIKw6ZFfXJW95QyijY4ks5rfL6DgaJpZM4F4LbW
.

@durka @andrewtj Je suppose que nous le déprécierions.

..= peut être utilisé comme opérateur dans le même sens que += .
Je suggère d'utiliser la marée ~ , par exemple 0~9 , 'A'~'Z' .

À quelle opération ..= correspondrait-il ? - n'est évidemment pas viable car
1-9 == -8 .

Le mer. 22 février 2017 à 20h04, Junfeng Liu [email protected]
a écrit:

..= peut être utilisé comme opérateur dans le même sens que +=.
Je suggère d'utiliser ~, par exemple 0~9, 'A'~'Z'.

-
Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/rust-lang/rust/issues/28237#issuecomment-281856846 ,
ou couper le fil
https://github.com/notifications/unsubscribe-auth/AAC3n7N2dM4DAzc_uc5JdHit4IJgyvYGks5rfNsPgaJpZM4F4LbW
.

@durka ..= ressemblent à des opérateurs d'affectation, le cas d'utilisation doit être rare. ~ est la marée pas sous. Utiliser ... est également ok.

impl Fill for Range<String> {
   fn fill() -> String { ... }
}
impl FillAsign for RangeAssign<String> {
   fn fill(&mut self) { ... }
}
(String::new("abc") .. String::new("f")).fill()  // "abcdef"
(String::new("abc") ..= String::new("f")).fill()  //  ()

Oh désolé, c'est pareil dans ma police. Je demandais si ..= est un composé
opérateur d'affectation comme +=, quelle opération effectue-t-il (correspondant
à +) ?

Le mer. 22 février 2017 à 20h29, Junfeng Liu [email protected]
a écrit:

@durka https://github.com/durka ..= ressemble juste à une affectation
opérateurs, le cas d'utilisation doit être rare. ~ est la marée pas sous.

impl Remplir pour la plage{
fn fill() -> Chaîne { ... }
}
impl FillAsign pour RangeAssign{
fn fill(&mut self) { ... }
}
(String::new("abc") .. String::new("f")).fill() // "abcdef"
(String::new("abc") ..= String::new("f")).fill() // ()

-
Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/rust-lang/rust/issues/28237#issuecomment-281861478 ,
ou couper le fil
https://github.com/notifications/unsubscribe-auth/AAC3n39uqbADB1rNtBh3PBTRY2XBXOUNks5rfOD-gaJpZM4F4LbW
.

@durka @nikomatsakis d' accord, eh bien, j'espère que cela sera bientôt résolu. La situation actuelle est délicate et le changement de syntaxe le sera aussi.

@pornel Déprécier ... dans match briserait la compatibilité, ce n'est donc pas une bonne solution. Je trouve toujours que ... le plus adéquat (cependant c'est l'inverse exact de Ruby, mais aucun problème similaire n'est discuté par les Rubyists).

@hyst329 mais ... peut être plus sujet aux erreurs, car en manquer ou en ajouter un . donnera une nouvelle signification

La dépréciation ne casse pas les choses. L'ancienne syntaxe devra être prise en charge pour toujours pour les programmes existants, mais les utilisateurs peuvent être orientés vers la nouvelle syntaxe via la documentation et rustfmt.

mais les utilisateurs peuvent être orientés vers la nouvelle syntaxe via la documentation et rustfmt.

Je déconseille fortement d'utiliser rustfmt pour cela. Cela exacerberait les qualités de footgun de ... lorsqu'il est utilisé en mode "appliquer automatiquement les modifications", car cela pourrait traduire silencieusement les fautes de frappe en des choses qui semblent beaucoup plus utiles. (Les rendant ainsi plus faciles à ignorer lors d'un examen ultérieur.)

Un avertissement du compilateur dans la veine de « veuillez vérifier ce que vous vouliez dire et utilisez soit .. soit ..= » qui ne peut pas être corrigé automatiquement serait beaucoup plus conforme aux efforts existants pour minimiser le risque d'erreur humaine.

Veuillez noter que je parlais dans le contexte des ... existants dans les modèles, où aucune arme à pied n'existe. Actuellement, Rust est dans une situation temporaire sans armes à pied où les modèles n'autorisent que ... et les expressions n'autorisent que .. , donc les deux sont à l'abri des fautes de frappe.

Bien sûr, je ne recommanderais pas de convertir ... dans les expressions en ..= , car cela ne ferait bien sûr que rendre la faute de frappe permanente.

Ahhh. J'avais oublié ça. Merci de me le rappeler.

@adelarsq En fait, des erreurs courantes comme 'a'..'z' ou 128u8..255u8 peuvent être facilement intégrées dans cargo-clippy tant qu'avertissements, par exemple. Et aussi, la largeur de .. et ... est clairement différente (lorsque vous utilisez une police à espacement fixe, bien sûr ; ne pas l'utiliser est généralement une mauvaise idée pour écrire du code source en général - pas seulement Rust) .

Nous pourrions simplement faire en sorte que la syntaxe soit (ellipses horizontales unicode) au lieu de ... cette façon, au moins personne ne le taperait par accident.

Edit : oh personne ne prenait cette suggestion au sérieux :cry: Désolé pour le bruit.

Je ne sais pas, la dernière fois que j'ai vérifié, Google Docs convertit automatiquement ... en points de suspension. Acteur majeur dans l'industrie de l'édition de texte.

De plus, tout le monde ne dispose pas d'une touche Compose pour saisir facilement Compose . . quand ils ne veulent

Sous Windows, je peux taper des points de suspension en utilisant Alt + 0133 avec le pavé numérique !

Et des mécanismes similaires basés sur les points de code existent à différentes couches de la pile sur les bureaux basés sur X11 (je me souviens que GTK + et la pile d'entrée X11 ont leurs propres solutions indépendantes), mais c'est un problème majeur de se souvenir des points de code par numéro.

Compose est une solution èŕÿ intuitive.

La seule séquence Windows Alt dont je me souviens est Alt + 219 de tous les menus de fichiers DOS Batch que j'ai créés quand j'étais enfant.

La syntaxe actuelle existe déjà depuis longtemps, stabilisons-la déjà et arrêtons ce bikeshedding sans fin.

Conserver la syntaxe actuelle est le pire que nous puissions faire car cela présente de nombreux inconvénients réels . Il ne s'agit pas seulement de faire du vélo, cela doit être bien fait. En sautant tout le fil, la syntaxe ..= été la plus acceptée jusqu'à présent...

J'ai un peu l'impression que c'est battre un cheval mort à ce stade, mais quand on y pense... La différence entre .. et ... est littéralement une copie du plus petit personnage possible que vous peut taper ou lire, mélangé à un groupe de caractères identiques, et a le potentiel de créer une classe d'erreurs extrêmement courante et souvent irritante et difficile à trouver (erreurs un par un) dans des cas qui sont par ailleurs complètement indiscernables à la fois à l'homme et à la machine.

Ou nous pourrions faire littéralement n'importe quelle autre syntaxe dans le monde.

D'une part, j'apprécie cette préoccupation. D'autre part, la syntaxe actuelle de correspondance de modèle ... est déjà inclusive, ce qui la rend parfaitement cohérente avec la syntaxe déjà utilisée ailleurs dans Rust.

Et personnellement, je n'ai aucun problème à reconnaître la différence, même si je reconnais que les personnes ayant des problèmes de vision, ou avec un moniteur 4k et une police 10pt, pourraient le faire.

Mais il semble que le consensus soit sur ..= et je suppose que ça me va aussi.

FWIW, j'ai eu cette situation où j'ai accidentellement tapé ... quand je voulais dire .. et puis je n'ai pas remarqué pendant un moment, mais après un moment je me suis demandé pourquoi mon programme se comportait étrangement.
Alors oui, il devrait y avoir une différence plus visible, et ..= le plus de sens.

Nomination pour la discussion @rust-lang/lang. Je pense que nous devrions simplement adopter ..= et l'appeler un jour. Avons-nous besoin d'une RFC modifiée ? Fais-le? Cela implique-t-il de déprécier la syntaxe ... existante dans les modèles ? (Je suppose que oui.)

Je suis fortement en faveur de ne pas utiliser ... pour les plages. Je ne sais pas si cela a déjà été mentionné dans ce fil ou dans le fil RFC, mais en plus du fait que ... ressemble de manière déraisonnable à .. , nous pouvons également utiliser ... dans le futur pour les génériques variadiques, qui sont bien plus importants que les gammes inclusives IMO.

..= semble clair, et sa laideur relative est justifiée en étant moins courante que .. .

Cela implique-t-il de déprécier la syntaxe... existante dans les modèles ? (Je suppose que oui.)

Cela semble être une bonne idée. Avertir sur ... et prendre en charge à la fois .. et ..= dans les modèles si nous le pouvons.

Je me méfie généralement de l'introduction d'avertissements qui affecteraient autant de personnes sans avoir également un outil automatisé pour mettre à jour la syntaxe, mais ... à ..= est un changement particulièrement simple. Nous pourrions également déprécier mais retarder le fait d'en faire un avertissement jusqu'à ce que nous disposions d'un tel outil. Que pensent tous les autres?

Je suis fortement en faveur de ... car c'est une syntaxe plus "habituelle" ; Je ne connais aucun langage qui utilise ..= , mais beaucoup utilisent .. et ... .

Si le sentiment contre ..= est fort, je préférerais opter pour une syntaxe sans plage inclusive (au lieu d'opter pour une méthode (a..b).inclusive() , qui me semble assez concise) pour éviter le problème visuel et encore une fois gratuit jusqu'à ... pour les génériques variadiques.

EDIT : Un bon argument contre (a..b).inclusive() est que nous aurons toujours ... dans match et aucune nouvelle syntaxe pour le remplacer, malheureusement. :embrouillé:

@steveklabnik Désolé si cela est déjà mentionné quelque part dans ce fil (très long), mais : quelles autres langues utilisent à la fois .. et ... pour les plages exclusives et inclusives, respectivement ?

Rust a l'habitude d'adopter des fonctionnalités et une syntaxe utiles d'autres langages, mais de manière sélective , et de rejeter ou d'adapter les choses le cas échéant.

@joshtriplett Ruby utilise les deux, mais avec des significations opposées ( .. est inclusif, ... est exclusif). Je ne crois pas que c'était une bonne idée dans Ruby, et cela semble encore plus déroutant pour nous d'avoir les deux, mais à l'envers.

@joshtriplett celui que je connais le mieux est Ruby; Je pensais que ça venait de Perl mais je n'en suis pas tout à fait sûr. Je suis plus d'accord avec la sémantique à l'envers de Ruby qu'avec ..= .

Honnêtement, je préférerais une syntaxe de plage inclusive stable à toute autre chose, et je reconnais que mon aversion intense pour ..= est une chose personnelle, sur laquelle les personnes raisonnables peuvent être en désaccord.

@steveklabnik Swift utilise ..< , je pense, non? Ce qui semble similaire à ..= mais pire, en ce sens qu'il optimise pour (imo) le mauvais cas. =)

Swift utilise ..< pour exclusif et ... pour inclus (leurs termes sont
"demi-ouvert" et "fermé").

J'aime toujours ..< (avec .. comme raccourci) et ..=.

Mais une autre question ouverte (peut-être pas dans le cadre de ce problème de suivi) est de savoir si nous adoptons "juste" une syntaxe pour les plages fermées, ou aussi des syntaxes (syntaxen?) >..=.

Le jeu. 16 mars 2017 à 14:19, Niko Matsakis [email protected]
a écrit:

@steveklabnik https://github.com/steveklabnik Swift utilise ..<, je pense,
à droite? Ce qui semble similaire à ..= mais pire, en ce sens qu'il optimise pour
(imo) le mauvais cas. =)

-
Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/rust-lang/rust/issues/28237#issuecomment-287147321 ,
ou couper le fil
https://github.com/notifications/unsubscribe-auth/AAC3n0Wop5fJh9HVo7pSqo0riHm96Gm4ks5rmX1BgaJpZM4F4LbW
.

Cela ne me dérangerait pas d'avoir une fonction inclusive dans le prélude :

for x in inclusive(1..10) {

}

Je n'ai jamais pensé que la symétrie avec le match est un argument convaincant. Je pense que nous avons décidé d'ajouter des motifs exclusifs .. , mais je n'aime pas ceux-ci non plus - une valeur dans le motif n'est plus associée au motif ! Faire correspondre une plage est fondamentalement différent de l'itération à travers une plage, il n'y a aucune raison qu'ils doivent être symétriques. J'aurais une légère préférence pour ne pas autoriser .. dans les modèles si c'est toujours une option, mais je pense que non ?

Je pense que les inconvénients avec ..= et ... sont tous les deux importants - ..= est assez étrange, mais ... augmente la probabilité d'erreurs de 1.

Il est préférable d'avoir un opérateur étrange plutôt qu'un potentiel de bogues sans fin (chaque langage introduit des opérateurs que d'autres n'ont pas, par exemple ..< dans Swift, toutes les opérations dans F# et Scala). Les gens devront lire le livre Rust de toute façon.
Étant donné que beaucoup de gens viennent de Ruby pour Rust, nous ne devrions pas l'avoir à l'envers par rapport à Ruby. (En plus de l'argument selon lequel ... augmente la probabilité d'erreurs de 1.)
Comment pouvez-vous accepter ..< dans Swift mais ne pas accepter ..= dans Rust ? ..= n'est pas si étrange.

L'extension de la syntaxe de plage dans les modèles est toujours une question ouverte, autant que je sache.
D'une part, nous ne pouvons pas le faire complètement, car Enum::Variant(..) est déjà
valide et le changer pour signifier que Enum::Variant(RangeFull) serait en rupture.

Le jeu. 16 mars 2017 à 15h07, Boscop [email protected] a écrit :

Il est préférable d'avoir un opérateur étrange (chaque langage introduit
opérateurs que les autres n'ont pas, par exemple ..< dans Swift, toutes les opérations en F#
et Scala). Les gens devront lire le livre Rust de toute façon.
Étant donné que beaucoup de gens viennent de Ruby à Rust, nous
ne devrait pas l'avoir à l'envers par rapport à Ruby. (En plus de l'argument
cela ... augmente la probabilité d'erreurs de 1 erreur.)
Comment pouvez-vous accepter ..< dans Swift mais ne pas accepter ..= dans Rust ?

-
Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/rust-lang/rust/issues/28237#issuecomment-287160485 ,
ou couper le fil
https://github.com/notifications/unsubscribe-auth/AAC3nz9ZNR2utl7LPTVvQPQ_Ma8sDBGuks5rmYhmgaJpZM4F4LbW
.

Alors. Je veux pouvoir taper des trucs comme slice.get(10...30) et manger mon gâteau aussi.

Je me suis convaincu que je préfère fortement inclusive(0..10) à l'une des autres syntaxes :

  • Alors que @nagisa veut écrire slice.get(10...30) , je ne veux pas avoir à faire très attention à savoir si c'est slice.get(10...30) ou slice.get(10..30) . Je pense que la proximité de la syntaxe est un vrai problème.
  • Je pense que tout le monde convient que ..= n'est pas esthétique et probablement peu intuitif.
  • (0..10).inclusive() est la même syntaxe mais moins pratique. Techniquement, inclusive prelude supporterait probablement les deux syntaxes.

Je pense que ça ressemblerait à ça :

trait IntoInclusive {
    type Inclusive;
    fn inclusive(self) -> Self::Inclusive;
}

fn inclusive<T: IntoInclusive>(range: T) -> T::IntoInclusive {
    range.inclusive()
}

Je pense que tout le monde est d'accord ..= est inesthétique et probablement peu intuitif.

Je pense que dire cela est un peu une généralisation excessive. Je trouve que ..= est plus esthétique et intuitif qu'une méthode comme inclusive() .

(De plus, nous ne savons pas dans quelle mesure l'aversion pour ..= pourrait être des efforts inconscients (ou conscients) pour trouver des problèmes avec des choses qui ne sont pas ... .)

.inclusive() est trop long pour quelque chose qui se produit si fréquemment (sur cette note, je pense aussi qu'il devrait y avoir une forme plus courte pour .enumerate() ).
Mais même si nous avions .inclusive() , il ne devrait y avoir qu'une seule fonction, pas deux.
De plus, ne pas avoir de syntaxe de plage inclusive ne permettrait pas leur utilisation dans match .
Mais peut-être avons-nous besoin d'un moyen de spécifier les extracteurs de manière générale, comme en Scala ? Pour que n'importe quel type puisse être utilisé dans une correspondance, cette correspondance appellera implicitement sa méthode unapply .

(De plus, nous ne savons pas dans quelle mesure l'aversion pour ..= pourrait être des efforts inconscients (ou conscients) pour trouver des problèmes avec des choses qui ne le sont pas ....)

Aucun de moi. C'est une sorte d'accusation de mauvaise foi.

De plus, ne pas avoir de syntaxe de plage inclusive ne leur permettrait pas d'être utilisés dans la correspondance.

Les modèles de plage inclusifs sont déjà pris en charge dans match . En fait, ils sont le seul type de gamme que nous prenons en charge en tant que modèles aujourd'hui.

@withoutboats ouais mais j'ai dit "ne pas avoir de syntaxe de plage inclusive ne leur permettrait pas d'être utilisés dans le match". À l'heure actuelle, il existe une syntaxe, mais mon argument était contre .inclusive() car il ne pouvait pas être utilisé dans un match à moins d'avoir des extracteurs comme Scala. et tout l'intérêt de ce problème est que la syntaxe de plage inclusive ne devrait pas être un cas spécial qui ne fonctionne qu'en correspondance et pour déterminer quelle syntaxe devrait être au lieu de la syntaxe actuelle.

Inclus : for i in 1..10! { }

En tant que personne qui travaille depuis plus de 15 ans avec Java/C/C++, je trouve que .. vs ... est assez déroutant et peut causer des bogues simplement en tapant des erreurs. De plus, la relation avec Ruby rend cela encore plus confus. C'est pourquoi ..= ou toute autre alternative est préférable.

jeter mon 'chapeau' dans le ring :

for i in 1..10^

Le chapeau/caret symbolisant que la bonne valeur va jusqu'au bout.

@leebenson Personnellement, je pense que ce serait mieux si c'était au milieu, pas cloué à l'extérieur.

for i in 1..^10

@ retep998 J'ai pensé qu'après avoir

@retep998 J'aime votre suggestion de ..^ bien mieux que ..= ; il semble beaucoup plus évocateur de sa signification, et il évite de ressembler à une étrange variante d'un opérateur d'affectation augmenté (comme += et *= ). Cela dit, l'un ou l'autre serait bien meilleur que ... .

Je ne peux pas me remettre de ..^ .

Sur le plan personnel, je trouve cela très moche (en partie parce que le .. est si verticalement disjoint du ^ dans de nombreuses polices).

En tant que gars UI/UX, je pense que c'est un exemple d'être trop intelligent pour votre propre bien.

Si je viens d'une autre langue et que je vois ..^ , il se peut que je ne le reconnaisse même pas comme une plage (pour autant que je sache, 5..^15 pourrait être un étrange raccourci factoriel partiel pour 15! - 4! ) parce que les humains pensent dans des contextes et la seule association que ce personnage a dans un contexte de programmation grand public est l'exponentiation.

(Si nous ne réfléchissions pas aux contextes, ... pourrait signifier quelque chose comme « un rappel est inséré ici » ou « émettre un événement » par analogie à son « contenu omis »-sens similaire dans le dialogue dans l'écriture en prose, juste pour montrez l'exemple le plus immédiat. Lui donner un sens "monte jusqu'au bout" via sa ressemblance avec une flèche, c'est comme faire des tours de magie via un tour de passe-passe, dans la mesure où il interagit avec les attentes d'un nouveau venu.)

En revanche, = a un précédent pour faire référence à la fois à l'action d'affectation et au concept d'égalité et il n'y a pas de "syntaxe d'exponentiation étrange" - comme une idée fausse pour ..= parce que le plus proche que vous pouvez obtenir " affectation + égalité" qui n'est pas déjà gérée par l'opérateur d'affectation est "quelque chose à voir avec une séquence de nombres, se terminant par celui de droite"... qui est une définition vague mais appropriée de ce que fait la syntaxe de plage.

Je crains également que, même si je reconnaissais que ..^ était une syntaxe de plage à partir de son utilisation dans le contexte, je n'aurais aucune idée intuitive s'il était inclusif ou exclusif au début, car il n'y a aucune signification pour le ^ dans le contexte pertinent, à l'exception de la possibilité que 2..^8 soit un raccourci pour une plage ouverte commençant à deux et progressant en prenant le pas précédent à la puissance 8. (c'est-à-dire 2..Inf^8 par opposition à 2..+8 étant un raccourci pour "itérer de 2 à l'infini par pas de 8".)

Ce problème est également évité par ..= parce que les gens sont habitués à penser en termes de < (exclusif) contre <= (inclus) lorsqu'ils écrivent des boucles while et des boucles for style C.

@ssokolow analyse légitime.

Personnellement, je peux soutenir soit ..= soit ..^ . La symbologie de l'un ou l'autre a un sens pour moi - c'est-à-dire "jusqu'à et égal à" ou simplement "jusqu'à", respectivement. Ils signifient tous les deux la même chose, à mon avis.

Ça va être difficile de trouver quelque chose qui satisfasse tout le monde, parce que nous apportons tous l'histoire d'autres langues et avec elle, une symbologie/un biais entaché. J'ai initialement ajouté le signe ^ _après_ le nombre, par exemple, car l'insertion avant avait l'impression de représenter un "pas" ou un exposant, alors qu'un suffixe laissait la plage intacte et en quelque sorte plus pure. Mais c'est juste moi.

Dans tous les cas, je préférerais une notation abrégée sous une forme ou une autre à un appel de fonction qui +1 implicitement la valeur de droite. Je suis d'accord avec les commentaires précédents selon lesquels il s'agit d'une syntaxe trop courante pour être déléguée à quelque chose qui ressemble à un appel de fonction. Cela ne me dérangerait même pas ... , mais d'accord, c'est probablement le bug = / == dans les nouveaux vêtements et lié à tirer quelqu'un dans le pied...

beaucoup de gens semblent détester activement ..= personne n'a dit quoi que ce soit de négatif
à propos de .... il a été simplement ignoré (sauf pour quelques pouces vers le haut) je
J'ai pensé que j'en reparlerais et que les gens y réfléchissent et donneraient un
raison de ne pas l'utiliser s'ils sont contre.

Je déteste même le mentionner parce que c'est juste plus de bruit, mais qu'en est-il .:
(point deux-points) pour inclus ? C'est 3 points mais 2 caractères, et je pense que le
la forme le distingue de ..

Le samedi 18 mars 2017 à 11h50, Lee Benson [email protected]
a écrit:

@ssokolow https://github.com/ssokolow analyse légitime.

Personnellement, je peux prendre du retard soit sur ..= soit sur ..^. La symbologie de l'une ou l'autre
a du sens pour moi - c'est-à-dire "jusqu'à et égal à" ou simplement "jusqu'à",
respectivement. Ils signifient tous les deux la même chose, à mon avis.

Ça va être difficile de trouver quelque chose qui satisfasse tout le monde,
parce que nous apportons tous l'histoire d'autres langues et avec elle, entachée
symbologie/biais. J'ai d'abord ajouté le signe ^ après le nombre, pour
exemple, car insérer avant avait le sentiment de représenter une 'étape'
ou exposant, alors qu'un suffixe laissait la plage intacte et en quelque sorte plus pure
sentiment. Mais c'est juste moi.

Dans tous les cas, je préférerais une notation abrégée sous une forme plutôt qu'une
appel de fonction qui +1 implicitement la valeur de droite. je suis d'accord avec tout à l'heure
commente qu'il s'agit d'une syntaxe trop courante pour être déléguée à quelque chose qui
ressemble à un appel de fonction. Cela ne me dérangerait même pas ..., mais d'accord, c'est
probablement le = / == bug dans les nouveaux vêtements et lié à tirer sur quelqu'un dans le
le pied...

-
Vous recevez ceci parce que vous avez commenté.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/rust-lang/rust/issues/28237#issuecomment-287566556 ,
ou couper le fil
https://github.com/notifications/unsubscribe-auth/AIhJ6jWgPwndKaQvVjULlV_OoC6WDO0Cks5rnCeLgaJpZM4F4LbW
.

Oh, est-ce encore dans une phase de bikeshedding ? ??

En relisant , je pense que je suis d'accord avec ..= et l'appeler un jour. La similarité de .. vs ... est trop subtile, et je préférerais que le jeton ... soit utilisé sans ambiguïté pour les génériques variadiques (https://github.com/ rust-lang/rfcs/pull/1935), où il remplit un objectif très distinct qui devrait conduire à moins de confusion entre les deux.

Je ne sais pas si le désir d'une syntaxe plus généralisée pour toutes les variantes semi-ouvertes est toujours là, mais je pense que cela ne vaut pas la peine de fournir une syntaxe de langage en dehors de .. et ..= .

Je déteste même le mentionner parce que c'est juste plus de bruit, mais qu'en est-il de .: (point deux-points) pour inclus ?

Je pense que @ssokolow a fait d'excellents points

Personnellement, je n'ai aucune objection à ce qu'il y ait un troisième point, à part le fait de savoir que cela finira par faire trébucher certaines personnes. Mais c'est aussi très facile à expliquer, donc je ne suis pas sûr qu'il incombe au langage de concevoir des solutions de contournement intelligentes. Est-ce que « 2 points est exclusif » ; 3 points inclus' vraiment _que_ difficile à saisir/déboguer ?

Dans tous les cas, qui prend la décision finale et quelle est la prochaine étape pour clore cela ? 18 mois à discuter du troisième personnage probablement _is_ bikeshedding à ce stade 😄

D'accord, ^ fait ressembler à une étape.
OMI, l'incohérence avec les autres opérateurs op= n'est pas un problème car il est impossible que nous ayons jamais a ..= b au sens de a = a .. b , puisque .. est pas un opérateur mais du sucre syntaxique pour construire un Range (et nous n'avons pas de schéma général de surcharge d'opérations où toute opération obtient automatiquement une forme de op= , et .. ).
Je ne dis pas que ..= est clair sans regarder la doc. Mais une fois que les gens ont regardé la doc, c'est plus facile à mémoriser, et ils devront quand même regarder la doc.

Compte tenu de la nomination de finirons par en discuter lors de la réunion de l'équipe

Je crains également que, même si je reconnaissais que ..^ était une syntaxe de plage à partir de son utilisation dans le contexte, je n'aurais aucune idée intuitive s'il était inclusif ou exclusif au début

D'accord. En fait, j'ai déjà vu cette syntaxe dans Perl 6 où cela signifie exclusif, à l'opposé de la proposition ici.

@solson C'est un argument très convaincant contre cela.

Perl semble avoir une syntaxe entièrement générale, avec .. signifiant inclus (sur les deux
côtés) et ^ de chaque côté rend cette limite exclusive.

Le sam. 18 mars 2017 à 18:51, Josh Triplett [email protected]
a écrit:

@solson https://github.com/solson C'est un argument très convaincant
encontre.

-
Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/rust-lang/rust/issues/28237#issuecomment-287580739 ,
ou couper le fil
https://github.com/notifications/unsubscribe-auth/AAC3n7Fnn1_t9BkYOhfS-7oCaGlVff2aks5rnF_5gaJpZM4F4LbW
.

Donc, je suis désolé de le dire, mais lorsque nous avons discuté de cette question lors de la réunion @rust-lang/lang, nous n'avons pas réussi à parvenir à un consensus. @withoutboats en particulier a de sérieuses réserves qu'ils peuvent, espérons-le, diffuser par eux-mêmes.

Quelques points importants dont nous avons discuté :

  • Si nous avons une syntaxe de plage inclusive dans les expressions et les modèles, cela devrait être le même

    • c'est-à-dire que si nous adoptons x ..= y , cela implique de déprécier la syntaxe de modèle x...y existante.

  • Une option tentante est de "ne rien faire" et d'écrire simplement (x..y).inclusive() ou quelque chose du genre. Cependant, cela ne fonctionnera pas dans les modèles (qui resteraient vraisemblablement x...y ). Cela soulève certaines questions en soi :

    • Voulons-nous toujours des modèles de gamme ? par exemple match 3 { 1..3 => false, .. }



      • Si c'est le cas, alors nous avons la même confusion potentielle !



    • @withoutboats semble penser que nous ne voulons peut-être pas de tels modèles. Moi-même et @joshtriplett doutions de cela; Je pense que nous avions tous les deux l'opinion qu'ils sont le genre de chose qui semble hors de propos jusqu'à ce que vous les vouliez, et ensuite ils se sentent absolument nécessaires . =)

  • Un autre problème concernant les modèles de plage exclusifs est qu'ils interagissent mal avec les modèles de tranche (également instables) (voir https://github.com/rust-lang/rust/issues/23121 pour plus de détails).

Je pense qu'une chose est ressortie de cette discussion , c'est qu'il serait bon de prendre une décision sur tous les facteurs conflictuels à la fois . Autrement dit, adopter une décision qui règle :

  • Que faire des expressions de plage exclusives ?
  • Devons-nous déprécier/modifier les modèles de gamme exclusifs existants ?
  • Que faire des modèles de gamme inclusifs ?
  • Que faire des motifs de tranches ?

Avant de commencer cet article, je tiens à dire que je me sentais très incertain qu'à chaque moment de la conversation, nous parlions tous du même concept. Par exemple, Niko dit que "les modèles de plage exclusifs semblent sans importance jusqu'à ce que vous les vouliez", mais je pensais que Niko et Josh parlaient d'expressions de plage inclusive à ce moment-là.

(Et je pense que dans la dernière partie du message de Niko, la première puce qui se lit actuellement "expressions de plage exclusives" devrait dire "expressions de plage inclusives".)

TL; DR mon avis

À propos des expressions de plage :

  • Nous ne devons introduire aucune syntaxe pour les expressions de plage inclusives - ni ... ni ..= .
  • Nous devrions ajouter au prélude une fonction qui prend une valeur de plage exclusive et renvoie une valeur de plage inclusive. Donc vous écririez inclusive(0..10) (le nom peut être bikeshedded).

À propos des modèles de plage :

  • Nous ne devons pas introduire de modèles de gamme exclusifs, ni aucun moyen d'en créer un.

En d'autres termes, le seul changement important que nous devrions faire est un changement de libs : ajouter une fonction au prélude.

Expressions de plage

Un élément fondamental de mon argument est le fait que l'itération à travers une valeur de plage inclusive est un besoin rare. Je pense que cela est corroboré par le fait que malgré l'acceptation de la RFC il y a 18 mois, nous n'avons toujours pas stabilisé cette fonctionnalité - pas à cause de problèmes de mise en œuvre mais parce que nous ne sommes pas satisfaits du compromis.

Je pense que les expressions de plage inclusives sont nécessaires assez souvent pour que nous puissions prendre en charge une manière simple de les créer, mais pas assez souvent pour qu'elles surmontent les inconvénients des syntaxes dont nous avons discuté jusqu'à présent.

En particulier, un inconvénient que chaque solution syntaxique a partagé est qu'aucune d'entre elles n'est vraiment auto-documentée. Il est relativement peu évident que 0...10 ou 0..=10 est une expression de plage inclusive . Comme ils seront rencontrés relativement peu fréquemment, ce sera une pierre d'achoppement pour les utilisateurs qui les rencontreront pour la première fois.

C'est-à-dire, si l'utilisateur remarque même qu'il n'a pas affaire à une plage "normale" .. . Bien sûr, c'est le gros problème avec ... , mais ..= n'élimine pas totalement le problème. Il est facile, en parcourant le code, de manquer ce caractère = (ou ^ ou : ou autre). Pas aussi facile que le . supplémentaire, mais je ne suis pas convaincu que ce soit assez perceptible.

Je pense en fait qu'il y a un compromis "notabilité vs évidence" entre ... et ..= . Je pense que c'est plus évident ce que signifie ... (à moins que vous ne veniez de Ruby, où les deux syntaxes ont le sens opposé) que ..= , mais c'est nettement moins visible .

Mais je pense qu'une fonction de prélude comme inclusive(0..10) est à la fois plus évidente et plus visible que n'importe quelle syntaxe dont nous avons discuté. Oui, c'est plus de caractères à taper, mais l'inconvénient de cet attribut est relatif à la fréquence d'utilisation.

Il évite également tous les problèmes d'analyse et de tokenisation et aide les utilisateurs à résoudre le problème (très ennuyeux) de priorité entre la plage et la méthode qui les oblige à écrire (0..10).filter et autres.

Modèles de gamme

La principale raison pour laquelle je pense que nous ne devrions pas ajouter .. est que cela introduit une ambiguïté autour des modèles de tranche, ce qui, à mon avis, est utile. J'aimerais résoudre ce problème en n'ayant pas à le résoudre.

La deuxième raison est que je pense qu'ils sont assez mauvais style (je sais que d'autres personnes ne sont pas d'accord). Par example:

if let 1..10 = x { .. }

Je pense que cela prête à confusion, car 10 ne correspond pas au modèle qui le contient. Niko a mentionné que ce n'est pas vraiment différent des expressions de plage exclusives ne donnant pas 10 , mais je pense que la grande différence est que nous avons beaucoup de précédents historiques de style Dijsktra (et cas d'utilisation) pour prendre en charge l'exclusivité gammes. En entrant dans Rust, je m'attendais à ce que les gammes itératives et de découpage soient exclusives, mais je n'avais pas cette attente pour les modèles.

Il a également le problème "off-by-one" que .. / ... dans les expressions a.

Je sais que Niko a mentionné qu'il aimerait écrire :

match x {
    0..10 => { ... }
    10..20 => { ... }
}

Mais je préférerais vraiment fortement voir :

match x {
    0...9 => { ... }
    10...19 => { .. }
}

Quoi qu'il en soit, j'ai été surpris que Niko ait voulu dire qu'il les trouve parfois "absolument nécessaires", donc j'aimerais entendre plus de contre-arguments. Puisqu'ils doivent être un constexpr, cela me semble beaucoup plus être une chose "agréable à avoir" qu'une chose "absolument nécessaire".

Je me sens définitivement plus facile à influencer sur des modèles de plage exclusifs que sur des expressions de plage inclusives.

L'argument de la cohérence

Niko a mentionné qu'avoir à la fois .. et ... dans les expressions et les modèles est important pour lui en raison de la cohérence. Je suis fondamentalement totalement insensible à cet argument. L'itération sur une plage et la correspondance sur une plage ne sont pas vraiment des opérations analogues, et il est logique qu'il y ait des différences entre la façon dont nous les traitons.

En effet, il n'y a même pas de connexion d'implémentation : 1..10 produit une valeur Range, alors que 1...10 correspond à une valeur entière. Ce n'est pas comme s'ils avaient une connexion structurante/déstructurante comme le font la plupart de nos syntaxes d'expression/motif symétriques.

Il semble techniquement plus correct d'appeler les modèles "modèles de domaine" que "modèles de plage" 🤓, ce qui met en évidence la non-analogie.

@sansbateaux

Par exemple, Niko dit que "les modèles de plage exclusifs semblent sans importance jusqu'à ce que vous les vouliez", mais je pensais que Niko et Josh parlaient d'expressions de plage inclusive à ce moment-là.

Pour ma part, j'ai trouvé à la fois des plages exclusives et inclusives nécessaires à divers moments (bien que j'aie utilisé exclusive pour les deux cas pour travailler sur Rust stable, et j'ai dû contourner cela avec un +1 dans la partie supérieure bondir). J'aimerais les avoir disponibles pour les modèles et les expressions.

Cela dit, personnellement, je n'aurais aucune objection à l'utilisation d'une fonction pour les plages inclusives, sauf que je veux avoir un moyen d'écrire à la fois des plages inclusives et exclusives dans des modèles , et j'aimerais que ces deux syntaxes ne se ressemblent pas au point de prêter à confusion comme le font .. et ... . Et étant donné une syntaxe pour écrire de telles plages dans des modèles, je ne sais pas s'il est logique d'avoir une syntaxe différente pour de telles plages dans des expressions.

En particulier, un inconvénient que chaque solution syntaxique a partagé est qu'aucune d'entre elles n'est vraiment auto-documentée. Il est relativement peu évident que 0...10 ou 0..=10 est une expression de plage inclusive. Comme ils seront rencontrés relativement peu fréquemment, ce sera une pierre d'achoppement pour les utilisateurs qui les rencontreront pour la première fois.

Je suis d'accord avec ça. Cela revient suffisamment rarement pour que je n'aie aucune objection à une syntaxe moins compacte. J'aimerais cependant avoir un mécanisme pour écrire des plages inclusives et exclusives dans les expressions et les modèles.

Cela ne me dérangerait pas, par exemple, si l'écriture d'un modèle de plage inclusif nécessitait une macro ou similaire.

@joshtriplett C'est là que je veux être très clair, quand vous dites ceci :

J'ai trouvé des plages exclusives et inclusives nécessaires à divers moments (bien que j'aie utilisé exclusif pour les deux cas pour travailler sur Rust stable et que j'ai dû contourner cela avec un +1 dans la limite supérieure).

Il semble clair que vous parlez d' expressions , mais la section que vous avez citée concernait les modèles (je sais que vous parlez de modèles dans votre prochain paragraphe, mais je pose la question de la "nécessité" que ce paragraphe n'aborde pas 😃) .

Le statu quo pour les modèles est que nous ne prenons en charge que les modèles de plage inclusifs, de la forme x...y . Pouvez-vous nous en dire plus si/quand vous avez trouvé des modèles de gamme exclusifs vraiment frustrants de ne pas avoir ?

@sansbateaux

Pouvez-vous nous en dire plus si/quand vous avez trouvé des modèles de gamme exclusifs vraiment frustrants de ne pas avoir ?

Quelque chose comme

    match offset {
        0x0200 .. 0x0280 => { /* GICD_ISPENDR<n> */ }
        0x0280 .. 0x0300 => { /* GICD_ICPENDR<n> */ }
        0x0300 .. 0x0380 => { /* GICD_ISACTIVER<n> */ }
        0x0380 .. 0x0400 => { /* GICD_ICACTIVER<n> */ }
        0x0400 .. 0x0800 => { /* GICD_IPRIORITYR<n> */ }
    }

vs

    match offset {
        0x0200 ... 0x027C => { /* GICD_ISPENDR<n> */ }
        0x0280 ... 0x02FC => { /* GICD_ICPENDR<n> */ }
        0x0300 ... 0x037C => { /* GICD_ISACTIVER<n> */ }
        0x0380 ... 0x03FC => { /* GICD_ICACTIVER<n> */ }
        0x0400 ... 0x07FC => { /* GICD_IPRIORITYR<n> */ }
    }

Je ne dirais pas que c'est particulièrement frustrant, mais le premier est certainement plus joli.

@withoutboats Pour plus de clarté, à plusieurs reprises, j'ai voulu des expressions de plage exclusives, des expressions de plage inclusives et des modèles de plage inclusive. Je ne peux pas penser à un moment où je me suis soucié profondément d'avoir des modèles de gamme exclusifs, même si je ne m'y opposerais pas non plus. Mais même si nous n'avons pas de modèles de plage exclusifs, je serais toujours très déroutant si les modèles de plage inclusifs utilisaient ... et les expressions de plage exclusives utilisaient .. .

@petrochenkov Je suppose que ceux-ci devaient se terminer par F , pas C ?

J'ai rencontré le même cas avec des modèles de plage hexadécimaux, par exemple 0x8000...0x9FFF => /* body */ . Je trouve que 0x8000..0xA000 a des propriétés un peu plus intuitives, comme sans avoir à y penser je vois tout de suite que la taille de la plage est de 0xA000 - 0x8000 = 0x2000 et que la prochaine plage adjacente commence à 0xA000 .

Traiter les +1 requis pour voir ces faits dans une plage inclusive est une petite différence avec laquelle je peux vivre, mais les plages exclusives (à la fois des modèles et des expressions) conviennent généralement mieux à mon travail.

@petrochenkov Je peux voir pourquoi vous préféreriez des plages exclusives pour les chiffres hexadécimaux (je ne le ferai peut-être toujours pas, mais cela ressemble à un accord très YMMV).

Comment traiterions-nous les ambiguïtés de la syntaxe des tranches ?

@joshtriplett

Je serais toujours très déroutant si les modèles de plage inclusifs utilisent ... et les expressions de plage exclusives utilisent .. .

C'est ainsi que fonctionne Rust aujourd'hui et cela ne semble pas être une source importante de confusion ?

@solson

Je suppose que ceux-ci étaient censés se terminer par F, pas C?

Non :)
(Ces choses sont en 32 bits et offset est un multiple de quatre.)

@sansbateaux

Je peux voir pourquoi vous préféreriez des plages exclusives pour les chiffres hexadécimaux (je ne le ferai peut-être toujours pas, mais cela ressemble à un accord très YMMV).

Je dois noter que ce n'est pas une préférence forte, je serais toujours d'accord pour abandonner à la fois les modèles exclusifs et les gammes inclusives (mais pas l'un d'entre eux, ce serait trop ridicule).

Comment traiterions-nous les ambiguïtés de la syntaxe des tranches ?

Facilement! PATTERN.. => .. @ PATTERN

Ma principale raison pour laquelle je veux que les plages inclusives soient simples est que je me suis retrouvé plus d'une fois dans des situations où je transmets une valeur d'arrêt dans une variable et c'est exactement la valeur maximale qu'un type de variable peut contenir, donc les seules solutions pour exclure le débordement au moment de la compilation sont :

  1. Utilisation d'une plage inclusive (la plus propre, mais pas stable)
  2. Upcasting avant le + 1 (en supposant que je ne suis pas déjà sur u64 et que ce soit inélégant)
  3. Prendre la valeur la plus faible et la valeur maximale moins un pour la plage, puis exécuter la tâche une fois de plus si nécessaire.

Prendre l'habitude d'utiliser des plages inclusives plutôt que d'ajouter + 1 à un algorithme où il n'a aucun objectif inhérent est un moyen non trivial de ne pas les rencontrer à nouveau plus tard dans cargo fuzz ... et en utilisant une fonction "make inclusive from exclusive" avec plus de caractères dans son nom que + 1 donne l'impression que les plages inclusives sont une chose exceptionnelle, plutôt que quelque chose que vous devriez utiliser habituellement.

C'est l'une des principales raisons pour lesquelles je suis contre. Cela donne l'impression que les plages inclusives sont un hack, à utiliser lorsqu'il est démontré que les plages exclusives ont échoué.

@ssokolow mais ce cas d'utilisation est confortablement couvert par une fonction de prélude. Personne ne soutient qu'il ne devrait pas être possible de créer des plages inclusives, juste s'ils devraient ou non avoir du sucre syntaxique pour les créer.

J'aime l'idée de @withoutboats d'une fonction de prélude. Je pense que l'autre endroit où les plages inclusives peuvent être plus courantes est lorsque vous n'utilisez pas d'entiers, par exemple en spécifiant les limites d'une recherche sur un btree (ou une structure de données similaire).

@withoutboats J'ai pas + 1 à une plage exclusive ), ressemble à un subtil découragement de ne pas les utiliser et à une possible arme à pied "Je te verrai dans cargo fuzz plus tard".

Si rien d'autre, c'est une verrue d'apprentissage.

Rust n'est pas Python 3.x, avec sa prise en charge d'entiers illimités. Rust ne cache pas les compromis matériels des utilisateurs, et je vois le ..= je préfère comme faisant simplement partie de l'utilisation de u32 et d'amis au lieu de int . (Surtout étant donné que les erreurs de débordement/sous-dépassement sont jusqu'à présent la chose la plus courante sur le « trophy case » de cargo fuzz .)

EDIT : Veuillez ignorer tous les éléments que vous ne voyez que dans les notifications par e-mail pour cela. Je viens de me réveiller et je ne tire pas encore sur tous les cylindres.

Je ne vois pas du tout inclusive(n..m) comme un découragement... Je préférerais l'écrire car c'est une construction très claire qui rend mon code plus facile à lire que n..(m + 1) et n..=m (que j'en suis venu à considérer comme inutilement bizarre alors que nous pourrions simplement dire le mot "inclusif").

n..=m est plus une verrue d'apprentissage que inclusive(n..m) IMO.

Je pense que pour le match, il y a un désir d'avoir une couverture complète de la plage numérique, plutôt qu'un type spécifique de motif.

Vraisemblablement, s'il y avait une syntaxe "continuer à partir du précédent", cela résoudrait également le problème.

BTW, puisque seul le premier motif correspond, le numéro de départ peut souvent être omis :

    match offset {
        0 ... 0x01FF => {}
        0 ... 0x027C => { /* GICD_ISPENDR<n> */ }
        0 ... 0x02FC => { /* GICD_ICPENDR<n> */ }
        0 ... 0x037C => { /* GICD_ISACTIVER<n> */ }
        0 ... 0x03FC => { /* GICD_ICACTIVER<n> */ }
        0 ... 0x07FC => { /* GICD_IPRIORITYR<n> */ }
    }

J'admets que cela peut être une question de point de vue, mais:

  1. Quand je vois .. et ..= , je me dis "Huh. Je me demande pourquoi ils ont deux syntaxes pour une si petite différence", ce qui m'amènerait alors à chercher des docs sur lesquels je pourrais me concentrer " 1..pivot et pivot..end " vs. " x..=yy peut être la valeur maximale possible".

  2. Avant d'avoir assez d'expérience pour penser habituellement en termes de tailles variables, j'aurais juste utilisé + 1 sur inclusive() (si j'allais même le chercher), parce que j'ai utilisé + 1 depuis l'école primaire, c'est court et facile à taper, et mon inexpérimenté est habitué à travailler dans des langages comme Python et JavaScript où l'addition provoquant un débordement n'est pas quelque chose dont les gens s'inquiètent.

EDIT : ... et c'est cette distinction conceptuelle au point 1 sur laquelle je pense que nous devrions nous concentrer. (c'est-à-dire que "de X au pivot" et "de X à la fin" doivent être distincts dans l'esprit du programmeur.)

@pornel
C'est horrible 😄
Dans ce cas spécifique, le début de plage est vraiment très important pour une personne qui lit le code, beaucoup plus important que tout problème de plage inclus/exclusif.

@ssokolow, il me semble que ce qui fait de +1 un problème n'est pas le nombre de caractères mais le fait que vous devez gérer le potentiel de débordement. De plus, il ne communique pas non plus l'intention et nécessite des parenthèses de précédence. Tout cela semble beaucoup plus important que le nombre de caractères.

C'est vrai, quelqu'un qui ne connaît pas le débordement peut atteindre +1 avant de créer une plage inclusive, mais cela ne semble pas dépendre de la syntaxe. Découvrir que ..= est une chose et que inclusive() est une chose présente le moment propice pour apprendre pourquoi vous voudriez spécifiquement des gammes inclusives.

@petrochenkov

Je serais toujours d'accord pour abandonner à la fois les modèles exclusifs et les gammes inclusives (mais pas l'un d'entre eux, ce serait trop ridicule) .

Pourriez-vous expliquer pourquoi vous vous sentez si fort à ce sujet ? Je considère définitivement que l'acceptation de modèles exclusifs n'a qu'un inconvénient dans la mesure où cela peut amener les utilisateurs à s'attendre à 0...10 comme expression, mais cela ne me semble pas si mal .

Une partie de mon problème avec inclusive() est que c'est "juste" une fonction et je crains que les gens fassent des choses comme aller à l'index de syntaxe Rust, rechercher "plage" ou "itérateur", puis supposer un retour sur investissement insuffisant pour "See[ing] Iterators".

("Je ne veux pas lire un manuel par hasard, je trouverai quelque chose d'utile... Je veux juste parcourir une plage et recommencer à progresser.")

@withoutboats Si nous avons inclus (a..b), mais que nous ne pouvons pas l'utiliser en match, cela n'en vaut pas la peine IMO.
La plupart du temps, lorsque j'utilise des plages inclusives, il s'agit de modèles de correspondance !
Alors pourquoi ne pouvons-nous pas supprimer ... et simplement utiliser ..= intérieur et à l'extérieur du match ?

@Boscop, la proposition n'est pas de supprimer ... en correspondance, mais de laisser les modèles exactement tels qu'ils sont sur stable.

@ssokolow semble pouvoir être résolu assez facilement avec une note dans la section ..

@withoutboats Mais pourquoi ne pas supprimer ... dans le match et utiliser ..= place, donc c'est cohérent ?
(afin que ce soit ..= intérieur et à l'extérieur du match)

Pour une couverture de plage numérique en virgule flottante, aides exclusives. Par exemple, l'une de ces limites est entièrement couverte, mais pas l'autre :

match x {
    0.0...3.141592653589792 => 1,
    3.141592653589793...6.283185307179585 => 2,
    6.283185307179586...10.0 => 3,
    _ => 4,
}

Et l'écrire avec des chevauchements semble plutôt dégoûtant (et moralement similaire au "tout commencer à partir de -∞ puisque les bras sont commandés" ci-dessus). Voir aussi les datetimes, comme la façon dont ISO8601 autorise T24:00, puisqu'un jour est [00:00, 24:00), pas [00:00, 23:59:59]. Ou des chaînes, ou des rationnels, ou ...

Étant donné le choix entre uniquement exclusif ou uniquement inclus, je prendrai exclusif à chaque fois.

(A part : le modèle 1 <= x <= N pour l'indexation est en fait mieux fait en tant que 0 < x <= N , qui est également exclusif - bien qu'à moitié fermé au lieu d'être à moitié ouvert - pour les mêmes raisons que Dijkstra a dit, juste inversé pour l'indexation basée sur 1 au lieu de 0.)

Cet opérateur aurait été super utile pour la fonction de serrage que j'ai proposée ici : https://github.com/rust-lang/rfcs/pull/1961 mais comme cela n'a pas été stabilisé, je devrai probablement modifier cette proposition pour utilisez plutôt deux arguments min et max. InclusiveRange est également très utile lorsque vous travaillez avec des valeurs à virgule flottante, nous n'avons donc pas à faire quelque chose comme :

0.0..1.0+EPSILON

Je ne suis même pas sûr que ce soit correct, mais pour le moment, il est très difficile de déclarer une plage inclusive de nombres à virgule flottante.

La bonne façon de procéder serait avec nextafter , pas avec epsilon. c'est- x...y == x..nextafter(y) dire telle fonctionnalité

Oups, j'ai fait un commentaire sur la syntaxe inclusive(a..b) mais j'ai réalisé que ce n'était pas vrai. Quoi qu'il en soit, j'aime ça mais j'espère que nous pourrons bikeshed un meilleur nom.

@durka Le nom me semble clair. Pouvez-vous préciser vos préoccupations à ce sujet ?

Donc, pour les plages inclusives, nous aurons a ... b dans match et inclusive(a..b) dehors du match ?
Pourquoi ne pouvons-nous pas être cohérents et avoir des a ..= b partout ?

Y a-t-il quelque chose qui empêche ops::{RangeInclusive, RangeToInclusive} d'être formellement stabilisé ?

À l'heure actuelle, il semble que le principal obstacle soit le débat sur la syntaxe, même si, indépendamment de ce débat, je suis à peu près sûr que des plages inclusives existeront quelle que soit la syntaxe finale.

Ce serait bien d'avoir ces types pour les bibliothèques stables à implémenter, puis les consommateurs de ces bibliothèques peuvent décider d'activer l'indicateur de fonctionnalité s'ils souhaitent utiliser la syntaxe spéciale.

Une chose que j'ai remarquée à propos de RangeInclusive l'autre jour : c'est difficile à coder si vous essayez d'accepter une plage. Le thread de serrage parlait d'autoriser .clamp(1...9) , mais le code finit par ressembler à ceci :

    fn clamp(self, r: RangeInclusive<Self>) -> Self where Self : Sized {
        match r {
            RangeInclusive::Empty { .. } =>
                panic!("Cannot clamp to an empty range"),
            RangeInclusive::NonEmpty { start, end } => {
                assert!(start <= end, "Cannot clamp to a degenerate range");
                if self < start { start }
                else if self > end { end }
                else { self }
            }
        }
    }

Avoir besoin de gérer RangeInclusive::Empty semble inutile puisque le but est simplement d'accepter la paire avec une belle syntaxe. S'il ne s'agissait pas d'une énumération, cela pourrait être simplement fn clamp(self, RangeInclusive { start, end }: RangeInclusive<Self>) , et beaucoup plus propre.

Malheureusement, je n'ai pas de bonne réponse pour savoir quoi faire à ce sujet, car exiger .into_iter() sur inclusif mais non exclusif serait également malheureux ...

Idée aléatoire : Voyant que la syntaxe du modèle ... n'est pas vraiment liée aux types de plage inclusifs, nous pourrions envisager de déprécier sa syntaxe en faveur d'une syntaxe sans rapport avec celles proposées ici. ... .

Étant donné qu'un modèle de plage inclusif est plus étroitement lié au modèle | , |... pourrait être un bon candidat :

match {
    1 | 2 | 3 => ...
    1 |... 3  => ...
}

Le résultat final serait que la syntaxe de plage inclusive et exclusive n'a plus de relation 1:1 avec la correspondance de modèle, et n'a donc plus besoin d'être cohérente avec elle.

@scottmcm

Malheureusement, je n'ai pas de bonne réponse pour savoir quoi faire à ce sujet, car exiger .into_iter() sur inclusif mais non exclusif serait également malheureux ...

Peut-être pourrions-nous ajouter un assistant comme range.nonempty() qui panique pour une plage vide et renvoie une paire ?

Alternativement, nous pourrions implémenter IntoIterator pour RangeInclusive et ce ne serait pas trop loin à mon humble avis.

Quel cas d'utilisation RangeInclusive::Empty sert-il ? Pourquoi une plage inclusive a-t-elle besoin de la capacité de représenter une plage vide ? Comment en écririez-vous un ? (Notez que vous pouvez déjà écrire des choses comme "la plage de 5 à 4, inclus", que l'itération traiterait vraisemblablement comme vide.)

@joshtriplett le cas principal est le débordement, bien qu'il existe des moyens de résoudre ce problème.

@joshtriplett start > end ne fonctionne en fait pas pour représenter la plage inclusive vide dans un cas important : 0u8...255u8 . Lorsque vous arrivez à 255u8...255u8 et que vous essayez de .next() , vous obtenez soit une panique, soit vous retournez à 0u8...255u8 , qui n'est pas vide. Au lieu de cela, nous passons à la variante Empty à ce stade.

@solson Ah, je vois. Ouais, c'est une douleur, et il est l' un des plus grands cas d'utilisation pour les gammes inclus.

(Je suppose que vous voulez dire 255u8 dans tous ces cas.)

(Je suppose que vous voulez dire 255u8 dans tous ces cas.)

Oui merci. Édité.

@solson cependant, ce cas peut être rectifié en échangeant 0 et 255 dans ce cas

@clarcharr C'est vrai. Étant donné que .next() doit toujours créer un cas particulier pour la génération d'une plage Empty , il peut toujours générer une plage qui sera traitée comme vide.

Personnellement, j'aime mieux cette façon parce qu'elle n'implique pas la plage vide.

Ce fil existe donc depuis un an et demi maintenant. Je viens juste de finir de tout lire et j'aimerais publier un récapitulatif concis pour les nouveaux arrivants et, espérons-le, nous aider à prendre une décision :

Ce que Rust Stable fait aujourd'hui :

0..5 représente une plage semi-ouverte, [0, 1, 2, 3, 4] qui ne peut pas être utilisée dans le pattern matching
0...5 représente une plage fermée [0, 1, 2, 3, 4, 5] qui ne peut être utilisée que dans le filtrage de motifs.

Plusieurs formes ont été proposées pour une syntaxe à plage fermée supplémentaire qui peut être utilisée en dehors de la correspondance de modèle. Je vais couvrir chacun et les avantages et les inconvénients d'entre eux.

0...5

Avantages : Cohérent avec la syntaxe de correspondance de modèle existante, rend le langage plus cohérent en supposant qu'aucune modification n'est apportée à la syntaxe de correspondance de modèle.

Inconvénients : il est facile de mal taper et de provoquer une erreur, il est également facile de mal comprendre l'intention en raison du fait que d'autres langages utilisent cet opérateur pour communiquer différents concepts.

0..=5

Avantages : plus difficile à saisir, plus clair sur le plan sémantique

Inconvénients : Incohérent avec la syntaxe de correspondance de modèle existante. Peut amener les utilisateurs à demander : Pourquoi est-ce ... ici mais ..= ici ?

0..^5

Très similaire à ..= mais a un inconvénient supplémentaire en ce qu'il ressemble à un opérateur d'exponentiation.

inclusive(0..5)

Avantages : Extrêmement clair sémantiquement. Ne sera pas mal tapé.

Inconvénients : un peu long. Également incompatible avec la syntaxe de correspondance de modèle.

0....5

Avantages : Évite également le problème de faute de frappe de ...

Inconvénients : mauvaise sémantique, incompatible avec la syntaxe de correspondance de modèle et similaire à la syntaxe de correspondance de modèle.

[0..5] Inutilisable. les crochets ont déjà une signification syntaxique dans la langue.

0..<=5 Inutilisable. Conflits avec la syntaxe existante pour comparer une valeur à une plage.

Chaque option répertoriée qui a un con de "incohérent avec la syntaxe de correspondance de modèle" pourrait être améliorée si nous devions changer la syntaxe de correspondance de modèle, mais cette route a des problèmes de compatibilité descendante. Alternativement, nous pourrions également rendre ... et (choisissez votre syntaxe ici) équivalents dans la correspondance de modèle afin d'éviter de rompre la compatibilité descendante, mais empêcher l'utilisation de ... dehors de la correspondance de modèle. Peut-être pourrions-nous également mettre à jour le guide de style pour décourager l'utilisation de ... dans la correspondance de motifs si nous devions emprunter cette voie.

Il y a également eu des discussions sur la création d'une syntaxe de plage à usage plus général qui vous permettrait de rendre les limites supérieure et inférieure inclusives ou exclusives, mais nous n'avons probablement même pas besoin de cette syntaxe car une plage semi-ouverte et fermée couvre probablement plus 99,9999% des cas d'utilisation.

J'ai essayé de représenter cette discussion du mieux que j'ai pu. Si vous pensez que je n'ai pas correctement exprimé votre point de vue, veuillez me le faire savoir afin que je puisse mettre à jour cela.

@Xaeroxe Merci pour l'excellent résumé.

Peut-être qu'il est possible d'avoir un outil (peut-être un plugin de rustfmt) qui convertit automatiquement les sources en utilisant ... dans la correspondance de motif avec la nouvelle syntaxe (par exemple ..= ) lorsque cela est décidé.
De cette façon, nous ne serons pas retenus par "tout le code écrit à l'ancienne".
Mais il doit être invoqué intentionnellement par les auteurs du projet et il devrait y avoir une notification / un titre sur tous les supports de rouille afin que tout le monde soit au courant du changement.
Avec ces choses, je pense que ce n'est pas un problème de changer la syntaxe ... dans la correspondance de modèle avec la nouvelle syntaxe.

Je pense qu'une chose que nous pourrions faire pour résoudre le problème de syntaxe est simplement de stabiliser RangeInclusive, comme l' a suggéré

Nous pourrions également ajouter la fonction inclusive (soit juste à std::range ou éventuellement au prélude aussi) ; cela n'empêche pas d'avoir un jour une syntaxe de première classe, mais cela rend beaucoup plus pratique la construction d'un RangeInclusive dès maintenant.

Cependant, tout cela semble être des décisions de libs donc je ne sais pas si l'équipe lang a compétence pour décider de stabiliser/ajouter ces éléments 😅.

Personnellement, je préférerais convertir RangeInclusive lui-même en quelque chose qui n'a pas Empty variante IntoIter ait la variante. Cela a plus de sens pour moi compte tenu du fait qu'il est essentiellement impossible de construire une plage vide sans manuellement Empty { at } .

Alternativement, échangez MAX et MIN sur le cas unique que j'ai mentionné. Cela rend plus difficile l'écriture de code plus général impliquant RangeInclusive , mais cela semble être une solution raisonnable au problème.

Indépendamment de ce qui se passe, je suis tout à fait en faveur de la stabilisation du type dans la bibliothèque standard, qui existera indépendamment des problèmes de syntaxe. Il permet aux bibliothèques d'écrire du code stable qui permet le découpage avec des plages inclusives, de sorte qu'au moment où la syntaxe est stabilisée, les gens ont déjà implémenté le code qui utilise les types. La syntaxe et les types sont sous différents indicateurs de fonctionnalité pour une raison.

@scottmcm Je suis d'accord que cela devrait probablement être un fil distinct à ce stade.

Pour tenter de faire avancer la discussion sur la syntaxe, je vais proposer la voie que je préférerais emprunter.

J'aime beaucoup la syntaxe ..= , donc je pense que nous devrions ajouter ce sucre syntaxique comme égal à ... dans la correspondance de motifs et en tant qu'InclusiveRange en dehors de la correspondance de motifs. Ensuite, afin de maintenir la cohérence du langage, nous devrions essayer de migrer les utilisateurs et leur code vers la syntaxe ..= dans les modèles, en utilisant des annonces et des outils automatisés. Une fois que nous pensons avoir migré suffisamment d'utilisateurs de ... nous pouvons en faire un avertissement du compilateur, puis éventuellement (peut-être même dans des années) une erreur de compilateur.

Cela fait 24 jours que ma proposition a été fournie et aucun commentaire n'a été fait. Devrions-nous aller de l'avant avec ce plan?

EDIT: Sur mobile, je n'ai pas vu les pouces vers le bas, donc je n'ai pas réalisé qu'il y avait des opinions dissidentes.

@Xaeroxe Je ne pense pas. Je ne suis pas d'accord pour dire que la dépréciation de ... en faveur de ..= est un bon choix pour les raisons que j'ai déjà publiées dans ce fil. Je n'ai pas répondu à votre proposition spécifique car la même idée avait déjà été avancée et discutée. La seule chose qui est claire ici, c'est que nous n'avons pas de consensus. Je pense que beaucoup d'entre nous se sentent fatigués par la discussion.

EDIT : Pour être plus précis, je ne veux pas déprécier ... en faveur de ..= car :

  • Déprécier la syntaxe représente un coût énorme en termes de désabonnement ; même si j'aimais sans équivoque ..= je ne pense pas que cela vaudrait la peine d'avoir un cycle de dépréciation juste pour obtenir des expressions de plage inclusives sur stable.
  • Je n'aime pas ..= , je pense que ce n'est ni évident ni clair ; il a l'avantage qu'il est moins susceptible de provoquer des erreurs, mais cela ne signifie pas qu'un utilisateur, le voyant pour la première fois, saura ce qu'il regarde.
  • Je ne suis pas d'accord avec la prémisse selon laquelle il doit y avoir une symétrie entre les modèles et les expressions ici, car ils ne font aucune sorte d'opérations de structuration/déstructuration analogues.

(Je change un peu de point de vue pendant ce commentaire, j'ai décidé de tout laisser pour que les autres puissent voir mon processus de réflexion et pourquoi je suis arrivé aux conclusions que j'ai faites)

Je ne peux pas vraiment commenter le coût de la dépréciation en raison de mon manque d'expérience avec de telles choses. Cependant, je suis toujours en faveur de ..= .

Je pense qu'à un moment donné, nous devons être prêts à demander aux utilisateurs d'apprendre quelque chose. La programmation dans son ensemble est quelque chose à apprendre, la syntaxe spécialisée en général a toujours un coût pour la sémantique. Je ne m'attends pas à ce que les gens reconnaissent la syntaxe à première vue, .. est tout aussi mauvais à cet égard.

Cependant, le fait d'avoir une surabondance de syntaxe spécialisée peut donner un langage plus proche du brainfuck que ce que nous voulons que Rust soit. Nous devons donc veiller à ce que les cas que nous choisissons de transformer en syntaxe spéciale soient en fait suffisamment courants pour en valoir la peine. Pour être honnête, maintenant que j'ai tapé ceci, je ne suis pas tout à fait sûr que cette affaire en vaille la peine. Le besoin de plages inclusives n'est pas assez élevé pour justifier une syntaxe.

Cependant, l'incohérence me dérange toujours. Avoir une fonction inclusive et ... dans la correspondance de motifs donne l'impression d'avoir à la fois du gris et du gris dans la langue anglaise. Lorsque nous avons l'opportunité de standardiser cela, une partie de moi a l'impression que nous devrions le faire. Cependant, il existe également de réels problèmes logistiques pour effectuer ce changement. Si nous devions jamais concevoir un Rust 2.0 (cela pourrait être fou, je n'en ai aucune idée), nous devrions peut-être revoir cela, mais je suppose que pour l'instant, avoir à la fois du gris et du gris est assez bon.

Je suis en faveur de l'utilisation d'une fonction inclusive pour les instances en dehors de la correspondance de modèle et de ... dans la correspondance de modèle pour le moment.

@sansbateaux

  1. Si vous ne dépréciez jamais rien, vous vous retrouvez avec l'union de toutes (plus ou moins) les mauvaises décisions comme le C++. Cela oblige les débutants à en apprendre encore plus, car les choses ne sont pas aussi cohérentes qu'elles pourraient l'être.
    Il est donc parfois logique de déprécier des choses pour faire place à la meilleure solution.

  2. cela ne signifie pas qu'un utilisateur, qui le voit pour la première fois, saura ce qu'il regarde.

C'est le cas de toute syntaxe. Nous (qui connaissons Rust) avons ce parti pris car pour nous, le code Rust semble évident, mais quiconque vient à Rust depuis un autre langage doit souvent rechercher la syntaxe. Cela ne change pas si nous utilisons ..= ou ... ou toute autre syntaxe pour les plages inclusives car, par exemple, d'autres langages utilisent ... pour les plages exclusives, ils doivent donc la rechercher de toute façon .
Notre objectif ne devrait pas être d'introduire uniquement des fonctionnalités d'apparence évidente :
Si nous voulions n'avoir que des fonctionnalités qui semblent évidentes, nous ne pourrions pas avoir la plupart des fonctionnalités existantes dans Rust. Les débutants DOIVENT regarder la doc de toute façon, qu'y a-t-il de si mal à cela ? La doc est bonne !


  1. Si vous vous souciez de minimiser le temps que les débutants doivent consulter la doc, nous devons nous efforcer d'obtenir une symétrie entre la construction et la correspondance des plages inclusives ! (et autres constructions)

Comme l'a dit @withoutboats , je pense que beaucoup d'entre nous sont fatigués de cette discussion ; Pour ma part, je suis resté assis pendant un certain temps. Cela dit, j'ai pris le temps de relire (merci pour le résumé @Xaeroxe !) et de revoir mes réflexions ici.

OMI, le problème le plus important en ce moment est la combinaison incomplète de syntaxes que nous proposons : ... dans les motifs, .. pour les expressions. Cette paire de syntaxes vous amène fortement à vous attendre à ce que .. fonctionne dans les modèles et ... dans les expressions -- et ce n'est pas le cas. Je crois que ce n'est pas une conception tenable à long terme et je veux vraiment y remédier.

Je pense également que, étant donné que nous avons fourni une syntaxe pour les deux types de plages, il est probablement préférable de continuer à le faire. Cela nous laisse quelques options :

  • Stabilisez ... dans les expressions et ajoutez .. aux modèles. C'est le changement le moins douloureux, mais il a des inconvénients bien discutés autour des erreurs un par un. Pourtant, d'autres langues ont cette combinaison et n'ont pas, à ma connaissance, terriblement souffert de telles erreurs.

  • Dépréciez ... dans les modèles et les expressions, ajoutez ..= aux deux et ajoutez .. aux modèles. Résout les inconvénients ci-dessus, est plus douloureux (en raison de la dépréciation) et ouvre la porte à d'autres types de gammes (comme l'exclusivité à gauche) à l'avenir.

À ce stade, je ressasse en grande partie la discussion, et honnêtement, je ne pense pas qu'il y ait beaucoup plus à dire à ce stade ; Je pense que nous avons exposé les compromis et avons juste besoin de l'équipe lang pour faire une évaluation et prendre une décision. Mais l'essentiel de mon commentaire est le point initial, pourquoi je pense que quelque chose doit changer ici (et pourquoi il ne suffit pas d'ajouter inclusive , IMO).

Pourtant, d'autres langues ont cette combinaison et n'ont pas, à ma connaissance, terriblement souffert de telles erreurs.

Je m'inquiète du biais de sélection ici. Nous n'avons aucun moyen fiable de juger si les problèmes sont mineurs ou s'ils viennent rarement à notre attention.

De plus, l'utilisation de ... impression que cela va à l'encontre de l'aspect « éviter les armes à pied à moins que les compromis ne soient trop sévères » de la philosophie de conception de Rust et des meilleures pratiques émergentes. (par exemple, le conseil de créer de nouveaux types enum plutôt que d'utiliser bool , il est donc plus difficile de mélanger les paramètres de vos fonctions.)

Par exemple, C a prouvé que l'affectation dans les instructions if est utile si une langue n'a pas while let , mais il a été reconnu que taper = alors que vous vouliez dire == est une arme à pied suffisante pour que des langages comme Python le refusent, même lorsqu'il existe des situations où les seules alternatives sont inhabituellement laides.

En allant dans l'autre sens, j'ai en fait demandé à Clippy d'attraper un cas comme celui-ci alors que j'étais fatigué de coder il y a environ une semaine...

foo == bar;  // This should be `foo = bar;`

... ce qui semble être un exemple parfait du genre d'erreur "appuyez sur la touche une fois de trop" qui nous inquiète ici... et, contrairement à " == n'a aucun effet", il y a pas de bon moyen de pelucher pour .. contre ... .

@ssokolow Pour être clair, ça me va aussi avec ..= ; Je ne pense pas que la dépréciation sera si douloureuse, et c'est une solution automatique très simple. Surtout, je veux juste que ce problème soit résolu.

Je peux probablement vivre avec la stabilisation de .. / ... (qui est déjà implémentée tous les soirs). Je suis d'accord avec @aturon que le langage tel qu'il existe suggère que cela fonctionnera.

Comme je l'ai dit, j'aimerais vraiment stabiliser le type libstd lorsque rust-lang/rfcs#1980 passe sans nécessiter une discussion sur la syntaxe.

Parallèlement à ce que @aturon a souligné, il serait peut-être utile de fusionner les problèmes de suivi à la fois pour cette syntaxe de plage exclusive ? Peut-être créer un problème de suivi séparé pour le type et l'utiliser pour stabiliser le type avant la syntaxe.

Je re-nomination pour la discussion de l'équipe lang. Je pense qu'il est très peu probable que des idées ou des compromis sensiblement nouveaux surgissent à ce stade. Nous devons prendre une décision sur les compromis qui ont été établis.

Le 18 mai 2017 à 9 h 55 min 30 s HAP, Aaron Turon [email protected] a écrit :

Je re-nomination pour la discussion de l'équipe lang. je pense que c'est très peu probable
que des idées ou des compromis considérablement nouveaux vont surgir à ce stade
point. Nous devons prendre une décision sur les compromis qui ont été
disposé.

Je vais être absent pour la réunion de la semaine prochaine en raison d'une conférence. Au cas où cela serait discuté lors de la réunion de la semaine prochaine, j'exprimerai mon soutien pour toute solution autre que ... , que ce soit ..= , inclusive , ou autre.

Cela vaudrait la peine de discuter de la syntaxe rest/spread pendant que nous y sommes.
Je vote .. pour la gamme exclusive, ... pour l'inclusif, .... pour le repos/propagation.

take_range(..max); // exclusive range
take_range(...max); // inclusive range
take_multiple_args(....tuple); // spread
if let 0..10 = get_num() {} // exclusive range pattern
if let 0...9 = get_num() {} // inclusive range pattern
if let [first, ....rest] = get_slice() {} // rest pattern

Je voterais ... pour une tranche de repos pour deux raisons :

  1. Les gens sont probablement déjà familiers avec ... signifiant "repos" dans des langages comme CoffeeScript (CoffeeScript utilise rest... dans les signatures de fonction pour varargs et les appelle "splats") et l'anglais (en utilisant le bon Unicode codepoint ou non, ce sont trois périodes qui ressemblent à des points de suspension, pas quatre, et les gens font un travail décent pour comprendre les points de suspension pour signifier approximativement "et il y a plus mais nous ne le disons pas à voix haute" en anglais, simplement en le rencontrant utilisé.)

  2. À moins que je manque quelque chose à propos de la syntaxe de Rust, utiliser .. et ..= pour les plages mais ... pour les tranches de repos signifierait que, dans chaque situation, taper ... quand vous vouliez dire .. ou vice-versa serait toujours une erreur de compilation.

    Pour cela, je fonctionne sur deux hypothèses :

    1. L'utilisation de la syntaxe rest seule (en dehors d'un contexte de décompression de séquences) serait interdite en tant que no-op sujette aux fautes de frappe. (c'est-à-dire que for _ in ...rest serait le même que for _ in rest si cela était autorisé, mais presque certainement une faute de frappe.

    2. L'utilisation d'une plage ouverte comme modèle à attribuer serait invalide. (c'est-à-dire que let [first, ..rest] = serait invalide.)

@ssokolow triple point signifie déjà une plage de motifs, ce serait donc un changement

@Pointe Phaux . J'avais oublié ça pour une raison quelconque.

Quelque chose pour accrocher l'étiquette "si jamais nous fabriquons Rust 2.0", peut-être.

le point triple signifie déjà une plage de motifs, ce serait donc un changement décisif pour le changer en syntaxe au repos.

Cependant, le ... dans les motifs doit avoir une expression des deux côtés, je crois ( a...b ), alors que la syntaxe du reste utilise ... comme préfixe, non ?

L'équipe lang a de nouveau discuté de cette fonctionnalité lors de notre réunion d'aujourd'hui et est arrivée à peu près à la matrice suivante :

  • La prise en charge de ... dans les modèles et de .. dans les expressions, et rien d'autre, est une conception intenable ; cela amène les utilisateurs à s'attendre à ce que la syntaxe fonctionne qui ne fonctionnera pas.

  • Autoriser ... et .. aux deux endroits aiderait, mais le problème du décalage par un est un réel problème ; aucun d'entre nous n'est impatient de recevoir des rapports de personnes passant des heures à traquer une période errante.

  • Passer à ..= et .. est moins esthétique, mais évite les problèmes pratiques très réels ci-dessus. Nous pouvons également le déployer de manière très douce : introduisez d'abord ..= comme syntaxe alternative (que rustfmt peut réécrire), et seulement après qu'elle soit devenue idiomatique, dépréciez ... .

Au cas où vous ne le sauriez pas, l'équipe pense que ..= et .. est notre meilleure voie à suivre. Ce problème a également été discuté au point qu'il est très peu probable que de nouveaux arguments soient soulevés, nous sommes donc prêts à franchir le pas : nous recherchons quelqu'un qui aimerait implémenter la notation ..= pour les deux modèles et expressions, et par la suite nous irons à FCP !

À cette fin, nous recherchons quelqu'un (ou quelques personnes) pour faire avancer la mise en œuvre. Cela peut probablement être fait dans un certain nombre de petits PR :

  • Pour commencer, ajoutons ..= à l'analyseur en tant qu'alias pour ... et convertissons les tests existants.

    • ... devrait continuer à fonctionner, bien sûr, et nous voulons que ce soit une dépréciation "silencieuse", il n'est donc pas nécessaire d'émettre des avertissements, etc. (encore).

    • il faudra donc garder les tests sur des motifs ...

    • Je pense que la façon de procéder consiste probablement à modifier le lexer en ajoutant le jeton DotDotEquals ( voici le DotDotDot existant ) puis en modifiant l'analyseur pour accepter DotDotEquals partout où nous accepter maintenant DotDotDot ( exemple )

    • ripgrep DotDotDot est ton ami ici ;)

  • ... dans les expressions n'a jamais été stable, nous pouvons donc simplement changer cela en ..= et supprimer l'ancien support

    • pour être gentil avec les gens dans la nature, nous pourrions traverser une période de dépréciation, mais je ne suis pas sûr que ce soit nécessaire (pensées?)

Juste pour noter que, lors de l'implémentation, la syntaxe extern fn foo(a: u32, ...) ne doit pas être changée en ..= 😆

Tenté de le prendre car cela ressemble à une belle première étape dans le code mais je ne vais pas avoir beaucoup de temps dans les 2 prochaines semaines donc si quelqu'un veut le prendre, n'hésitez pas !

Je suis personnellement plus en faveur de ..^ que de ..= , car a operator= b est déjà, pour certains opérateurs, un alias pour a = a operator b . ^ d'autre part est beaucoup moins utilisé, uniquement pour XOR, donc cela devrait causer moins de confusion.

.. donne un type différent de celui des opérandes gauche et droit, donc je ne vois pas cela comme un problème pour ..= . Le contexte aide également à identifier le but de l'opérateur, quelque chose comme += renvoie () afin qu'il puisse apparaître comme sa propre déclaration, généralement sur sa propre ligne. Alors que ..= renvoie InclusiveRange afin qu'il apparaisse comme une expression dans d'autres instructions. De plus, comme mentionné ci-dessus, ..^ semble avoir plus à voir avec l'exponentiation qu'une plage.

@Xaeroxe ^ n'a rien à voir dans Rust avec l'exponentiation (bien qu'il soit utilisé comme tel dans d'autres langages), tandis que += , -= , *= all existent dans Rust. En fait, même ^= existe.

Mais idk, c'est bien d'avoir aussi ..= .

Puisque #42134 a été fusionné, pouvons-nous maintenant stabiliser la structure de la bibliothèque ? Je suppose que nous allons vouloir attendre que la syntaxe se règle avant de stabiliser cela, bien que comme je l'ai dit plus tôt, il serait utile de stabiliser la structure plus tôt.

@clarcharr Je pense que nous avons pris la décision de stabiliser cette structure ainsi que la syntaxe ..= , nous avons donc juste besoin de quelques PR pour le faire.

EDIT : Oups je me suis trompé. Nous l'implémentons dans le compilateur, la stabilisation de la syntaxe devra attendre la fin de la période de commentaire final. Je pense que nous devrions stabiliser la structure à ce stade mais ce n'est pas non plus ma décision à prendre.

J'ai arrêté de suivre le sujet il y a longtemps, quand il m'a semblé que ... faisait consensus. ..= me semble juste gênant car cela ressemble à une affectation à première vue.

Mais bien plus important, je ne pense pas que ce bikeshedding soit assez important pour changer la syntaxe actuelle du pattern.

cette syntaxe est nulle !
= avoir un sens d'affectation, même dans +=, -=, *= modèle, mais ..= consiste à obtenir quelque chose. si confus et laid.
comme l'index du tableau commence à 0, '...' est bon et beau, les gens s'y habitueront.

@zengsai
..= est conceptuellement dérivé d'opérateurs comme == et <= , qui existent déjà dans Rust et indiquent une comparaison d'égalité, pas une affectation.

(ie. 1..=5 est un raccourci pour "Range over values 1 <= x <= 5 " par opposition à 1..5 signifiant "Range over values 1 <= x < 5 ")

EDIT : De plus, il ne s'agit pas de " s'y habituer ", c'est une question de ce qui est plus difficile à mal lire ou mal taper lorsque vous êtes fatigué ou distrait. Les erreurs imprévues comme celle-ci sont notoirement footgun-y.

En fait, j'ai accidentellement tapé ... alors que je voulais déjà dire .. . Heureusement, je cible toujours Rust stable, donc le compilateur l'a détecté. (Cependant, je ne me souviens pas s'il s'agissait d'un spasme musculaire ou d'une mémoire musculaire en supposant que je voulais taper une pseudo-ellipse parce que j'écris beaucoup de non-fiction.)

@zengsai ... est trop subtil, ressemble trop à ..

Ce sera vraiment anormal pour une langue d'avoir un nombre différent de points signifiant différentes choses

Retirer une arme à pied est plus important que d'être esthétiquement attrayant.

Nouveaux arrivants : J'ai fait un TL;DR, car c'est un fil très long. Vous pouvez le lire ici : https://github.com/rust-lang/rust/issues/28237#issuecomment -296310123

en parlant de « les erreurs les unes après les autres sont notoirement connues sous le nom de footgun-y », je dois dire : un problème de faute de frappe ne devrait pas être utilisé comme la principale raison de ce changement.

regardez cette comparaison, ".." et "..." vs "=" et "==", cela signifie-t-il que nous devrions trouver une autre syntaxe pour "==" pour éviter le problème de faute de frappe de l'utilisateur ? si "=" et "==" conviennent, pourquoi ".." et "..." ne le peuvent pas ?

Je suis rust-lang depuis plus de deux ans. et il a été utilisé dans plusieurs de mes projets privés. J'adore ça, mais cette syntaxe me met vraiment mal à l'aise. non seulement l'esthétique, mais aussi la fluidité de l'écriture et de la lecture du code.

@zengsai , j'ai .. contre ... étant une erreur un par un, alors que ..= se démarque définitivement plus et a gagné pas ce problème.

Je ne suis pas sûr d'aimer la syntaxe ..= d'un point de vue esthétique, mais je peux voir d'où tout le monde vient d'environ .. et ... lisant de manière très similaire.

@zengsai Parce que = contre == a une solution qui n'est pas disponible pour .. contre ... .

Bien sûr, vous pouvez confondre = et == en C... mais c'est un pistolet reconnu et des langages plus modernes comme Python et Rust ont résolu cela :

  1. C'est une erreur si vous tapez if x = y plutôt que if x == y (Ceci est le correctif fait par Rust et Python)
  2. Lorsque j'ai accidentellement tapé x == y; lieu de x = y; , j'ai reçu un avertissement concernant une expression qui n'a aucun effet.

Il n'y a aucun moyen pour le compilateur de même reconnaître qu'une confusion .. vs ... est louche , et encore moins fausse.

@zengsai .. et ... évaluent des types qui implémentent tous les mêmes traits et peuvent être utilisés essentiellement de manière interchangeable (c'est par conception). L'erreur off by one est un problème très réel.

Je veux être clair que je déteste aussi cette syntaxe, à tel point que je ne suis pas d'accord avec le commentaire de @aturon selon lequel la situation actuelle où nous utilisons .. et des expressions et ... dans motifs est « intenable ; » en fait, je pense qu'il est préférable d'avoir la déconnexion que d'avoir cette syntaxe.

Mais il est clair que nous n'aurons jamais de consensus là-dessus, qu'il n'y a pas de nouveaux arguments à avoir sur ce fil, et que la majorité des utilisateurs activement investis (ainsi que le reste de l'équipe linguistique) ont favorisé ce changement. Je me retire donc pour que le problème soit résolu.

Si cela peut vous consoler d'après mon expérience, la grande majorité des cas d'utilisation n'ont jamais vraiment besoin de cette fonctionnalité, et elle n'apparaîtra donc pas partout dans votre code.

En fait, je suis toujours très mécontent de la dépréciation de ... dans les modèles, et je vais simplement serrer les dents pour que ce problème puisse être résolu. Toute l'équipe de lang convient qu'avoir à la fois des expressions .. et ... serait une verrue terrible, amenant certains utilisateurs à passer des heures à déboguer un problème de faute de frappe totalement silencieux.

Le reste de l'équipe lang est convaincu qu'il est inacceptable d'avoir une déconnexion entre les expressions et les modèles, et bien que je ne sois pas d'accord, nous avons tous fait valoir nos arguments et je ne pense pas qu'être dans une impasse pour toujours soit sain.

@ssokolow Désolé, je ne peux toujours pas être d'accord avec toi. le compilateur peut vous avertir de ce genre de faute de frappe, mais que se passe-t-il si vous tapez "x=5" à l'endroit où il devrait être "x=6" ?

Le compilateur n'est pas parfait pour éviter les fautes de frappe, c'est le programmeur.

si ce changement n'a pas d'effets secondaires, je suis tout à fait d'accord. mais cela a fait perdre à la langue la fluidité de l'esthétique, de l'écriture et de la lecture, ce qui ne vaut pas la peine à mon avis personnel.

La rouille d'aujourd'hui rencontre déjà des problèmes de lecture et d'écriture, plus la syntaxe est rare et contre-intuitive, plus la courbe d'apprentissage est longue, n'en faites pas un autre Perl.

@withoutboats Nous nous disputons avec, parce que nous l'aimons. Peut-être que cet argument est trop tard et ne peut rien changer, juste...

@zengsai

Il y a certainement des compromis à faire, mais j'ai l'impression que nous n'allons jamais nous mettre d'accord sur le meilleur point d'équilibre entre ceux-ci.

Indépendamment de mes goûts personnels, je vois ..= comme un petit prix à payer pour éviter ce qui peut être une très grande perte de temps à essayer de traquer les bogues.

(Mon domaine d'intérêt est la conception UI/UX et l'une des plus grandes règles qu'ils vous enseignent est que vous devez viser à rendre la facilité de faire une erreur inversement proportionnelle au préjudice et/ou au temps de réparation que cela causera. )

À mon avis, 5 contre 6 est beaucoup plus évident à voir que .. contre ... .

@zengsai Je reçois trop d'e-mails juste pour cette conversation, que diriez-vous de passer au canal IRC rouille pour mieux exprimer vos sentiments ?

@daiheitan Ceci est une communication normale. Si vous ne l'aimez pas, je vous suggère d'annuler votre

Quand j'ai regardé Rust pour la première fois, j'ai été vraiment surpris par la syntaxe .. . (1..10).sum() est... la somme d'entiers de 1 à 9 ? Si vous présentez cette syntaxe à un nouveau venu et lui demandez ce que cela signifie, il est très probable qu'il s'attend à ce qu'elle passe de 1 à 10. Et il aurait raison de le faire, puisque vous vous attendriez à ce que la syntaxe symétrique exprime la symétrie gammes. Pourquoi le 1 devrait-il être inclus mais pas le 10 ?

L'ajout d'une autre forme asymétrique ..= pour une plage symétrique rend cela encore plus incohérent visuellement. On pourrait se demander pourquoi le côté gauche n'a pas besoin de = pour être inclusif, donc ce serait =..= pour les plages inclusives des deux côtés.

Quelque chose comme la syntaxe Swift ( ..< pour exclusif et ... pour inclus) éviterait ces problèmes et améliorerait la lisibilité. Vous pouvez facilement deviner le sens correctement même si vous êtes complètement nouveau dans la langue, il y a donc une chose de moins à retenir. Je me serais attendu à ce que quelque chose comme celui-ci soit choisi, surtout compte tenu de la poussée de Rust vers la convivialité pour les nouveaux arrivants.

@rkarp Dans une certaine mesure, cela est probablement dû à un biais préexistant.

Par exemple, il y a beaucoup d'influence Python dans Rust et Python utilise le même type de plages semi-ouvertes. (c'est-à-dire que les range(1, 5) ou myList[1:5] Python ont tous les deux le même comportement que les 1..5 de Rust)

La justification de cela dans Python était liée au fait qu'il n'y avait qu'une seule syntaxe et qu'avoir une syntaxe semi-ouverte facilitait les choses comme head, tail = myList[:pivot], mylist[pivot:] .

Cela dit, étant donné que Rust a dépassé la version 1.0, il existe des règles assez strictes pour ne pas casser le code existant. .. pour les motifs extérieurs exclusifs et ... pour les motifs intérieurs exclusifs doivent rester valides.

..= fonctionne parce que vous pouvez accepter .. (exclusif) et ..= (inclus) partout et traiter ... comme un synonyme obsolète de .. dans les motifs.

Juste pour dire, avoir ..= comme jeton est techniquement un changement incompatible, car il affecte les règles :tt dans les macros. Ce ne serait probablement pas problématique, mais vous voudrez peut-être vérifier si quelqu'un ne le fait pas, étant donné que cela peut aussi bien être un changement discret. (l'alternative est d'autoriser .. /* why not */ = , ce que je ne pense pas être une bonne idée)

@ssokolow Techniquement, c'est une erreur de type dans Rust, pas une erreur d'analyse. a = 2 est une expression qui renvoie () , et if attend bool , ils sont donc clairement incompatibles.

Les règles changent petit à petit. Techniquement, les ..= sont 3 jetons où les 2 premiers n'ont pas d'espace après eux.

@eddyb : J'avoue que je ne comprends pas tout à fait. Existe-t-il un moyen d'introduire un nouveau jeton sans affecter la façon dont :tt l'analyse ?

Ce code signale actuellement « Règle 2 » et « Règle 4 ». Ce changement, si je le comprends bien, le changera en "Règle 2" et "Règle 5".

macro_rules! ex {
    ( . . )   => { "Rule 1: . ." };
    ( .. )    => { "Rule 2: .."};
    { . . = } => { "Rule 3: . . = " };
    { .. = }  => { "Rule 4: .. = " };
    { ..= }   => { "Rule 5: ..=" };
}

macro_rules! show {
    ( $($t:tt)* ) => { println!("{}", ex!($($t)*)) };
}

fn main() {
    show!(..);
    show!(..=);
}

Non, c'est un changement dans la façon dont les jetons sont définis. @jseyfried peut mieux expliquer les conséquences.

Techniquement, c'est une erreur de type dans Rust, pas une erreur d'analyse. a = 2 est une expression qui renvoie (), et si attend bool, ils sont donc clairement incompatibles.

@xfix Merci. Je n'ai pas fait attention la dernière fois que j'ai fait cette faute de frappe et je ne suis toujours pas complètement habitué à penser en termes de langages orientés vers l'expression.

J'ai ajusté mon commentaire.

Je n'aime pas la syntaxe ..= et je suis contre la dépréciation de ... dans les modèles. Si nous avons peur de l'erreur de frappe, nous pouvons toujours utiliser la struct RangeInclusive { start, end } plutôt que ... ou ..= pour son raccourci.

Ambiguïté potentielle que je viens de réaliser :

if let 5..=x { ... }

@clarcharr On dirait qu'il ne compile pas cependant.

rustc 1.17.0 (56124baa9 2017-04-24)
error: unexpected token: `=`
 --> <anon>:3:13
  |
3 |     if let 5..=x {
  |             ^^

error: aborting due to previous error

@clarcharr @kennytm
Après avoir introduit ..= comme un seul opérateur, l'erreur serait :

error: expected one of `::` or `=`, found `{`
 --> <anon>:3:13
  |
3 |     if let 5..=x {
  |                  ^

error: aborting due to previous error

Comme maintenant avec let x=10; if let 5..x {}

Donc cette "ambiguïté" ne compilerait pas et ne serait donc pas plus une ambiguïté que if let 5..x {} .

@Boscop Le fait est qu'actuellement, si nous traitons 5.. comme un motif comme Some(5) , alors if let 5.. = x serait similaire à let Some(5) = x , et ce dernier compile. Mon commentaire montre que 5.. n'est pas un modèle, il n'y a donc aucun risque de compatibilité de if let pour l'introduction de ..= .

Si nous introduisons cette fonctionnalité et autorisons à la fois ..= et .. dans les modèles, if let 5..=x devrait toujours être if let 5.. = x et il devrait compiler : if let (single expression) n'a pas de sens, donc je ne pense pas qu'il y ait d'ambiguïté.

@kennytm donc nous avons tous les deux montré pour 2 ambiguïtés différentes qu'ils ne compileront pas. (Ce n'était pas clair de qui il parlait. C'était un peu ambigu, heh.)

@daboross Comme kennytm l'a dit, 5.. n'est pas un modèle et ne compile pas, même maintenant. Et cela ne changera pas si nous ajoutons ..= comme opérateur. Il n'y a pas d'ambiguïté. Ce qui est important, c'est que maintenant, ..= ne peut pas être analysé comme un seul opérateur, mais une fois que nous pouvons l'analyser comme un seul opérateur, il n'y a plus d'ambiguïté.

5.. n'est pas un modèle actuellement valide, et nous n'avons pas non plus de modèles d'intervalles à moitié fermés. Cela étant dit, le manque de modèles d'intervalles à moitié fermés est souvent considéré comme une source d'incohérence par rapport aux expressions de plage et pourrait finir par être implémenté pour les modèles également. Nous pourrions également vouloir ajouter la possibilité d'omettre un côté de l'intervalle dans les modèles plus tard pour, par exemple, des correspondances d'entiers exhaustives.

Ainsi, bien que l'observation de @clarcharr ne souligne pas nécessairement l'ambiguïté lorsque la grammaire actuelle est prise en compte, il s'agit certainement d'une ambiguïté lors de l'examen des futures extensions potentielles qui pourraient entrer en conflit avec la proposition d'utiliser ..= pour les modèles.

Dans cet esprit, je suggérerais d'utiliser un autre symbole ici. ^ me semble assez correct, car il n'est utilisé que dans un contexte d'expression actuellement IIRC.

(C'est une autre raison pour laquelle je pense que c'est une bonne idée de stabiliser la structure maintenant et la syntaxe plus tard.)

@nagisa, il n'y a pas de conflit concernant if let si le jeton ..= est ajouté avant que le modèle RangeFrom ne soit pris en charge. On pourrait ajouter un espace entre les .. et = pour lever l'ambiguïté, tout comme x <- y (placement in) vs x < -y (inférieur à + négatif).

(Puisque ^ est l'opérateur exclusif -or, je trouve ironique d'utiliser ..^ pour la plage inclusive )

Dans les milliers de plages que j'ai écrites, dont bon nombre entièrement fermées, peut-être même une ou deux à moitié ouvertes dans le mauvais sens, je ne vois toujours pas vraiment la nécessité d'une syntaxe supplémentaire. 1..(n+1) n'est pas si difficile à écrire.

Cela ne fonctionne pas pour end = T::max_value().

Le 29 mai 2017 à 16h33, "Diggory Hardy" [email protected] a écrit :

Dans les milliers de gammes que j'ai écrites, bon nombre d'entre elles entièrement fermées,
peut-être même un ou deux entrouverts à l'envers, je ne sais toujours pas
voir le besoin de toute syntaxe supplémentaire. 1..(n+1) n'est pas si difficile à écrire.

-
Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/rust-lang/rust/issues/28237#issuecomment-304662258 ,
ou couper le fil
https://github.com/notifications/unsubscribe-auth/AApc0ipynL_qrZqUBldOJOX046RNY2H_ks5r-skwgaJpZM4F4LbW
.

Je préférerais une méthode sur des plages à moitié fermées à ..= cependant.

Le 29 mai 2017 à 16h35, "Simonas Kazlauskas" [email protected] a écrit :

Cela ne fonctionne pas pour end = T::max_value().

Le 29 mai 2017 à 16h33, "Diggory Hardy" [email protected] a écrit :

Dans les milliers de gammes que j'ai écrites, bon nombre d'entre elles sont entièrement
fermé, peut-être même un ou deux entr'ouverts à l'envers, je ne sais toujours pas
vraiment voir la nécessité d'une syntaxe supplémentaire. 1..(n+1) n'est pas si difficile à
écrivez.

-
Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/rust-lang/rust/issues/28237#issuecomment-304662258 ,
ou couper le fil
https://github.com/notifications/unsubscribe-auth/AApc0ipynL_qrZqUBldOJOX046RNY2H_ks5r-skwgaJpZM4F4LbW
.

Je souhaite vraiment que nous stabilisions déjà les traits et les types avec une méthode pour les construire parce que je suis presque sûr qu'il n'y a pas de désaccord à ce sujet. Veuillez ne pas laisser bikeshedding sur la syntaxe retarder la stabilisation de la fonctionnalité de base elle-même.

Cela ne fonctionne pas pour end = T::max_value().

Voulez-vous vraiment itérer sur 2^64 valeurs, voire 2^8 valeurs ? Si vous souhaitez uniquement parcourir les dernières valeurs, par exemple un u32 , il est souvent plus facile d'en ajouter une à l'intérieur de la boucle. Et si vous voulez vraiment itérer jusqu'à 2^B-1 pour une raison obscure, alors vous pouvez toujours coller if i == END { break; } à la fin d'une boucle.

Ce n'est pas parce que nos entiers standard non signés prennent en charge les valeurs 2^32 ou 2^64 que la valeur représentable la plus élevée est utilisée très souvent. Et si vous faites quelque chose avec u8 , n'oubliez pas qu'il est probablement plus facile pour le processeur d'utiliser u32 pour un compteur de toute façon.

Mais même si je ne vois pas le besoin d'une syntaxe de générateur à plage fermée, je ne peux pas réfuter les arguments de l'équipe en faveur du changement . Tant pis :/

Qu'en est-il de ces quatre options pour englober toutes les options d'inclusion ?

1...10
1>..10
1..<10
1>.<10

J'imagine que l'on devrait être capable de comprendre ce qu'ils impliquent sans plus d'explications, étant donné que les opérateurs d'inégalité ont été martelés dans l'esprit de tout le monde depuis la maternelle... je ne sais pas si cela serait pénible à d'autres égards, cependant.

Alternativement, nous pourrions inverser les inégalités:

1...10
1<..10
1..>10
1<.>10

... juste pour que le dernier ne ressemble pas à un Cartman en colère.

@vegai et qu'en est-il de la syntaxe a..b existante qui ne va certainement pas être supprimée ? Non, je ne pense pas que suggérer de nouvelles options de syntaxe résoudra quoi que ce soit.

Hmm, il y a donc eu deux « ambiguïtés potentielles » soulevées :

  • if let 5..= x -- comme indiqué, ce n'est pas vraiment une ambiguïté maintenant , mais cela pourrait en quelque sorte l'être. D'un autre côté, ce type d'ambiguïté survient fréquemment et est résolu par le tokenizer. C'est-à-dire que si nous considérons ..= comme un jeton dans notre analyseur, ce n'est pas ambigu même si nous ajoutons des motifs 5.. dans le futur ; vous avez simplement besoin d'écrire un espace entre le .. et le = (par exemple, let 5.. = x ).
  • l'ambiguïté par rapport aux macro-règles. C'est en effet pénible et malheureux, et c'est l'une des raisons pour lesquelles nous nous dirigeons vers un système différent pour les "macros 2.0", où nous évitons d'exposer l'ensemble de "jetons composés" à l'utilisateur final.

    • à la fin, nous pouvons gérer la rétrocompatibilité de macro_rules! via un code de cas particulier si nécessaire ; en tout cas, je pense qu'il n'y a pas moyen d'éviter ce genre de problème sauf en utilisant ... .

Avant de stabiliser les plages inclusives, le problème #42401 devrait également être corrigé imo, car après la stabilisation, le correctif serait un changement décisif.

@est31 bon point, j'ai ajouté cela à la liste de contrôle en tête du problème

Le tranchage str vérifié est lui-même instable et la résolution de ce problème ne bloque pas du tout les plages inclusives.

Oh, @nagisa a raison, cela n'a rien à voir avec la syntaxe des plages. Pouvez-vous l'enlever de la tête à nouveau? Mon erreur. Le bug est plutôt dans l'implémentation de get , et donc gardé par la fonctionnalité str_checked_slicing :

    impl SliceIndex<str> for ops::RangeToInclusive<usize> {
        type Output = str;
        #[inline]
        fn get(self, slice: &str) -> Option<&Self::Output> {
            if slice.is_char_boundary(self.end + 1) {
                Some(unsafe { self.get_unchecked(slice) })
            } else {
                None
            }
        }
    [...]

supprimé

Une autre mise à jour de la case à cocher : PR https://github.com/rust-lang/rust/pull/42134 a appliqué le https://github.com/rust-lang/rfcs/pull/1980 tweak

Bump : comment pouvons-nous stabiliser au moins les structures pour 1,20 ?

Que diriez-vous d'emprunter le célèbre opérateur d'accès au C++ pour la syntaxe de plage inclusive ? ??

@nikomatsakis et @rust-lang/libs (je ne sais pas comment marquer cela), que ressentiriez-vous si je soumettais un PR qui déplace les structures vers un problème de suivi différent, afin que nous puissions parler de la stabilisation pour eux là? Je pense que ce serait un bon moyen d'avancer pour les stabiliser plus tôt en attendant que la nouvelle syntaxe soit implémentée/installée.

cc @rust-lang/libs (seules les personnes d'une équipe peuvent taguer la leur ou d'autres équipes)

Merci @eddyb !

@clarcharr Basé sur https://github.com/rust-lang/rust/pull/42275#discussion_r119211211 , je pense que ce serait apprécié.

Suis-je trop tard pour le train de la proposition de syntaxe ?
Le courant ressemble à quelqu'un qui essaie d'attribuer la valeur à la tranche.

for i in a..b {} // [a..b) 
for i in a..+b {} //[a..b] 
for i in a-..b {} //(a..b) 
for i in a-..+b {} // (a..b]

Cette syntaxe rendrait impossible l'ajout d'implémentations Add pour les plages à l'avenir. Je ne sais pas vraiment si c'est un problème car je ne suis pas vraiment sûr de ce que ferait une implémentation de Add .

D'accord pour le suivi plus. Changé en préfixe.

Parce que a.. , ..b et .. sont des constructions valides dans Rust, cela produit toujours des ambiguïtés avec les opérations mathématiques :/

a... / a..= / a..+ ne serait pas valide, n'est-ce pas ? Étant donné qu'avoir une plage illimitée incluant un point final n'a pas vraiment de sens.

Je ne serais pas trop inquiet pour Add , il ne semble pas que ce soit une chose trop courante à faire avec les plages, et si vous le vouliez, vous pourriez faire (x..+y) + z ?

Edit : peu importe, je viens de comprendre ce que tu voulais dire. Ce serait a..+b qui serait ambigu, non ? Puisque maintenant, cela signifie a.. + b .

@daboross Je ne dis pas que c'est une bonne ou une mauvaise idée, mais cette implémentation (ou une variante de celle-ci) pourrait être quelque chose que nous souhaitons pour les gammes à l'avenir :

impl<T> Add<T> for RangeFrom<T> where T: Add<T> {
    type Output = RangeFrom<T>;
    fn add(self, rhs: T) -> RangeFrom<T> {
        (self.start + rhs)..
    }
}

Cet impl spécifique peut être ou non une bonne idée, mais il ne m'a pas fallu trop de temps pour le proposer comme cas d'utilisation futur possible. Je pense que ce serait une mauvaise idée d'exclure la possibilité que ceci ou quelque chose comme cela soit ajouté en raison de décisions de syntaxe existantes.

Mon autre préoccupation est que le but de rejeter ... est de minimiser le risque de fautes de frappe difficiles à reconnaître et de permettre aux parenthèses de faire la différence entre deux significations différentes de l'abstrait a..+b se sent comme ça reviendrait dans cette direction.

De plus, je n'ai pas encore vu de justification solide pour a-..b et a-..+b au-delà de "ne serait-ce pas bien par souci d'exhaustivité" alors que le .. actuel et le projet ..= deux ont des justifications connues et valides.

Vous ne pouvez pas utiliser + pour cela car cela rend la syntaxe de l'expression ambiguë.

EDIT : bien que, je suppose, cela rendrait possible l'implémentation de plages inclusives entièrement dans la bibliothèque, car vous finiriez par avoir une implémentation de <Range as Add<{integral}>>::Output = InclusiveRange .

Je peux suggérer la variante ..! . Il a une rime productive avec .. et met davantage l'accent sur le dernier point, ce qui le rend plus visible.

Bien sûr, cela entrerait en collision avec l'opérateur ! mais, honnêtement, je ne pouvais pas imaginer la situation où l'on aurait besoin de mettre ! dans une sous-expression liée.

..! a un problème d'intuitivité. Un nouveau venu qui n'est pas encore familiarisé avec la syntaxe pourrait facilement mal comprendre que ..! signifie "jusqu'à, mais pas..."

Il entre également en collision avec la syntaxe pour "plage jusqu'au complément au niveau du bit de..." (ce qui le mettrait dans une situation similaire à l'utilisation de + )

Accepter. Mais d'un autre côté, ..= peut également être mal interprété comme l'un des opérateurs d'affectation.

À quoi attribueriez-vous s'il s'agissait d'un opérateur d'attribution ?

Basé sur la proposition de @snuk182 :

a...b // [a; b] shorthand for RangeIncusive
a..-b // [a; b) new Range shorthand 
a..b // [a; b) old Range shorthand exists for compatibility

Je doute que nous ayons besoin d'autres combinaisons. Dans tous les cas, il peut être ajouté ultérieurement :

a-..b // (a; b]
a-.-b // (a; b)  

Bien que la dernière option semble un peu bizarre. ^_^

Veuillez arrêter de proposer une syntaxe contenant un opérateur unaire, c'est- a..-b dire a..!b , a..*b , a..&b ou a?..b , ceux-ci ne seront jamais accepté.

..! a un problème d'intuitivité. Un nouveau venu qui ne connaît pas encore la syntaxe pourrait facilement se méprendre..! pour signifier "jusqu'à, mais pas..."

..= a le même problème avec l'intuitivité. Quiconque voit un = s'attend à une affectation ou à une comparaison. Je reconnais que cette syntaxe résout complètement le problème de distinction car chaque fois que je vois ..= , je ne peux pas m'empêcher de me demander ce que fait ce signe égal ici.

La seule syntaxe proposée qui soit à la fois assez intuitive et cohérente avec la syntaxe actuelle est ... . Mais il semble que le navire a navigué.

Les nouveaux arrivants devront de toute façon consulter les documents fréquemment. Même avec ... ils regarderaient les documents. Ce n'est pas évitable. Mais ..= a un bon mnémonique ( up to et equal to ) afin qu'ils n'aient pas à consulter fréquemment la documentation de cet opérateur.

Et si l'opérateur ... restait tel quel, mais à la place on changeait l'opérateur .. en ..⎵ , c'est-à-dire deux points et un espace (je devais mettre ça '⎵ ' car un espace normal ne s'afficherait pas sur cette page Web). Ce serait le seul endroit dans la langue où l'espace blanc compte. Ce serait également un changement radical, car tout code comme a..b se plaindrait qu'il n'y a pas d'opérateur tel que .. , et conseillerait d'ajouter au moins un espace après les points. Je pense que l'espace les rend suffisamment distincts visuellement :

a.. b
a...b

@tommit Je ne pense pas que ce serait une bonne idée pour être honnête.

L'opérateur est actuellement assez flexible concernant les espaces blancs, par exemple : a..b et a .. b sont les mêmes. C'est probablement pour le rendre cohérent avec d'autres opérateurs, tels que a+b et a + b . Ceux-ci, bien sûr, font la même chose et permettent aux gens d'utiliser différents styles de syntaxe. C'est une bonne chose si vous me demandez!

Pour ajouter à cela, la notation ..= est cohérente avec les notations <= et >= (qui sont également considérées comme _inclusive_).

Il est toujours bon de vérifier quelles sont les autres possibilités, mais ce n'est probablement pas la bonne solution.

Accepter. Comparé à <= et >= , ..= semble plausible, voire logique.

Soit dit en passant, si vous êtes un fan de ... ou si vous n'aimez tout simplement pas à quoi ressemble ..= , alors la solution de compromis serait d'utiliser une police avec des ligatures de programmation, comme FiraCode avec une ligature spéciale pour ..= , qui peut être mappé sur ... , ou même quelque chose de bizarre, comme ⩷, ⩦ ou ≔.

Modification radicale de tous les codes de rouille existants à l'aide de plages... mortes à l'arrivée,
Pardon. Si quelqu'un a une proposition vraiment sérieuse et rétrocompatible pour
répondre aux préoccupations qui ont été soulevées, et il n'a pas été discuté
déjà, écoutons-le, mais gardons au moins ça comme standard, ouais ?
Ce fil est plein d'abris à vélos et l'équipe a déjà pris une décision donc
c'est une barre haute à franchir.

Dans tous les cas, il semble encore y avoir beaucoup de bikeshed en cours sur la syntaxe réelle. J'ai déposé #43086 pour stabiliser au moins les structures, les traits et les impls afin que la fonctionnalité de base puisse être utilisée (il semble y avoir une demande, voir le commentaire de @ retep998 ci-dessus).

L'éléphant dans la pièce est que .. est en fait le vrai problème ici en raison de son aspect symétrique mais de sa signification asymétrique. La "bonne chose à faire" impliquerait probablement de le déprécier, mais il n'y a aucune volonté de le faire car tant de code l'utilise déjà.

Déprécier le ... parfaitement cohérent (apparence symétrique, sens symétrique) est la solution de facilité, mais au prix d'ajouter un autre opérateur incohérent dans ..= . Cela ressemble à ajouter une mauvaise conception pour contourner la mauvaise conception précédente.

Il y a un autre problème à cause de cette double incohérence : il n'y a pas de bonne façon d'ajouter les deux dernières variantes d'inclusion restantes (exclusives des deux côtés et exclusives du côté gauche uniquement). Étant donné que .. et ..= auraient déjà un = implicite sur le côté gauche, nous devrions annuler cela d'une manière ou d'une autre, éventuellement avec un < . Ils devraient donc ressembler à quelque chose comme ça :

  • <..= pour (a; b]
  • <.. pour (a; b)

Bonne chance pour deviner correctement ce que cela signifie en tant que nouveau venu. Donc, ils ne seraient probablement (à juste titre) même jamais considérés comme ajoutés.

Si .. n'était pas si ancré ou n'existait même pas, proposer un design cohérent pour tout cela à partir de zéro ne semble pas si difficile, par exemple :

  • .. (ou ... ) pour [a; b]
  • ..< pour [a; b)
  • <.. pour (a; b]
  • <..< pour (a; b)

J'ai le sentiment que les deux dernières variantes pourraient être utiles à un moment donné, faut-il vraiment bloquer le chemin vers elles si rapidement ? Dans tous les cas, la seule bonne raison de choisir ..= plutôt que de déprécier .. est de casser beaucoup moins l'ancien code, mais ce serait au mieux un mal nécessaire, rien à célébrer.

_Edit : Ajout d'un exemple et de quelques commentaires pour plus de clarté._

Je suis d'accord avec @rkarp sur le fait que .. est le vrai problème ici, pas ... ou ..= . Le sens asymétrique est particulièrement mal compte tenu que d' autres ( les plus populaires) langues font réellement donner un sens symétrique à elle. Kotlin, Ruby et Haskell considèrent que 5 est compris entre 3, 5, par exemple. Les articles mathématiques semblent également favoriser cela. Le pire ici est que les débutants n'ont aucune chance de deviner le comportement de 3..5 dans Rust : vous décideriez soit que 4 et seulement 4 est membre de la plage 3..5 (itération sur les points) ou que les deux 3 et 5 sont également dedans (itération sur « tout ce que nous pouvons voir » et l'extrapolation des points).

Je ne suis pas d'accord sur la difficulté de changer cela cependant. Je pense que la suggestion de

[1..4] // 1, 2, 3, 4
[1..4[ // 1, 2, 3
]1..4] // 2, 3, 4
]1..4[ // 2, 3

Toute occurrence de x..y (sans crochets) pourrait être traduite en [x..y[ et émettre un avertissement du compilateur. Après quelques versions, le compilateur pourrait simplement refuser de compiler des notations de plage "nues" et peut-être même proposer des outils pour convertir automatiquement vers la nouvelle notation.

https://github.com/rust-lang/rust/issues/28237#issuecomment -274216603 ce n'est pas une idée nouvelle et nous ne pouvons pas l'utiliser pour les raisons que nous avons déjà mentionnées.

Je suis tout à fait d'accord avec l'idée que, si nous concevions le langage à partir de zéro avec le recul, nous voudrions considérer ensemble les syntaxes des plages exclusives et inclusives. Je pense que ..= n'est pas l'opérateur idéal pour une plage inclusive ; c'est simplement la meilleure option actuellement sur la table. Mais déprécier l'opérateur de gamme exclusif actuel serait excessivement douloureux et rebutant pour les utilisateurs et les projets Rust existants.

Il existe de nombreuses autres propositions qui pourraient fonctionner. Par exemple, je n'ai pas vu de ..@ proposé, et x..@y me semble évocateur. Le défi consiste à trouver quelque chose de plus convaincant que la proposition actuelle, tout en conservant l'absence d'ambiguïté.

Je voulais souligner le commentaire de @ssokolow il y a 2 mois, comme ma vue préférée de la symétrie :

  • ..4 contient des choses < 4
  • ..=4 contient des choses <= 4

Je pense que nous n'avons besoin que d'une gamme inclusive, c'est plus simple.
Vous pouvez toujours ajouter + 1 ou -1 pour modifier la plage.
Et .. c'est mieux, parce que .. c'est plus simple que ... !

@AlexanderChen1989 Comme cela a déjà été dit dans plusieurs articles sur ce fil, ce n'est pas possible car changer la signification de .. casserait le code existant.

De plus, ce n'est pas si simple en fait. Plus particulièrement, +1 et -1 peuvent provoquer un débordement/sous-dépassement d'entier.)

Voici un exemple qui fonctionne dans nightly (via l'ancien candidat pour la syntaxe de plage inclusive) où...

  • ... quelle que soit la boucle que vous mettez en premier, paniquera en cas de débordement/sous-débogage dans les versions de débogage
  • ... ils se comporteront complètement à l'opposé des versions prévues dans la version (c'est-à-dire que le "0 à 0" sera itéré 256 fois et le "0 à 255" ne sera pas itéré du tout)
#![feature(inclusive_range_syntax)]
fn main() {
    let max = 255u8;
    let user_provided = 0u8;

    for x in 0...user_provided-1 {
        println!("(0 to 0, exclusive via 'inclusive - 1'): {}", x);
    }

    for x in 0..max+1 {
        println!("(0 to 255, inclusive via 'exclusive + 1'): {}", x);
    }
}

8 propositions de syntaxe mortes à l'arrivée ont été faites depuis que l'équipe linguistique a pris sa décision. Les nouveaux arrivants s'il vous plaît lire le fil. Nous avions de très bonnes raisons pour prendre les décisions que nous avons prises, je le promets.

À mon humble avis, l'OP devrait être mis à jour pour indiquer qu'il ne devrait plus y avoir de discussion sur la syntaxe dans ce fil et que toute proposition de syntaxe de plage exclusive (c'est-à-dire les plages (a, b) et (a, b]) devrait être déplacée vers un autre fil.

Cela ne devrait parler que de choses qui doivent être faites pour stabiliser le plan actuel.

@clarcharr J'ai pris une décision principalement unilatérale et l'ai ajoutée au PO, bonne idée. Si le bruit continue, je voterais pour verrouiller le fil.

Bonjour, je suis nouveau et j'aimerais commencer à travailler sur celui-ci. Je vais essayer d'écrire le PR pour ajouter ..= comme synonyme de ... dans les modèles, déprécier ... dans les expressions et afficher une erreur indiquant que la syntaxe a été modifiée en ..= . Est-ce que ce son est correct ?

@Badel2 cool. J'ai en fait commencé -- je vais bientôt pousser ma branche et la lier ici.

@durka juste pour clarifier - proposez-vous de laisser @Badel2 continuer à partir de votre succursale ? Pourriez-vous les encadrer dans le cadre du travail de la période d'implémentation ? Ils sont dans le canal Gitter.

Je suis également d'accord que le problème réel est .. . Ainsi, la solution la plus favorable est de déprécier (ne pas remplacer tout de suite, donc cela ne __pas__ casserait le code existant) le .. en faveur de quelque chose comme ..< (il n'y aura pas de confusion entre a..<b et (a..)<b , puisque le .. finira par cesser d'exister).

@hyst329 Veuillez lire les messages déjà

Le tout premier message dit, en gras, "Plus aucune discussion sur la syntaxe ne devrait avoir lieu dans ce fil."

Cela mis à part, ce que vous décrivez a déjà été proposé ici à plusieurs reprises par d'autres qui n'ont pas lu la discussion existante et plusieurs raisons sont données en réponse pour lesquelles ce n'est pas une option viable.

Désolé, ce n'est pas très constructif, mais chaque fois que je vois ..= et que j'essaie de me souvenir de quoi il s'agit, cela ressemble à un opérateur d'affectation similaire à += ou <<= . C'est très déroutant que ce ne soit pas le cas. (Bien que, certes, cela ait été hors contexte, par exemple « prise en charge initiale ..= syntaxe

@SimonSapin J'ai exprimé la même critique de manière plus constructive ci-dessus, suggérant plutôt ..^ : https://github.com/rust-lang/rust/issues/28237#issuecomment -304325663

Pour moi, un gros point qui parle pour ..= est une sorte de cohérence avec swift (qui a ..< .. pour les gammes exclusives et ..= .

@SimonSapin Je ne pense pas qu'il y ait quelqu'un qui en soit complètement satisfait. Le problème, c'est que des centaines de commentaires ont malheureusement confirmé qu'il n'y avait pas de meilleure alternative.

Ce correctif a réussi à me convaincre que ne rien faire est mieux que de gâcher la syntaxe du modèle actuel uniquement pour couvrir les cas extrêmes.

.. a très peu de cas d'utilisation dans les modèles et vous pouvez toujours vous en passer.

... peut être remplacé par un RangeInclusive ou un (Bound<T>, Bound<T>) dans les expressions qui en ont vraiment besoin. C'est plus verbeux mais facile à comprendre.

@UtherII

... et j'étais convaincu que ... est intenable au moment où j'ai été sauvé d'un bogue subtil par le message "Vous ne pouvez pas utiliser la syntaxe de plage inclusive sur stable" du compilateur.

Il est tout simplement trop facile d'appuyer accidentellement sur . une fois de trop (ou, compte tenu des mécanismes impliqués, une fois de trop peu) lorsque vous appuyez plusieurs fois de suite rapidement.

J'ai coché la case "Changer pour accepter ..= comme synonyme de ... dans les motifs et pour accepter ..= dans les expressions" car c'est déjà le cas après #44709 avec le dotdoteq_in_patterns et inclusive_range_syntax respectivement. Ce qui reste est juste la documentation et la stabilisation.

Demande de stabilisation

J'aimerais stabiliser la gamme inclusive à 1,26 (bêta le 30 mars, stable le 11 mai) ou avant. Un PR de stabilisation a été soumis en tant que #47813.

Résumé

Les 3 fonctionnalités suivantes seront stabilisées :

  • inclusive_range_syntax — La syntaxe a..=b et ..=b dans une expression :

    for i in 1..=10 {
        println!("{:?}", &a[..=i]);
    }
    
  • dotdoteq_in_patterns — La syntaxe a..=b dans un motif :

    match c {
        b'0'..=b'9' => c - b'0',
        b'a'..=b'z' => c - b'a' + 10,
        b'A'..=b'Z' => c - b'A' + 10,
        _ => unreachable!(),
    }
    

    (Remarque : la syntaxe a...b est toujours acceptée sans avertissements)

  • inclusive_range — Les types std::ops::{RangeInclusive, RangeInclusiveTo} et leurs champs :

    let r = 1..=10;
    assert_eq!(r.start, 1);
    assert_eq!(r.end, 10);
    

Documentation

Plusieurs PR de documentation sont soumis par @alercah , merci !

Essais

Vous pouvez trouver des cas de test dans :

Questions non résolues

  • L'utilisation de a..=b dans une boucle for a des performances bien inférieures à celles de a..(b+1) raison de son next() plus complexe et moins convivial pour les optimiseurs. Ceci est actuellement suivi dans #45222. Ceci est actuellement atténué par #48012 lors de l'utilisation de méthodes d'itérateur au lieu d'une boucle for.

    Nous pourrions avoir besoin de garder les champs de RangeInclusive instables si nous ne voulons pas encore nous engager dans la conception dans rust-lang/rfcs#1980.

Nous pourrions avoir besoin de garder les champs de RangeInclusive instables si nous ne voulons pas encore nous engager dans la conception dans rust-lang/rfcs#1980.

+1
Est-il nécessaire d'exposer les champs de plage directement, plutôt que via une interface basée sur des méthodes ?

@rfcbot fcp fusionner

Conformément au résumé de stabilise la syntaxe de plage inclusive ( ..= ).

(Cela dit, je trouve les performances inférieures de ..= légèrement inquiétantes, et je me demande s'il est logique de faire en sorte que ..= ne Iterator pour le moment, dans afin d'atténuer cela.)

Le membre de l'équipe @nikomatsakis a proposé de fusionner cela. L'étape suivante est l'examen par le reste des équipes taguées :

  • [x] @BurntSushi
  • [x] @Kimundi
  • [ ] @KodrAus
  • [x] @alexcrichton
  • [x] @aturon
  • [x] @cramertj
  • [x] @dtolnay
  • [x] @eddyb
  • [x] @nikomatsakis
  • [x] @nrc
  • [x] @pnkfelix
  • [x] @sfackler
  • [ ] @sansbateaux

Aucune préoccupation actuellement répertoriée.

Une fois qu'une majorité de réviseurs approuvera (et aucun ne s'y opposera), cela entrera dans sa dernière période de commentaires. Si vous repérez un problème majeur qui n'a été soulevé à aucun moment de ce processus, veuillez en parler !

Consultez ce document pour plus d'informations sur les commandes que les membres de l'équipe tagués peuvent me donner.

Je me demande s'il est logique de faire ..= pas directement implémenté Iterator pour le moment, afin d'atténuer cela.

Ces traits stables sont implémentés pour RangeInclusive<T> pendant au moins quelques T s dans Nightly actuel : Iterator , FusedIterator , ExactSizeIterator , Debug , Clone , Eq , PartialEq , Hash , TrustedLen .

@SimonSapin J'oublie, avons-nous déjà stabilisé la structure? (En d'autres termes, est-ce observable ?) Je supposais que ce n'était pas le cas.

cela dit, je pense aussi vraiment, vraiment que 1..2 et 1..=2 devraient être utilisables dans tous les mêmes endroits, ce qui plaide contre tout changement ici, et suggère à la place que nous devrions simplement poursuivre les atténuations et améliorer optimisations.

Pourquoi pas des plages de cas particuliers où end == MAX ? Cela pourrait conduire à ce que les plages les plus inclusives aient le même code que les plages exclusives, à l'exception de celles qui vont directement à la frontière ont plus de code. Étant donné que la branche end != Max ne modifierait jamais end , elle pourrait facilement être intégrée par l'optimiseur.

@nikomatsakis Non, les structures sont instables pour le moment. Mais la proposition de @kennytm inclut de les stabiliser.

@SimonSapin

Non, les structures sont instables pour le moment. Mais la proposition de @kennytm inclut de les stabiliser.

Je vois; en effet, c'est pourquoi j'ai mentionné que nous devions supprimer l'impl Iterator maintenant ou jamais. =)

@SimonSapin Je ne pense pas que nous puissions stabiliser la syntaxe de l'expression a..=b sans stabiliser la structure. Cependant, nous pourrions laisser les champs instables, si nous pensons pouvoir le modifier.

Bon, je ne voulais pas dire que nous ne devrions pas stabiliser les types lors de la stabilisation de la syntaxe pour la construction des valeurs de ces types.

Huzzah d'avoir échappé à la gamme syntaxe bikeshed et stabilisée ! :tada:

Étant donné une machine à remonter le temps, je dirais qu'aucun des types Range n'est :Iterator , et qu'ils sont juste :IntoIterator . Mais dans l'état actuel des choses, je pense que la cohérence avec Range est la meilleure option. Nous pouvons mettre ce cas avec Chain dans le seau "Eh bien, il s'avère que l'itération interne est parfois

Une autre chose qui n'était pas résolue, également liée à l'itération : voulons-nous nous engager sur une représentation particulière du RangeInclusive une fois l'itération terminée ? À l'heure actuelle, il se termine à 1..=0 , mais d' autres options ont été discutées . Je ne sais pas si la documentation serait suffisante pour empêcher les gens de s'y fier, bien que la documentation actuelle rende la plage de post-itération assez inutile, ce qui au moins la décourage.

Nous pouvons mettre ce cas avec Chain dans le seau "Eh bien, il s'avère que l'itération interne est parfois plus rapide".

Je pense que nous avons vraiment besoin de le réparer pour n'avoir pas moins de performances qu'une gamme exclusive ; il n'y a aucune raison fondamentale pour cela.

il n'y a aucune raison _fondamentale_ pour cela.

Cela dépend des invariants que nous pouvons appliquer. Dans les deux formulations précédentes avec un peu d'état supplémentaire, rien n'imposait que ce bit était réellement défini lorsque nous avions terminé l'itération (et en fait il n'était pas défini sur des littéraux comme 100..=0 ), donc la boucle la condition de sortie doit être composée, ce qui signifie que LLVM n'est plus disposé à la dérouler pour nous, nous obtenons donc de moins bonnes performances. Réparer complètement cela semble signifier soit agrandir la structure et ne pas avoir de champs pub, faire RangeInclusive: !Iterator , soit améliorer LLVM pour optimiser ce type de boucles.

Cela dit, j'ai essayé différentes manières d'écrire RangeInclusive::next , et il semble que le choix de mon passé de faire correspondre sur un Option<Ordering> rend LLVM très triste - le simple fait de mettre des opérateurs de comparaison à la place donne bien meilleur assemblage. Modifier les relations publiques vers le haut : https://github.com/rust-lang/rust/pull/48057

Étant donné une machine à remonter le temps, je dirais qu'aucun des types Range n'est :Iterator, et qu'ils sont juste :IntoIterator. Mais dans l'état actuel des choses, je pense que la cohérence avec Range est la meilleure option. Nous pouvons mettre ce cas avec Chain dans le seau "Eh bien, il s'avère que l'itération interne est parfois plus rapide".

Je suis fondamentalement d'accord avec cela.

:bell: Ceci entre maintenant dans sa dernière période de commentaires , selon l' examen ci-dessus . :cloche:

:bell: Ceci entre maintenant dans sa dernière période de commentaires , selon l' examen ci-dessus . :cloche:

@rfcbot fcp annuler

@withoutboats et @KodrAus n'ont pas coché leurs cases.

Proposition de @cramertj annulée.

Le membre de l'équipe @cramertj a proposé de fusionner cela. L'étape suivante est l'examen par le reste des équipes taguées :

  • [x] @alexcrichton
  • [x] @aturon
  • [x] @cramertj
  • [x] @dtolnay
  • [x] @eddyb
  • [x] @nikomatsakis
  • [x] @nrc
  • [x] @pnkfelix
  • [x] @sfackler
  • [ ] @sansbateaux

Aucune préoccupation actuellement répertoriée.

Une fois qu'une majorité de réviseurs approuvera (et aucun ne s'y opposera), cela entrera dans sa dernière période de commentaires. Si vous repérez un problème majeur qui n'a été soulevé à aucun moment de ce processus, veuillez en parler !

Consultez ce document pour plus d'informations sur les commandes que les membres de l'équipe tagués peuvent me donner.

:bell: Ceci entre maintenant dans sa dernière période de commentaires , selon l' examen ci-dessus . :cloche:

@rfcbot fcp concern Les modèles de plage ont un problème de priorité d'opérateur - https://github.com/rust-lang/rust/issues/48501.

( @petrochenkov La syntaxe est <strong i="6">@rfcbot</strong> concern KEYWORD , sans fcp . Cependant, je pense que seul le membre de l'équipe tagué peut enregistrer une préoccupation.)

La dernière période de commentaires est maintenant terminée.

Si #48501 est suffisant pour bloquer la stabilisation, je suppose que nous devons attendre que #48500 fusionne (et se stabilise) ? Ugh, j'espère que nous pourrons trouver un chemin plus rapide. Cette fonctionnalité a été si longue à venir et est maintenant dans un état précaire où les messages d'erreur pointent les gens vers une syntaxe instable.

@durka
Je ne pense pas que cette stabilisation nécessite d'attendre la stabilisation https://github.com/rust-lang/rust/pull/48500.
... dans les modèles existe toujours et il a toujours l'ancienne priorité, donc si vous avez &BEGIN ... END dans un modèle (cela devrait être assez rare, je suppose), il y a toujours une option pour ne pas le changer en ..= pendant un certain temps.

Je pense que nous pouvons stabiliser le #48500 assez rapidement

Personnellement, je serais d'accord avec un atterrissage "insta-stable"

inclusive range a été stabilisé car la demande d'extraction #47813 a été fusionnée mais ce n'est pas dans la version 1.25, pourquoi ? Bien que la pull request ait été fusionnée le 16 mars

@mominul, une fonctionnalité n'est disponible qu'après avoir été fusionnée dans la branche master, donc ..= est disponible à partir de 1.26, pas 1.25.

De cette façon, vous pouvez les tester en version bêta et tous les soirs avant qu'ils ne deviennent stables.

Merci pour les contributions @kennytm et @clarcharr ! La version Rust 1.26 n'est définitivement pas ennuyeuse, du moins pour moi ! :le sourire:

Je sais qu'il est trop tard pour participer à cette discussion, mais pourquoi ne pas omettre entièrement la syntaxe .. et utiliser des mots à la place ?

Dans Scala, vous avez 1 to 4 qui génère [1, 2, 3, 4] , 1 until 4 qui génère [1, 2, 3] , et un mot-clé optionnel by qui suit qui indique la taille du pas : 1 to 10 by 2 = [1, 3, 5, 7, 9] .

Cela rend l'intention plus claire et évite l'erreur "par défaut" qui semble si préoccupée par tout le monde.

Certes, cela casse tout le code existant, si la syntaxe d'origine n'est pas prise en charge.

@ElectricCoffee dans les gammes de rouille to et until comme mots-clés afin de prendre en charge cela, et ce serait un changement beaucoup plus important.

Cela fonctionne bien dans Scala, mais les choix de conception de Rust diffèrent largement.

@ElectricCoffee bien que j'aimerais ressentir cela, je ne pense pas qu'il soit souhaitable d'ajouter les mots-clés supplémentaires pour cela.

Je pense que les mots-clés de langage intégrés doivent être réduits au minimum, car ils pourraient entrer en collision avec des noms de fonctions ou de variables.

Bien que to et until ne soient pas des mots utilisés dans le std (pour autant que je sache), je suis sûr que ce sont des mots courants utilisés dans d'autres caisses et projets.

@daboross c'est en fait un point juste que je n'ai pas pris en compte, bien que cela soit dit, a .. b signifie dans un sens a to b , peu importe ce que a et b sont en réalité.

Et oui, @timvisee ils le sont probablement.

@ElectricCoffee Mais si to signifiait ..= et until signifiait .. vous devriez écrire a until b , pas a to b au lieu de a .. b . Comme vous pouvez le voir, il n'est pas "plus" intuitif d'utiliser ces mots que les opérateurs. Mais il serait plus verbeux d'écrire until partout où .. est utilisé, car c'est beaucoup plus courant que ..= (donc si des mots ont été utilisés, .. devraient être affectés au mot le plus court).

Et vous avez tout à fait raison à ce sujet @Boscop , c'était cependant juste un exemple de la façon dont les mots pouvaient être faits.

Je crois que j'ai vu to pour exclusif et upto pour inclus dans certaines langues également.
Tout cela n'était qu'une idée.

Dans Scala, la plage inclusive est plus utilisée que la plage exclusive, et se voit donc attribuer le mot le plus court.

@timvise On peut simplement utiliser a.to(b) et a.until(b) , aucun mot-clé supplémentaire n'est nécessaire (et cela ne rend pas la syntaxe beaucoup plus maladroite).

@ hyst329 Je n'y ai même pas pensé. Je dois dire que j'aime beaucoup cette idée ! Vous avez en effet raison.

Je ne crois pas cependant que ce serait un remplacement complet approprié pour la syntaxe actuelle (/new). Mais ce serait un bel ajout.

Je suis d'accord avec le commentaire de Boscop sur l'intuitivité. Mis à part des mots comme "incluant" et "sauf", l'anglais courant ne fait pas vraiment la distinction entre les gammes inclusives et exclusives assez fortement pour qu'il y ait un raccourci prêt à l'emploi.

À moins qu'il ne soit utilisé dans un contexte où « A à B » est également utilisé, il est ambigu de savoir si « A à B » signifie une gamme inclusive ou exclusive dans le discours quotidien ici dans le sud de l'Ontario, au Canada, et « jusqu'à » est associé avec suffisamment de temps pour que, lorsqu'il est utilisé dans ce sens plus lâche, il n'est pas clair si l'"événement" auquel "jusqu'à" s'associe est "jusqu'à ce que nous voyions X" ou "jusqu'à ce que nous ayons traité X".

@ hyst329 Les avoir comme méthodes limiterait cependant les plages aux types de nombres. Je préférerais vraiment ne pas avoir une syntaxe pour les plages de nombres et une autre pour les plages d'autres choses.

Je suppose que nous pourrions ajouter un nouveau trait fourre-tout au prélude pour la création de plages, mais cela frise toujours le changement pour les choses qui ont des méthodes réelles to et until .

J'avoue, je pensais que la suggestion de mots-clés était une blague de poisson d'avril.
La syntaxe ..= a été stabilisée.

Le jeu. 5 avril 2018 à 13:53, David Ross [email protected] a écrit :

@ hyst329 https://github.com/hyst329 Les avoir comme méthodes limiterait
s'étend aux types de nombres, cependant. Je préférerais vraiment ne pas avoir une syntaxe pour
des plages de nombres et une autre pour des plages d'autres choses.

Je suppose que nous pourrions ajouter un nouveau trait fourre-tout au prélude pour créer
gammes, mais c'est encore à la limite d'un changement radical pour les choses qui ont
méthodes actuelles jusqu'à et jusqu'à.

-
Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/rust-lang/rust/issues/28237#issuecomment-379021814 ,
ou couper le fil
https://github.com/notifications/unsubscribe-auth/AAC3nwBj-b985q1Ez0OHDEHkG6DWV_5nks5tlloZgaJpZM4F4LbW
.

Oui, nous avons eu plus de 300 commentaires sur ce problème, et le tout premier commentaire dit :

plus aucune discussion de syntaxe ne devrait avoir lieu dans ce fil . Toute proposition différente de syntaxe de gamme exclusive doit avoir lieu sur le forum de l'utilisateur ou le forum interne, après avoir lu tous les commentaires existants et leur justification ici. Notamment, la rupture de la compatibilité descendante est un non-démarreur.

Je vais verrouiller ce problème pour l'instant, désolé si je marche sur les pieds !

Je crois que tout ce qui est couvert par ce problème est fait. Veuillez rouvrir et mettre à jour la liste de contrôle dans le message d'origine du problème s'il y a autre chose.

Cette page vous a été utile?
0 / 5 - 0 notes