Pourquoi (position <taille) est-il un modèle si répandu dans les conditionnels?

9

Dans une déclaration de condition (IF), tout le monde l'utilise (position < size), mais pourquoi?
Seule convention ou il y a une bonne raison à cela?

Trouvé à l'état sauvage:

if (pos < array.length) {
   // do some with array[pos];
}

Rarement trouvé:

if (array.length > pos) {
   // do some with array[pos];
}
Felipe
la source
7
Un cas où cela ne me dérange pas d'avoir la "variable" à droite est if (MIN <= x && x <= MAX). (Dans certaines langues, cela peut être écrit ainsi MIN <= x <= MAX; en C, c'est parfaitement légal mais ne signifie pas ce que vous pourriez penser que cela signifie).
Keith Thompson
5
Pourrait être lié à la façon dont les intervalles sont écrits [min, max]et non [max, min]. Par conséquent, il est naturel de vérifier qu'un élément xappartient à l'intervalle en écrivant min <= x <= max.
Andres F.
Quel conumdrum.
Tulains Córdova
Le deuxième exemple peut être clarifié comme si (! (Array.lengh <= pos)) ...
OldFart

Réponses:

48

Le modèle le plus profond est que nous utilisons naturellement «[chose qui varie] [comparaison] [chose qui ne varie pas]» comme ordre standard. Ce principe est vrai pour votre exemple car la position peut varier, mais pas la taille.

La seule exception courante est lors du test d'égalité, certains programmeurs s'entraînent à utiliser l'ordre inverse (connu sous le nom de conditions Yoda ) afin d'éviter le commun variable = constantplutôt que le variable == constantbogue - je ne m'en tiens pas à cette idée car je trouve l'ordre naturel décrit ci-dessus beaucoup plus lisible, principalement parce que c'est la façon dont nous exprimons l'idée en anglais, et parce que la plupart des compilateurs modernes le détectent et émettent un avertissement.

Jules
la source
3
En fonction de vos outils de développement, beaucoup avertiront (ou feront des erreurs) sur la variable = constantconstruction.
GalacticCowboy
5
+1. Recherchez "Conditions Yoda" pour plus de détails sur le constant == variablephénomène.
John M Gant
J'ai vu cette même chose récemment dans ma propre base de code (par exemple if(DBNull == row["fieldName"]) methodCall()et je me suis demandé si je devenais fou parce que la plupart du temps je l'ai vu faire l'inverse.
Andrew Gray
1
J'ajouterais également qu'il (position < size)exprime souvent une limite supérieure, donc en fait, il reformule une partie de lowerbound <= position < upperbound, avec la taille comme limite supérieure. Avec les deux contraintes explicites, le positionne peut aller qu'au milieu.
Steve314
4
C'est probablement lié à la langue; on parse " opérateur X Y " comme " X est ( opérateur Y )", comme la relation est un trait de X . En demandant la comparaison, nous demandons si X a une bonne ou une mauvaise valeur (et Y est traité localement comme une constante). Demander "pos <array.length" revient à demander: "La position est-elle correcte (inférieure à la longueur du tableau)?" Si non, quelque chose ne va pas dans la position; donnez-moi un autre poste, et je serais heureux de faire ce que vous vouliez. Mais rien ne cloche sur la longueur du tableau. Demander "array.length> pos" donne l'impression que nous devrions augmenter le tableau s'il est trop court.
14

La seule justification que j'aie jamais vue est que c'est comme des lignes de nombres ou d'autres choses d'ordre que nous avons apprises à l'école. Par exemple, nous écrivons des lignes numériques comme ceci:

<--|--|--|--|--|--|-->
   1  2  3  4  5  6

Les petites choses apparaissent à gauche des grandes choses. La même chose s'applique à d'autres choses telles que les dates (pensez à la façon dont un calendrier est présenté).

