Rust: Supprimer l'opérateur ternaire

Créé le 29 janv. 2012  ·  29Commentaires  ·  Source: rust-lang/rust

L'un des commentaires qui m'a marqué après l'annonce 0.1 était que quelqu'un me demandait pourquoi nous avions un opérateur ternaire, puisqu'il est fonctionnellement identique à nos expressions if . Je suis sympathique à ce sentiment

Dernièrement, je me suis méfié de l'ajout rapide de fonctionnalités au langage et je pense que nous devrions être plus prudents avant de nous engager dans des choses dont nous n'avons pas vraiment besoin. L'un des mandats initiaux lors de l'annonce de Rust était de se concentrer sur la suppression de fonctionnalités (c'est dans la FAQ du langage), et je ne pense pas qu'il y ait un moyen de prétendre que nous avons réussi à cela.

Certes, l'opérateur ternaire est une fonction à faible entretien, mais son retrait est également à faible impact.

A-frontend E-easy

Commentaire le plus utile

D'accord. J'aurais aimé faire de JS un langage d'expression. La grande séparation déclaration/expression motive ?: mais Rust est exempt de cela, et if-else suffit.

/être

Tous les 29 commentaires

Je suis d'accord. Je me demandais pourquoi nous avions aussi l'opérateur ternaire.

D'accord. J'aurais aimé faire de JS un langage d'expression. La grande séparation déclaration/expression motive ?: mais Rust est exempt de cela, et if-else suffit.

/être

En tant que grand utilisateur de l'opérateur ?: en C/C++, je préfère la syntaxe compacte. Je pense aussi qu'il formate mieux lorsque l'expression est trop longue pour tenir sur une seule ligne :

let x = some_very_long_condational
     ? if_true
     : if_false

let x = if some_very_long_condational 
     { if_true}
     else { if_false}

La syntaxe peut empirer, à mon avis, si if_true et if_false ne tiennent pas sur une seule ligne. Par exemple, où devraient être placés les accolades.

Juste mes deux cents.

J'apprécie:

let x = if some_very_long_condational { 
                 if_true
           } else { 
                 if_false
           }

Il ajoute quelques lignes supplémentaires (la "ligne else" et le crochet final), mais il le maintient propre et vous pouvez ajouter autant de code que vous le souhaitez dans l'un ou l'autre.

J'utilise beaucoup l'opérateur ternaire en C++, mais je pense que la syntaxe est mauvaise. Vous avez à repérer le ? et : au milieu d'une mer d'autres jetons pour voir que c'est même un conditionnel. Avec expression-si vous avez le premier signe indiquant au lecteur "voici un conditionnel".

Eh bien, je préfère toujours la syntaxe de l'opérateur ?: . Je trouve votre choix de formatage trop détaillé, en particulier pour les cas simples où if_true et if_false sont des expressions simples (par opposition aux déclarations multiples se terminant par une expression).

Néanmoins, je ne m'opposerai pas très fortement si l'opérateur ?: est supprimé.

J'utilise également ?: partout, mais je pense toujours que le supprimer serait une bonne idée - cela libère deux (!) Sigils ASCII dans notre syntaxe d'expression. Pensez à toutes les autres choses incroyablement cryptiques que nous pourrions faire avec eux.

Une utilisation non cryptique serait de les autoriser dans le nom de prédicat.
Par exemple, "empty?()" au lieu de "is_empty()".

@marijnh ++ :)

Personnellement, je m'en fous. Igor a plaidé pour le retour du ternaire dans https://mail.mozilla.org/pipermail/rust-dev/2010-November/000110.html

Cela a été fait dans la demande de tirage #1705.

    return parent.index_of(child_a) < offset_b ? -1 : 1

semble infiniment mieux que

    return if parent.index_of(child_a) < offset_b {
        -1 
    } else {
        1
    }

Si nous devons être pythony à ce sujet,

return -1 if parent.index_of(child_a) < offset_b else 1

serait bien mieux.

Je suis d'accord, je ne comprends pas pourquoi il a dû être supprimé... Veuillez ne pas forcer les utilisateurs de Rust à écrire du code inutilement lourd/verbeux, alors qu'une pratique aussi courante (opérateur ternaire) existe dans la plupart, sinon toutes les langues.

