pg.gimran.org

Удерживая программу в голове

Август 2007 · Все эссе

Перевод эссе Пола Грэма «Удерживая программу в голове». Оригинал: https://paulgraham.com/head.html. Машинный перевод (Gemini).

Translation of Paul Graham's essay 'Holding a Program in One's Head'. Original: https://paulgraham.com/head.html. Machine translation (Gemini).

Хороший программист, интенсивно работающий над собственным кодом, способен удерживать его в голове так же, как математик удерживает задачу, над которой размышляет. Математики не ищут ответы, решая примеры на бумаге столбиком, как учат школьников. Большую часть работы они проделывают в уме: они стараются понять пространство задачи настолько хорошо, чтобы ориентироваться в нём так же свободно, как в воспоминаниях о доме, где прошло детство. В своём лучшем проявлении программирование выглядит точно так же. Вы удерживаете всю программу в голове и можете манипулировать ею как угодно.

Это особенно ценно на старте проекта, ведь поначалу важнее всего иметь возможность менять то, что вы делаете. Не просто решить задачу другим способом, а изменить саму решаемую задачу.

Ваш код — это ваше понимание исследуемой проблемы. Поэтому по-настоящему понять задачу можно лишь тогда, когда весь код держится у вас в голове.

Загрузить программу в голову не так-то просто. Если оставить проект на пару месяцев, то по возвращении к нему могут уйти дни, чтобы снова во всём досконально разобраться. Даже когда вы активно работаете над программой, в начале каждого рабочего дня может потребоваться полчаса только на то, чтобы загрузить её в память. И это в лучшем случае. Обычные программисты, работающие в типичных офисных условиях, вообще никогда не входят в такой режим. Или, выражаясь более драматично, обычные программисты в типичных офисных условиях никогда по-настоящему не понимают задач, которые они решают.

Даже у лучших программистов проект, над которым они работают, далеко не всегда полностью загружен в голову. Но есть вещи, которые могут в этом помочь:

Избегайте отвлекающих факторов. Отвлечения вредят многим видам деятельности, но программированию они вредят сильнее всего, потому что программисты обычно работают на пределе объёма деталей, который способен удержать их мозг.

Опасность помехи определяется не её продолжительностью, а тем, насколько сильно она перемешивает ваши мысли. Программист может выйти из офиса и пойти купить сэндвич, не потеряв код из памяти. Но неподходящее по характеру прерывание способно полностью стереть мысли за 30 секунд.

Как ни странно, запланированные помехи могут быть хуже внезапных. Если вы знаете, что через час назначена встреча, вы даже не начнёте браться за что-то сложное.

Работайте длинными отрезками. Поскольку каждый запуск работы над программой сопряжён с фиксированными накладными расходами, эффективнее работать несколько долгих сессий, чем множество коротких. Разумеется, наступит момент, когда вы начнёте тупить из-за усталости. Это индивидуально для каждого. Я слышал о людях, способных непрерывно кодить по 36 часов, но максимум, который когда-либо удавался мне, составляет около 18, а лучше всего я работаю интервалами не более 12 часов.

Оптимум — это не предел вашей физической выносливости. У разделения проекта на части есть как минусы, так и плюсы. Иногда, возвращаясь к задаче после отдыха, вы обнаруживаете, что подсознание уже приготовило для вас готовый ответ.

Используйте лаконичные языки. Более мощные языки программирования делают программы короче. И программисты, похоже, думают о программах хотя бы отчасти на том языке, на котором их пишут. Чем лаконичнее язык, тем короче программа и тем легче загрузить её в голову и удерживать там.

Усилить эффект мощного языка можно с помощью подхода, называемого программированием снизу вверх (bottom-up programming), когда вы пишете программы несколькими слоями, где нижние служат языками программирования для верхних. Если всё сделать правильно, в голове придётся держать только самый верхний слой.

Постоянно переписывайте программу. Переписывание кода часто приводит к более чистому архитектурному решению. Но даже если бы этого не происходило, в нём всё равно была бы польза: чтобы переписать программу, её нужно полностью понять, так что нет лучшего способа загрузить её в голову.

Пишите код, удобный для повторного чтения. Все программисты знают, что писать читаемый код — это хорошо. Но самый главный читатель — это вы сами. Особенно в начале: прототип — это разговор с самим собой. А когда пишешь для себя, приоритеты меняются. Если вы пишете для других, возможно, не стоит делать код слишком плотным. Некоторые части программы легче читать, если всё расписано подробно, как во вводном учебнике. Но если вы пишете код так, чтобы его было легко перезагрузить обратно в голову, пожалуй, лучше сделать ставку на краткость.

Работайте небольшими группами. Когда вы манипулируете программой в уме, ваш мысленный взор обычно останавливается на границе кода, который принадлежит вам. Другие части вы понимаете хуже, а главное — не можете обращаться с ними вольно. Поэтому чем меньше программистов, тем сильнее проект может видоизменяться. Если программист всего один, как это часто бывает вначале, можно проводить тотальные переделки архитектуры.

Не позволяйте нескольким людям редактировать один и тот же участок кода. Чужой код никогда не понимаешь так же хорошо, как свой собственный. Как бы внимательно вы его ни читали, вы его только читали, а не писали. Поэтому, если фрагмент кода написан несколькими авторами, ни один из них не понимает его так же глубоко, как понимал бы единственный автор.

