Про читаемость кода
Vanya KhodorСовсем недавно мы начали говорить про существующий code style и гайдлайны к написанию кода на C++. Как сделать хорошо -- а точнее лучше -- никто не знает и не понимает. Если ощущения и опыт коллег, набросы и пожелания от заинтересованных.
В процессе набрели на ресёрч про то, что делает код читаемым, а что нет. Авторы проанализировали почти 5'000 работ про читаемость кода, выбрали 15 из них. Я так понял, самые человекоориентированные и оперирующие терминами вокруг отдельных элементов форматирования. Ниже я сделаю его tldr с какими-то вставками, но, конечно, вы всегда можете почитать оригинал : )
Дисклеймер: никто ничего не понял.
В работе были выделены 13 элементов форматирования (например, отступы), 33 уровня форматирования (например, размер отступа) и 27 сравнений (например одно сравнение это сравнить 4 размера отступа).
Из интересного, по некоторым вопросам данные в разных исследованиях расходятся. А ещё 5/15 рассматриваемых работ были признаны устаревшими == написанными более 30 лет назад.
Preface
Понятно, что объективно сказать, что такое "читаемый код", нельзя. Эта штука субъективна и не несёт в себе никакой общепризнанной нагрузки.

Авторы используют английские термины legibility и readability. В общем это про то, "как легко понять текст, который вы читаете". Авторы приводят штук 5 разных определений, но в конце сходятся в том, что readability это про семантику кода, то есть популярные идиомы, название переменных и so on, а legibility про оформление этого кода: отступы, пустые линии и прочее.
Ещё у чуваков есть солидный кусок текста (глава 3) про то, как они собирали изначальный сет статей для анализа и чем этот ресёрч отличается от предыдущего, который они проводили. Для нас тут это out of scope, но в целом было интересно.
Formatting layout
В одной из рассматриваемых работ исследовали влияние форматирования кода в общем смысле. Т.е., грубо говоря, сравнивали такой код
public float arrayAverage(int[] array) {
int counter = 0;
int sum = 0;
while (counter < array.length) {
sum = sum + array[counter];
counter = counter + 1;
}
float average = sum / (float) counter;
return average;
}
с таким
public float arrayAverage(int[] array) {
int
counter
= 0;
int sum = 0;
while (counter
< array.length) {
sum =
sum + array[counter];
counter
= counter + 1;
}
float average
= sum /
(float) counter;
return
average;
}
Что же лучше читается🧐🧐🧐
Правда исследовали они не читаемость, а влияние чтение кода на биологические процессы в мозге. Влияния не обнаружено!
Spacing
В другой работе (1983его) исследовали влияние размера отступа и блоков в коде на "читаемость" этого кода. Они смотрели на 0/2/4/6 пробелов как отступ. Из важных для нас выводов утверждается, что отступ в 2 пробела наиболее эффективен.
Ещё одна работа в этой области выясняла отличия между нулевым отступом, отступом в 2-4 и рандомным отступом в каждой строчке на читаемость программ на Pascal. Тут обнаружили, что рандомный отступ хуже других вариантов с точки зрения понимания каждой отдельной строки кода (даже отсутствия отступа). И наличие отступа в 2/4 помогает быстрее понимать весь код (респондентам приходилось просматривать меньше строк кода для получения полной картинки).
Хотя в большинстве ресёрчей какая-то зависимость нашлась, одна из них всё равно утверждает, что разницы никакой. Ну так бывает.
Другие виды выравнивания:
- выравнивание одинаковых инструкций по вертикали
- пробелы между операторами и параметрами (a+b vs a + b)
статистически не влияют на читаемость кода.
Моё ИМХО с этим не согласно, так что я бы на ревью всё равно комментик оставил.
Block delimiters
Тут исследовалась важность наличия своего отступа во вложенных блоках кода, т.е. такое
int f() {
for (int x : v) {
std::cout << x;
}
}
против
int f() {
for (int x : v) {
std::cout << x;
}
}
Никакой значимости эксперименты не показали (what).
И раз это конкретное исследование было с использованием Pascal, то заодно глядели на различные способы расстановки BEGIN/END, читай фигурных скобок в нормальных языках. Говорят, что удобнее всего, когда начало и конец скоупа на отдельных строках, хотя вообще-то этот результат был получен только опросом респондентов и не включает в себя никакие статистические эксперименты. В другом ресёрче про Java выяснили, что оставлять { на строке вместе с последним выражением удобнее.
Там же чуваки выяснили, что не обязательно использовать { и } для выделения скоупа в циклах (в контексте Java).

Однако в C/C++ аналогичный эксперимент (ну что значит аналогичный, просто пытавшийся выяснить то же самое, сама постановка и масштабы отличались) показал, что опускать фигурные скобки там, где это возможно, приводит к статзначимому росту ошибок в понимании кода.
Я топлю за то, чтобы скобки были всегда. Это и читать легче, и дебагать.
Long or complex code line
Длина строки это в целом жоский холивар. Не будем разбирать за и против тех или иных вариантов. И в историю 80 и 120 символов вдаваться не будем (хотя у ограничения в 120 не так просто найти адекватные корни). Рассматриваемое исследование (2018) показало, что строки до 80 символов более читаемы. Конец.
Ещё один вопрос связан с количеством statements в рамках одной строки. И тут примерно все работы сходятся в том, что так делать не стоит: такой подход ощутимо усложняет чтение кода.
Правда это не касается объявлений нескольких переменных в одной строке. Там статзначимых результатов не было. Если конечно вы не пишете на C++:
int a, b, *c, d = 3, e(), f(int arg);
Word boundary styles
В другой работе из 2010-ого исследовали влияние стиля на понимание кода. С точки зрения понимания смысла CamelCase и snake_case оказались равны, но второй помогал понять происходящее ощутимо быстрее. Хотя в исследовании 2 года спустя нашли другой факт в пользу CamelCase: вхождения таких переменных в код находить чуть проще.
Conclusion
Цитата из изначального ресёрча:
Our results highlight that the area is immature and many studies are inconclusive.
Мне вообще нравится поинт, что не так важно, какой у вас стайлгайд, как важно то, есть ли он у вас вообще. Стандартная библиотека в плюсах написано коряво с точки зрения читаемости, но она работает. Стиль консистентен. Так и надо.
Но я бы про многие вещи на ревью набросил : )