Quoi qu'il en soit, c'est fait, mais je voulais juste ajouter ma voix à celles qui soutiennent un style de code plus propre.

cette syntaxe me manque aussi

Je pense qu'il y a trois effets de conspiration à l'œuvre ici, à savoir

1) "La grande séparation déclaration/expression" (@BrendanEich);
2) Coercition des non-booléens dans des contextes booléens ;
3) Même les langages « dynamiques » n'obtiennent généralement pas de « syntaxe dynamique » (vraies macros) et de « sémantique dynamique » (à la from __future__ import division Python) de nos jours.

(1) signifie que if ... then ... else ... est fondamentalement différent de ... ? ... : ... , ce qui est une distinction tout à fait dispensable. Il existe des cas extrêmes comme return , mais dans l'ensemble, la distinction n'est pas nécessaire.

(2) signifie que vous pouvez, dans de nombreuses langues, utiliser des expressions arbitraires comme tests ; cela ne semble pratique que tant que vous utilisez toujours votre première langue et devient ennuyeux dès que vous commencez avec votre seconde. Comme indiqué ci-dessus dans cette discussion sur false soit true — écrivez simplement if ( d.length == 0 ) ... et vous avez gagné _so_ beaucoup de clarté !

(3) signifie que vous êtes coincé avec tout ce que le comité linguistique vous donne, et quoi que ce soit, la langue sera probablement coincée avec jusqu'à ce que quelqu'un vienne, bifurque ou réécrive la base de code et lui donne un nouveau nom. Cela pourrait être différent; il pourrait y avoir des langues qui permettent, disons, use 'ternary conditions'; use 'empty lists are false'; . Il existe des précédents pour cela. Bien sûr, beaucoup de choses vont à l'encontre d'une telle flexibilité car vous devrez toujours garder à l'esprit ces "marqueurs de déviation" et vous rappeler de les copier lorsque vous copiez-collez un programme. OTOH si de simples utilisateurs pouvaient changer facilement la syntaxe et la sémantique du langage et préconditionner de telles pratiques dans des modules installables, cela pourrait grandement aider à l'évolution du langage.

@kevina Parfois, la verbosité n'est pas une mauvaise chose, mais je suis d'accord pour dire que les opérateurs ternaires nettoient très bien le code.

@caitp : qu'est-ce qui ne va pas exactement ?

return if parent.index_of(child_a) < offset_b { -1 } else { 1 }

ou l'une de mes "clauses étreintes" préférées

return 
    if parent.index_of(child_a) < offset_b { -1 } 
    else                                   {  1 }

... ou utilisez une correspondance, surtout s'il y a plusieurs conditions ...

return match parent.index_of(child_a) < offset_by {
  true  => -1,
  false => 1
}

... et bien sûr s'il est susceptible d'être réutilisé : il suffit de le déplacer dans une fonction...

return parent.is_child_before(offset_b)

Regardez ça... vous avez des options... parce que _everything_ est une expression.

Jamais dans la rouille je n'ai voulu sauver les _six caractères_ qu'il faut pour écrire if {} else {} au lieu de
() ? : , plus le chaînage de conditions supplémentaires est beaucoup plus agréable avec if-as-an-expression. (Les opérateurs ternaires imbriqués deviennent très rapidement désordonnés.)

À mon avis : lors de l'utilisation de if-as-an-expression je ne vois pas la nécessité d'injecter autant d'espaces inutiles. Je trouve également qu'il se lit plus naturellement que l'opérateur ternaire, et la verbosité supplémentaire aide à séparer visuellement les deux clauses. C'est juste mon $0.02

Je pense que vous avez peut-être mal lu ce que j'ai dit (et notez que c'était il y a quelque temps)

Je signale simplement que je ne vois pas en quoi l'opérateur ternaire semble "infiniment meilleur".
À mon avis, les formes communes sont infiniment plus belles que les formes de cas particuliers.

Le commentaire dit que parfois, les expressions conditionnelles sont très utiles, par opposition aux instructions conditionnelles. Laisser tomber les accolades câlins n'est que subjectivement une amélioration