И, конечно же, вы не можете безопасно перепроектировать то, над чем работают другие. Дело не только в том, что пришлось бы просить разрешения. Вы даже не позволяете себе думать о подобных вещах. Менять архитектуру кода, у которого несколько авторов, — всё равно что менять законы; менять же архитектуру кода, который контролируете вы один, — всё равно что увидеть второй смысл в картинке с двойным изображением.

Если нужно задействовать в проекте нескольких человек, разделите его на компоненты и отдайте каждый в одни руки.

Начинайте с малого. Программу становится легче держать в голове по мере того, как вы к ней привыкаете. Вы можете начать относиться к отдельным частям как к чёрным ящикам, когда будете уверены, что полностью их изучили. Но когда вы только приступаете к проекту, вы вынуждены видеть всё целиком. Если взяться за слишком масштабную задачу, вам, возможно, так и не удастся охватить её полностью. Поэтому, если нужно написать большую, сложную программу, лучший способ начать — это, возможно, не составлять спецификацию, а написать прототип, решающий часть задачи. Каковы бы ни были плюсы планирования, их часто перевешивают преимущества способности удерживать программу в голове. Поразительно, как часто программистам удаётся случайно соблюсти все восемь пунктов. У кого-то появляется идея нового проекта, но, поскольку она официально не одобрена, ему приходится заниматься ею в нерабочее время — которое оказывается более продуктивным, так как никто не отвлекает. Движимый энтузиазмом к новому проекту, он работает над ним помногу часов подряд. Так как поначалу это всего лишь эксперимент, вместо «производственного» языка он берёт обычный «скриптовый» язык — который на самом деле оказывается намного мощнее. Он полностью переписывает программу несколько раз; для официального проекта это было бы неоправданно, но это труд по любви, и он хочет довести всё до совершенства. А поскольку никто, кроме него, этот код не увидит, он опускает любые комментарии, кроме пометок для самого себя. Он поневоле работает в маленькой группе, потому что либо ещё никому не рассказал об идее, либо она кажется настолько бесперспективной, что никому больше не разрешают над ней работать. Даже если группа есть, несколько человек не могли бы редактировать один и тот же код, потому что он меняется слишком быстро для этого. И проект начинается с малого, потому что сама идея поначалу скромна; у него просто есть классная фича, которую хочется опробовать.

Ещё более поразительно число официально утверждённых проектов, которым удаётся сделать неправильно все восемь пунктов. На самом деле, если посмотреть на то, как пишется софт в большинстве организаций, возникает ощущение, будто они намеренно стараются всё делать не так. В некотором смысле так оно и есть. Одним из определяющих свойств организаций с момента их появления было отношение к отдельным людям как к взаимозаменяемым деталям. Это отлично работает для более параллелизуемых задач — например, ведения войн. На протяжении большей части истории хорошо вымуштрованная армия профессиональных солдат гарантированно побеждала войско воинов-одиночек, какими бы доблестными те ни были. Но появление идей не слишком-то поддаётся распараллеливанию. А программы — это и есть идеи.

Утверждение о том, что организации не любят зависеть от индивидуального гения, не просто верно — это тавтология. Само определение организации подразумевает отказ от этого. По крайней мере, наше текущее представление об организации.

Возможно, мы могли бы дать определение новому типу организаций, который объединял бы усилия отдельных людей, не требуя их взаимозаменяемости. Пожалуй, такой формой организации является рынок, хотя точнее было бы назвать рынок вырожденным случаем — тем, что получается по умолчанию, когда организовать процесс иначе невозможно.

Скорее всего, максимум, чего мы добьёмся, — это некий хак, вроде того, чтобы заставить подразделения разработки функционировать иначе, чем остальная часть компании. Возможно, оптимальное решение для крупных компаний — даже не пытаться создавать идеи внутри, а просто покупать их. Но каким бы ни оказалось решение, первый шаг — осознать наличие проблемы. Само словосочетание «софтверная компания» содержит в себе противоречие. Эти два слова тянут в противоположные стороны. Любой хороший программист в крупной организации обречён на конфликт с ней, потому что организации созданы так, чтобы препятствовать тому, к чему стремятся программисты.

Хорошие программисты всё равно умудряются добиваться многого. Но зачастую это требует практически акта бунта против нанявших их организаций. Возможно, поможет, если больше людей поймут, что поведение программистов продиктовано требованиями их работы. Они работают длинными запоями, во время которых забивают на все прочие обязательства, бросаются сразу кодить вместо предварительного написания спецификаций и переписывают уже работающий код вовсе не из-за своей безответственности. Они предпочитают работать в одиночку или огрызаются на людей, заглядывающих в дверь поздороваться, вовсе не из-за своей нелюдимости. У этого кажущегося случайным набора раздражающих привычек есть одно-единственное объяснение: сила удержания программы в голове.

Поможет ли понимание этого крупным организациям или нет, их конкурентам оно точно пойдёт на пользу. Самое уязвимое место больших компаний в том, что они не дают отдельным программистам делать великие вещи. Так что если вы маленький стартап, именно сюда их и стоит бить. Беритесь за задачи, которые под силу решить только одному большому мозгу.

Спасибо Сэму Альтману, Дэвиду Гринспену, Аарону Ибе, Джессике Ливингстон, Роберту Моррису, Питеру Норвигу, Лизе Рэндалл, Эммету Ширу, Сергею Царёву и Стивену Вольфраму за чтение черновиков этой статьи.