Cela se résume essentiellement à la façon dont nous pensons naturellement à l'ordre des choses. Il est plus facile de lire le premier formulaire car vous n'avez pas besoin de faire beaucoup de traitement mental dessus.

Becuzz
la source
1
Vous voulez dire que l'expression qui évalue à la plus petite valeur vient en premier dans la condition? Comment pouvez-vous être sûr que ce sera vrai si les valeurs changent un runtime?
Tulains Córdova du
@ user61852 Vous n'avez pas besoin de connaître les valeurs au moment de l'exécution. Ex: J'ai 2 valeurs que je calcule à la valeur d'exécution A et à la valeur B et je veux tester que la valeur A est inférieure à la valeur B. J'écrirais "si (valeurA <valeurB)". Que la valeur A finisse par être inférieure à la valeur B est sans importance. Il est plus facile (pour moi au moins) de regarder cela et de savoir que je recherche lorsque la valeur A est inférieure à la valeur B. Si je devais voir "si (valeurB> valeurA)", je dois m'arrêter et penser à quelle chose est la plus petite quand je vais suivre cette branche de code.
Becuzz
1
J'ai mal compris. J'ai voté contre la réponse. Maintenant, je veux voter, mais le site exige que la réponse soit modifiée afin que je puisse changer mon vote. Veuillez faire quelques modifications pour que je puisse voter.
Tulains Córdova
@ user61852 Vous devriez pouvoir changer votre vote maintenant.
Becuzz
11

Bien que ce soit principalement une question de convention, je pense que cela correspond le mieux à notre façon de penser - cela montre l'élément sur lequel nous mettons l'accent.

Si nous les traduisons en anglais, ce serait l'expression "si la position est inférieure à la longueur du tableau", où le sujet de la phrase est l'élément transitoire.

Pour l'exprimer dans l'autre sens, "si la longueur du tableau est supérieure à la position" met la longueur du tableau (supposée être une valeur fixe) dans le sujet et la position (transitoire) devient l'objet direct.

GalacticCowboy
la source
3
En fait (dans votre dernière phrase) la position devient l'objet d'une préposition. Mais je suis d'accord avec ce que vous essayez de dire. En linguistique, nous dirions que la position est le sujet et "moins que la longueur du tableau" est le commentaire . "La tendance à placer les constituants d'actualité au premier plan (phrase du sujet) est répandue." en.wikipedia.org/wiki/…
LarsH
4

Mon avis, et ce n'est que mon avis, est que c'est une convention de lisibilité. Bien que les deux soient identiques, ils se sentent différents dans mon cerveau. Je ne veux pas savoir si la taille du tableau est supérieure à la pos. Je veux savoir si pos est plus petit que la taille du tableau.

C'est comme une discussion à moitié vide vs à moitié pleine. Mathématiquement identiques, mais mon cerveau les verra différemment selon le contexte.

Personnellement, si je vois

if (array.lengh > pos) {
    // do some with array[pos];
}

Je vais commencer à penser si c'est un bug et ce que le programmeur voulait dire. Essaie-t-il de faire autre chose que la vérification des limites?

Peut-être que je ne suis tout simplement pas brillant, mais si je dois faire ce genre d'analyse sur chaque ligne de code, mon cerveau me fait mal.

Brandon
la source
3

Pour exprimer ce que certains ont essayé de faire, d'une manière différente ...

Lorsque l'ordre ne fait aucune différence dans le comportement du programme, la différence est clairement une question de ce qui est le plus lisible pour les humains. Voici une raison linguistique pour laquelle mettre le «sujet» à gauche est logique:

En linguistique, le sujet d'une phrase est ce dont on parle, et le commentaire est ce qui est dit sur le sujet. Dans cet exemple, nous pouvons supposer que positionc'est le sujet et "moins que la longueur du tableau" est le commentaire . En anglais et dans de nombreuses autres langues, le sujet est généralement exprimé avant le commentaire.
" La tendance à placer les constituants topiques au début de la phrase (sujet) est très répandue. "