return parent.index_of(child_a) < offset_b ? -1 : 1

vs

return if parent.index_of(child_a) < offset_b { -1 } else { 1 }

@caitp est-ce que le deuxième ici est vraiment infiniment pire que le premier ? Le if else de Rust est toujours une expression (pas une déclaration).

Mes pensées sont :

  • La seconde semble être plus lisible pour quelqu'un sans histoire d'autres langues et
  • Nous ferions probablement mieux de garder la syntaxe ? dans nos manches pour le futur sucre (peut-être lié à Option, etc.)

@mitchmindtree totalement.

Encore une fois, vous ne comprenez pas ce que disait le commentaire.

return if parent.index_of(child_a) < offset_b { -1 } else { 1 } évalue toujours le conditionnel en tant qu'expression (et peut donc être un opérande pour return ).

Les accolades sont moches, mais le point principal concerne les expressions conditionnelles, pas les accolades. Il s'agit d'être capable d'écrire return foo.bar.baz(<conditional operand>) contre if (<conditional operand>) { return foo.bar.baz(1); } else { return foo.bar.baz(2); }

Je pense que ce que nous devons vraiment comprendre, c'est que ce problème date de plus de trois ans. Étant donné que les gens n'ont pas vraiment manqué autant de ternaires en trois ans, je pense qu'il est sûr de dire qu'ils resteront supprimés.

@caitp hmm, je ne suis toujours pas sûr de suivre. Tu parles de la rouille en particulier ? Ou simplement des déclarations contre des expressions en général ?

Dans la rouille tu peux encore faire

return foo.bar.baz(if cond { 42 } else { 0 })

? (Je sais que vous ne parliez pas d'accolades, désolé pour la confusion :smile_cat: )

À l'époque, dans ToT, il n'y avait aucun moyen de le faire dans Rust.

Je n'ai pas d'opinion tranchée, mais je veux juste ajouter que si ? et : peuvent mieux être utilisés pour d'autres choses, pourquoi ne pas utiliser quelque chose comme ?? et ?: place, par exemple cond ?? 43 ?: 0 ?

Pourquoi changer la façon dont les développeurs sont habitués depuis des dizaines d'années ?

Le sam. 24 oct. 2015 02:46, Kevin Atkinson [email protected] a
écrit :

Je n'ai pas d'opinion tranchée, mais je veux juste ajouter que c'est ? et : peut
mieux vaut être utilisé pour d'autres remerciements pourquoi ne pas utiliser quelque chose comme ?? et ?:
au lieu. alors peut-être cond ?? 43 ? : 0.

-
Répondez directement à cet e-mail ou consultez-le sur GitHub
https://github.com/rust-lang/rust/issues/1698#issuecomment-150728625 .

@RenaudParis Désolé, ce que je voulais dire c'est : je n'ai pas d'opinion si ? et : peuvent mieux être utilisés pour d'autres choses, pourquoi ne pas utiliser quelque chose comme ?? et ?: place, par exemple cond ?? 43 ?: 0 ?

L'une des raisons pour lesquelles l'opérateur ternaire a été supprimé était que " ?" pourrait être utilisé pour autre chose à l'avenir. Ma suggestion était d'utiliser un autre opérateur. cond ?? 43 ?: 0 est toujours plus court que if cond {43} else {0} .

Je pense qu'il est correct d'être supprimé, mais ce ne serait pas si grave si les bracelets n'étaient pas nécessaires pour une seule expression. (Et oui, je sais à quel point c'est pénible dans l'analyseur, ça en vaut vraiment la peine - la lisibilité est très importante)

par exemple

if i ==0 
     return i
else 
      1  

ou même

if i == 0  return i
    else 1  

Ce format est meilleur que

 if i == 0   ? return i
      : 1  

ou

if i == 0   
      ? return i 
      : 1  

versets

if i ==0 {
      return i
}
else {
    1
}      

assez moche/difficile à lire pour quelque chose de si commun.

Cela devient pire mais plus facile à lire si vous avez une politique de développement contre les accolades égyptiennes.

if i ==0
{
     return i
}
else
{
     1
 }      
Cette page vous a été utile?
0 / 5 - 0 notes