Чому (позиція <розмір) є такою поширеною схемою в умовах?


9

У заяві про стан (ІФ) кожен використовує (position < size), але чому?
Лише конвенція чи є для цього вагома причина?

Знайдено в дикій природі:

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

Рідко знайдено:

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

7
Один випадок, коли я не заперечую за тим, щоб мати "змінну" справа if (MIN <= x && x <= MAX). (У деяких мовах це може бути записано як MIN <= x <= MAX; на мові C це абсолютно законно, але не означає, що ви можете вважати, що це означає).
Кіт Томпсон


5
Можливо, це стосується того, як записуються інтервали, [min, max]а не [max, min]. Тому перевіряти, чи елемент xналежить до інтервалу, записуючи лише природно min <= x <= max.
Андрес Ф.

Яка судома.
Tulains Córdova

Другий приклад можна додатково уточнити так, ніби (! (Array.lengh <= pos)) ...
OldFart

Відповіді:


48

Більш глибока закономірність полягає в тому, що ми, природно, використовуємо "[річ, яка змінюється] [порівняння] [річ, яка не змінюється]" як стандартний порядок. Цей принцип справедливий для вашого прикладу, оскільки положення може змінюватися, а розмір - не.

Єдиним загальним винятком є ​​тестування на рівність, деякі програмісти навчаються використовувати протилежний порядок (відомий як умови Yoda ), щоб уникнути загального, variable = constantа не variable == constantпомилки - я не тримаюсь з цією ідеєю, тому що я вважаю описане природне впорядкування вище набагато читабельнішим, насамперед тому, що саме так ми висловлюємо ідею англійською мовою, і тому, що більшість сучасних укладачів виявить це і видасть попередження.


3
Залежно від ваших інструментів розробки, багато хто також попередить (або помилиться) на variable = constantконструкції.
GalacticCowboy

5
+1. Шукайте в "Умовах Йоди" для отримання більш детальної інформації про це constant == variableявище.
Джон М Гант

Нещодавно я бачив цю саму річ у своїй власній кодовій базі (наприклад, if(DBNull == row["fieldName"]) methodCall()і цікавився, чи не сходить я з розуму, бо більшу частину часу я бачив, як це робилося навпаки.
Ендрю Грей,

1
Я також додав би, що (position < size)часто виражає верхню межу, тому фактично це перезавантаження частини lowerbound <= position < upperbound, розміром як верхнє обмеження. З явними двома обмеженнями, positioncan може йти лише посередині.
Steve314

4
Це, мабуть, пов'язане з мовою; ми розбираємо « оператор X Y » , як « X є ( оператор Y )», як відношення є рисою X . Задаючи порівняння, ми запитуємо, чи має X хороше чи погане значення (а Y локально трактується як константа). Запитуючи "pos <array.length", схоже на запитання: "Чи нормально положення (менше, ніж довжина масиву)?" Якщо ні, то щось не так у положенні; дайте мені іншу посаду, і я був би радий зробити те, що ви хотіли. Але щодо довжини масиву нічого поганого. Запитуючи "array.length> pos", схоже, нам слід збільшити масив, якщо він занадто короткий.

14

Єдине виправдання, яке я коли-небудь бачив, це те, що це схоже на рядки чисел чи інші замовляючі речі, які ми дізналися в школі. Наприклад, ми пишемо рядки типу:

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

Більш дрібні речі з’являються зліва від більших речей. Те саме стосується інших речей, таких як дати (подумайте, як складено календар).

Це в основному зводиться до того, як ми, природно, думаємо про порядок речей. Простіше читати першу форму, тому що не потрібно надто сильно розумово обробляти її.


1
Ви маєте на увазі, що вираз, що оцінює меншу величину, приходить спочатку в умові? Як ви можете бути впевнені, що це буде правдою, якщо значення змінить час виконання?
Тулен Кордова

@ user61852 Вам не потрібно знати, які значення знаходяться під час виконання. Наприклад: У мене є 2 значення, які я обчислюю під час виконанняA і valueB, і я хочу перевірити, що valueA є меншим, ніж valueB. Я б написав "if (valueA <valueB)". Чи не закінчується значенняA менше, ніж valueB, не має значення. Простіше (принаймні для мене) подивитися на це і знати, що я шукаю, коли valueA менша, ніж valueB. Якби я бачив "if (valueB> valueA)", я повинен зупинитися і подумати про те, яка річ є меншою, коли я збираюся дотримуватися цієї гілки коду.
Becuzz

1
Я неправильно зрозумів. Я проголосував відповідь вниз. Зараз я хочу проголосувати за це, але сайт вимагає відредагувати відповідь, щоб я міг змінити свій голос. Будь ласка, зробіть кілька редагувань, щоб я міг проголосувати.
Тулен Кордова

@ user61852 Ви маєте можливість змінити свій голос зараз.
Becuzz

11

Хоча це, головним чином, питання конвенції, на мою думку, це найкраще відповідає тому, як ми думаємо - це показує предмет, на якому ми робимо акцент.

Якщо ми перекладаємо їх на англійську, це буде фраза "Якщо позиція менша за довжину масиву", де темою речення є перехідний елемент.

Щоб висловити це інакше, "якщо довжина масиву більша за позицію", ставить довжину масиву (вважається фіксованим значенням) в тему, а позиція (перехідна) стає прямим об'єктом.


3
Насправді (в останньому реченні) позиція стає об’єктом прийменника. Але я згоден з тим, що ти намагаєшся сказати. У лінгвістиці ми би сказали, що позиція - це тема , а "менша довжина масиву" - коментар . "Схильність до розміщення тематичних складових речень спочатку (тематика) є широко поширеною." en.wikipedia.org/wiki/…
LarsH

4

Моя думка, і це лише моя думка, це те, що це конвенція про читабельність. Хоча обидва однакові, вони почуваються по-різному в моєму мозку. Я не хочу знати, чи розмір масиву більше, ніж поз. Я хочу знати, чи розмір pos менший за розміром масиву.

Це як напівпорожня проти напівповна дискусія. Математично однакові, але мій мозок побачить їх по-різному, залежно від контексту.

Особисто, якщо я бачу

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

Почну думати про те, чи це помилка чи ні, що мав на увазі програміст. Він намагається зробити щось інше, ніж перевірку меж?

Можливо, я просто не яскравий, але якщо мені доведеться робити такий аналіз у кожному рядку коду, мій біль болить.


3

По-різному висловити те, що деякі намагалися досягти ...

Коли порядок не має ніякої різниці у поведінці програми, різниця явно є питанням того, що можна зрозуміти людям. Ось мовна причина, чому розміщувати "тему" зліва має сенс:

У лінгвістиці тема речення - це те, про що говорять, а коментар - те, що говорять про тему. У цьому прикладі можна припустити, що positionце тема , а "менша довжина масиву" - це коментар . Англійською та багатьма іншими мовами тема зазвичай висловлюється перед коментарем.
" Схильність до розміщення тематичних складових речень спочатку (тематика) є широко поширеною. "

Таким чином, хороше емпіричне правило думати про вашу рядку коду в реченні (або пункту, в даному випадку), вирішити , що вирок про , і покласти , що перший , якщо ви можете. Часто те, що речення "про", буде змінною, а не постійною. Але іноді коментар також передбачає змінну, так що ви не можете просто пройти цей шлях.


1

Це поєднання двох речей, що походять від основного асемблера, до якого були зібрані ранні мови (і багато нинішніх).

  1. Масиви - це нульові зсуви в пам'яті (тобто перший фрагмент даних знаходиться на початку виділеного блоку пам'яті ... 0-індексу). Звідси використання 0..n-1 для різної деталі.

  2. Розгалуження, якщо значення менше іншого значення (або зареєструвати тощо), як правило, є однією інструкцією. Отже, використання простого менш (<) оператора.

