OVH Cloud OVH Cloud

Opérateur ternaire, indenter ?

33 réponses
Avatar
Pierre Maurette
Bonjour,

J'infidélise actuellement pas mal du coté de Php et Java. Je me rends
compte à cette occasion de l'intérêt de l'opérateur ternaire, qui est
peut-être mal vendu en C.
On peut le trouver peu lisible, mais il suffit de s'y mettre et
l'investissement est rentable, vu qu'il a la même syntaxe et le même
comportement en C, C++, Php, Java et quelques autres "C inspired" sans
doute.

Ce que j'apprécie, c'est qu'il s'agit d'un *opérateur*, avec les
possibilités qu'offre l'évaluation économique garantie.

C'est sur le style que j'aimeerais avoir des avis. J'ai lu ici que
certain guru préférait développer en plusieurs lignes.
A partir de cette expression:

running_ = status == 0 ? false : status == 1 ? true : !running_;

je peux faire:

running_ = (status == 0) ? false : (status == 1) ? true : !running_;
(parenthésage sytématique des conditions)

ou (ma préférée peut-être)
running_ = (status == 0 ? false : (status == 1 ? true : !running_));
(parenthésage sytématique de l'opérateur ternaire)

ou les deux:
running_ = ((status == 0) ? false : ((status == 1) ? true :
!running_));

Sur plusieurs lignes, par exemple:
running_ = status == 0 ?
false
:
status == 1 ?
true
:
!running_
;

Je n'aime pas trop la présentation sur plusieurs lignes, au motif
qu'elle masque l'aspect opérateur et donne l'idée d'une instruction de
contrôle de flux.

Des avis ? Merci d'avance ....

--
Pierre Maurette

10 réponses

1 2 3 4
Avatar
Jean-Claude Arbaut
Stephane Legras-Decussy wrote:
"Harpo" a écrit dans le message de news:
445e3a2a$0$20175$

Je pense que quelque chose de simple doit s'écrire simplement sans
prendre beaucoup de lignes, cela évite de browser des pages d'une
fonction avant de se rende compte qu'elle ne fait pas grand chose.



oui mais là en l'espèce, c'est quelque chose de
simple qui s'écrit compliqué en peu de ligne.

je préfère largement scroller 2 pages qu'un gamin de 12 ans
comprend que de jouer au Sudoku sur 3 lignes qui tuent...


La comparaison avec le sudoku est bien trouvée :-)
Dans le cas précis, des if-else seraient largement
préférables, mais il arrive qu'un ?: soit très clair,
voire plus clair qu'un if-else: écrire 5 lignes quand
on peut se contenter de quelques caractères tout bêtes...

dès qu'un projet devient gros, de toute facon, ça devient
globalement complexe à comprendre avec des montagnes
de fichiers donc il faut compenser
en étant toujours localement trivial amha.


Le ?: peut être trivial. Il peut aussi être imbitable, bien
sûr, suffit de jeter un oeil aux IOCCC.


Avatar
Pierre Maurette
Mais néanmoins il y a une erreur, une typo sans doute. Quelle règle
cohérente peut amener à aligner le premier ? sous le 'a' de "status" et le
second sous le 's' de "status" ? Il n'y a pas de style unique, mais je n'en
vois aucun qui arrive à ce résultat.


Eh bé, Tout ça en arriver là ? Tu ne pouvais pas le dire tout de suite ?
Sache que je n'ai plus 20 ans et ma vue baisse (ce qui me console, c'est que
ça t'arrivera aussi hé hé). J'ai fait la mise en page à la main vite fait en
mettant (croyant mettre) une tabulation de 3 espaces... Pas besoins de jouer
aux devinettes pour si peu...

Prend une femme, fait des enfants, ça t'occupera...


http://www.leconjugueur.com/frconjonline.php

J'ai cinquante ans, mon fils le plus âgé vingt-trois, et ma vue
commence à sérieusement m'inquiéter dans la vie courante. Heureusement
qu'avec un ordinateur ce genre de problème n'en est pas un.

En fait, il ne s'agissait pas du tout d'un problème de vue et nous le
savons tous les deux. Mais surtout je n'aurais rien relevé sans "A trop
forcer le trait, on se décrédibilise...".

--
Pierre Maurette


Avatar
Stephane Legras-Decussy
"Pierre Maurette" a écrit dans le message de
news:
En fait, il ne s'agissait pas du tout d'un problème de vue et nous le
savons tous les deux. Mais surtout je n'aurais rien relevé sans "A trop
forcer le trait, on se décrédibilise...".