Donc , une bonne règle de base est de penser à votre ligne de code comme une phrase (ou clause, dans ce cas), décider de ce que la phrase est au sujet , et de mettre ce premier si vous le pouvez. Souvent, l'objet de la phrase sera une variable plutôt qu'une constante. Mais parfois, le commentaire impliquera également une variable, vous ne pouvez donc pas vous contenter de cela.

LarsH
la source
1

C'est une combinaison de deux choses, provenant toutes deux de l'assembleur sous-jacent dans lequel les premiers langages ont été compilés (et de nombreux langages actuels aussi).

  1. Les tableaux sont des décalages de base zéro en mémoire (c'est-à-dire que le premier bloc de données est au début du bloc de mémoire alloué ... l'index 0). D'où l'utilisation de 0..n-1 pour la pièce variable.

  2. La ramification si une valeur est inférieure à une autre valeur (ou registre, etc.) est généralement une instruction unique. D'où l'utilisation de l'opérateur simple inférieur à (<).

Ainsi, le modèle est passé de l'ancien assembleur à ANSI-C (qui ressemble plus à un assembleur de macros à certains égards) et de là à Java et aux autres langages de type C.

andyb
la source
0

Comme beaucoup d'autres réponses l'ont dit, il est très souvent plus facile à lire:

[thing that varies] [comparison] [thing that does not vary]

Presque tout le monde que je connais utilise exclusivement ce style.

Il existe une exception, pour les langages de style C qui utilisent =pour l'affectation et ==pour la comparaison. Si vous tapez accidentellement:

if (variable = 5) ...

au lieu de:

if (variable == 5) ...

alors vous n'obtiendrez pas d'erreur car il s'agit d'une ligne de code valide. (Certains compilateurs et IDE vous avertiront de le faire, mais il est toujours très facile d'avoir une faute de frappe aussi simple.)

Cependant, si vous écrivez:

if (5 == variable) ...

le compilateur / interprète générera une erreur car ce n'est pas une construction valide (dans la plupart des langues, de toute façon).

Cette commutation est souvent appelée condition Yoda .

MISE À JOUR : Voici une liste des endroits où les conditions Yoda sont utiles .

Moshe Katz
la source
-1

Personnellement, je préfère ceci:

bool positionIsWithinBounds = pos < array.length;
if (positionIsWithinBounds) {
   // do some with array[pos];
}

... c'est plus de code, mais c'est aussi très facile à lire.

John MacIntyre
la source
4
+1 pour avoir donné un nom à la comparaison. Vraiment, cependant, j'aime mieux cette approche pour les conditions plus complexes, et pas tellement pour les cas simples comme celui-ci. Cela me fait en fait arrêter de penser à "tableau", "limites", "à l'intérieur", et à ce que tout cela signifie, quand je sais instinctivement ce que cela signifie posd'être > array.length. En d'autres termes, même si cela rend le sens du conditionnel très clair, cela rend en fait un peu plus difficile à lire l'OMI.
John M Gant
Encore un autre nom à suivre ...
Deduplicator
-1

C'est une question de préférence ou de convention. Si vous voulez être cohérent, il existe deux façons tout aussi raisonnables de procéder:

  1. Mettez toujours le «sujet» en premier (pensez-y comme une phrase) - la valeur sur laquelle porte le test. Ainsi, par exemple, vous écririezif (age>5)

  2. Ou placez toujours le plus petit élément en premier (pensez-y car les valeurs sont ordonnées sur votre écran dans l'ordre naturel). Ainsi, par exemple, vous écririez if (a<b)que ce code concerne principalement a ou principalement b.

Les deux conventions recommandent le premier extrait que vous avez montré au lieu du second, donc je suppose que dans ce cas particulier, vous avez votre réponse. Je dirais qu'il est sage d'éviter d'écrire du code qui viole à la fois (1) et (2) ici, car cela rendra la lecture plus difficile pour la plupart des gens.

le thon rouge
la source