Отже, шаблон перемістився зі старовинного асемблера в ANSI-C (який певним чином схожий на асемблер макросу), а звідти на Java та інші мови, схожі на С.


0

Як було сказано в багатьох інших відповідях, читати дуже часто:

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

Майже кожен, кого я знаю, використовує виключно цей стиль.

Є один виняток для мов стилю С, які використовуються =для призначення та ==порівняння. Якщо ви випадково набрали:

if (variable = 5) ...

замість:

if (variable == 5) ...

тоді ви не отримаєте помилку, оскільки це дійсний рядок коду. (Деякі компілятори та IDE попередить вас про це, але все-таки дуже просто отримати такий простий друк.)

Однак якщо ви пишете:

if (5 == variable) ...

компілятор / інтерпретатор помилиться, оскільки це не є дійсною конструкцією (у більшості мов, у будь-якому випадку).

Цей перемикач часто називають умовою Yoda .

ОНОВЛЕННЯ : Ось список місць, де Умови Yoda корисні .


-1

Особисто я віддаю перевагу цьому:

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

... це більше код, але також дуже легко читати.


4
+1 для назви порівняння. Дійсно, однак, мені подобається такий підхід краще для складніших умов, а не стільки для простих випадків, як цей. Це насправді змушує мене перестати думати про "масив", "межу", "всередині", і що це все означає, коли я інстинктивно знаю, що це означає posбути > array.length. Іншими словами, незважаючи на те, що це робить умовне значення дуже зрозумілим, воно насправді ускладнює читання ІМО.
Джон М Гант

Ще одна назва, яку слід слідкувати за ...
Дедуплікатор

-1

Це питання уподобань чи домовленостей. Якщо ви хочете бути послідовними, ви можете скористатися двома не менш розумними способами:

  1. Завжди ставите «предмет» на перше місце (думайте про це як про речення) - значення, про яке йде тест. Так, наприклад, ви писали бif (age>5)

  2. Або завжди поставте на перший план менший елемент (подумайте про це, як значення впорядковані на екрані у природному порядку). Так, наприклад, ви писали б if (a<b)незалежно від того, в основному цей код стосується a або здебільшого про b.

Обидві конвенції рекомендують перший фрагмент, який ви показали замість другого, тому, мабуть, у цьому конкретному випадку ви маєте свою відповідь. Я б сказав, що розумно уникати написання коду, який порушує і (1), і (2), оскільки це ускладнить читання більшості людей.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.