je propose une real-TV avec Pierre et ED enfermé
dans un cube pendant 72h avec un BigMac et un PC
pour deux... :-)

Avatar
James Kanze
Emmanuel Delahaye wrote:
<présentation opérateurs ternaires>


1 ligne, pas de problèmes si il n'y en a qu'un... Par contre, si il y
en a plusieurs :


Sur plusieurs lignes, par exemple:
running_ = status == 0 ?
false
:
status == 1 ?
true
:
!running_
;



A trop forcer le trait, on se décrédibilise...


running_ = status == 0
? false
: status == 1
? true
: !running_;


Et même. De la même façon qu'on n'indente pas des else if d'un niveau
supplémentaire chaque fois, j'écris :

running_ = status == 0
? false
: status == 1
? true
: !running_;

En fait, dans les cas les plus simples (et avec un seul ?:), l'écrire
sur une seule ligne ne me gènerait pas. Je constate, en revanche, que
c'est un construct qui pose de problèmes à un bon nombre de
programmeurs ; le mettre sur plusieurs lignes semble resoudre ces
problèmes. Alors, au moins que le code soit uniquement pour moi, c'est
toujours réparti sur plusieurs lignes.

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34


Avatar
James Kanze
Simias wrote:
Pierre Maurette wrote:
running_ = status == 0
? false
: status == 1
? true
: !running_;






Il n'y a pas un petit souci dans ton indentation ?





C'est possible, mais je ne vois rien. Au lieu de jouer aux
devinettes, donne ta version...




running_ = status == 0
? false
: status == 1
? true
: !running_;




euh... on perd pas tout l'interet du ternaire la? je veux dire, c'est
utilise pour la conscision en general. La non seulement le gain par
rapport au 'classique' if est minime, mais c'est pas des plus lisible
a mon gout.


Si l'intérêt, c'est d'ajouter à l'obfuscation, on en perd en le mettant
sur plusieurs lignes. D'après mes expériences, beaucoup de programmeurs
ont des problèmes avec l'expression quand c'est sur une seule ligne.
(Quand il s'agit de plusieurs ?: embriqués, comme ici, j'en fais
partie.)

J'ajouterais egalement qu'un autre interet du ternaire c'est de
pouvoir le mettre dans un appel de fonction:


On n'importe où ailleurs où une expression est demandée. (Je m'en sers
souvent sur des return, par exemple.)

void foo(int);


// ...


int i;


//...


foo((i < 10) ? i : (i -10));


foo( i < 10
? i
: i - 10 ) ;

Ça marche aussi.

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34





Avatar
James Kanze
Stephane Legras-Decussy wrote:
"Simias" a écrit dans le message de news:
445dfba5$0$23118$
euh... on perd pas tout l'interet du ternaire la? je veux
dire, c'est utilise pour la conscision en general.



c'est quoi l'interet de la concision ?


« Good writing is clear and concise. » C'est ce que me disait
toujours mon prof d'anglais au lycée. La même chose vaut pour le
code.

On remarque bien, évidemment, qu'il y a deux critères. La
concision ne doit pas nuire à la clairté.

J'ajouterais egalement qu'un autre interet du ternaire c'est
de pouvoir le mettre dans un appel de fonction:



tu pars à la retraite, on doit jeter ton code...


Pourquoi. L'important, c'est que l'important soit ce qui se voit
d'abord. *Si* l'important dans la fonction ou l'algorithme,
c'est qu'ici, on fait un choix, les « if » s'imposent. Si
l'important, c'est qu'on appelle telle ou telle fonction, ou
qu'on initialise telle ou telle variable, l'opérateur ?:
s'impose -- l'utilisation de l'« if » devient de l'obfuscation.
Donc, par exemple, je préfère de loin :

int i = (a > b ? a : b) ;
à
int i ;
if ( a > b ) {
i = a ;
} else {
i = b ;
}

(Dans ce cas-ci, je le préfère même sans les sauts à la ligne.
Ce n'est pas le cas de la plupart des gens avec qui j'ai
travaillé, en revanche, et donc, dans un code de production,
j'écrirais le premier :

int i = a > b
? a
: b ;

Même si ça me paraît exagéré ici.)

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34


Avatar
James Kanze
Jean-Claude Arbaut wrote:
Simias wrote:
Stephane Legras-Decussy wrote:



"Simias" a écrit dans le message de
news: 445dfba5$0$23118$




euh... on perd pas tout l'interet du ternaire la? je veux dire,
c'est utilise pour la conscision en general.





c'est quoi l'interet de la concision ?




Tu as entendu parler d'Ada ;-)


Qui permet aussi du code assez conscis. Quant au COBOL, en
revanche...

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34




Avatar
Jean-Claude Arbaut
James Kanze wrote:
Jean-Claude Arbaut wrote:
Simias wrote:
Stephane Legras-Decussy wrote:

"Simias" a écrit dans le message de
news: 445dfba5$0$23118$

euh... on perd pas tout l'interet du ternaire la? je veux dire,
c'est utilise pour la conscision en general.


c'est quoi l'interet de la concision ?



Tu as entendu parler d'Ada ;-)


Qui permet aussi du code assez conscis.


Moins que le C tout de même. Mais ce n'est pas forcément une critique,
ce langage me semble assez bien fait. Il faudrait que je l'apprenne
mieux pour en dire plus.

Quant au COBOL, en
revanche...


J'ai entendu parler :-)

A l'opposé, APL...





Avatar
Harpo
Pierre Maurette wrote:


Personnellement, je ne trouve aucun sens à indenter par rapport au
début de la ligne qui peut justement être n'importe quoi.


Ce n'est pas par rapport au début de la ligne mais par rapport au niveau
courant d'indentation.

Ma logique
voudrait qu'on le fasse (éventuellement à 0, alignement) par rapport
au début de la condition ou au signe ?


Mais si tu places '?' derrière la condition, l'indentation sera
dépendante de la longueur de cette condition.
Si tu places '?' sur la ligne suivante, il me semble plus correct
d'incrémenter le niveau d'indentation.
ex avec une incrementation de 2 espaces :

if (blah) {
my_result = ( cond )
? x
: ( blurb )
? y
: etc.
}

en plus je mettrais les (condition) ? ... : ...
feuilles (les plus incluses) sur une même ligne. Mais ça se discute.

, l'important étant que les deux résultats soient alignés.


Je pense que l'important est que les branches de l'alternative soient
alignées

Mais je préfère ne pas indenter et conserver tout le caractère
opérateur.
Comme pour le

if {}
else if {}
else if {}
else {}


qui s'écrit mécaniquement mais n'est pas "évident" au début, on peut
généraliser :

cond1 ? a : cond2 ? b : ..... : condn ? x : y ;

ou alors :

cond1 ? a :
cond2 ? b :
..... :
condn ? x :
y ;


Oui, ça doit être bon aussi, on pourrait aussi écrire :

if (blah) {
my_result = ( cond ) ? x
: ( blurb ) ? y
: ( blob ) ? z
: etc.
}

C'est un cas particulier qui se produit lorsque l'imbrication se fait
systématiquement dans la branche ':'

Là où ça peut risquer de causer problème, c'est lorsqu'on a :
cond1 ? ( cond2 ? a : (cond3 ? b : c) ) : d
( les parenthèses ne sont sans doute pas nécesaires )
Il faudrait quand même indenter dans la branche '?', en fait ça ne
change pas des else if

--
http://patrick.davalan.free.fr/

Avatar
Pierre Maurette
[...]
Là où ça peut risquer de causer problème, c'est lorsqu'on a :
cond1 ? ( cond2 ? a : (cond3 ? b : c) ) : d
( les parenthèses ne sont sans doute pas nécesaires )
Il faudrait quand même indenter dans la branche '?', en fait ça ne
change pas des else if


opérateur "!" peut-être ?

Pour ce qui est de passer à la ligne (avec ou sans indentation), j'en
reste à l'idée que c'est un opérateur, et que les règles absolues sont
néfastes. (b != 0 ? a / b : MAX_INT) par exemple perd son intérêt si on
passe à la ligne. Je ne parle pas de compacité, sinon (b?a/b:MAX_INT)
serait mieux, mais de lisibilité. Eventuellement une macro. Surtout si
c'est (b != 0 ? a / b : (a < 0 ? -MAX_INT : MAX_INT)) ...

Pour le reste je passe à la ligne pour les arguments de fonctions quand
et seulement quand ils sont nombreux et/ou longs, et j'indente au
besoin les expressions arithmétiques complexes.


--
Pierre Maurette

1 2 3 4