Кодеры за работой. Размышления о ремесле программиста
Шрифт:
Это по поводу прочности. Чем прочнее ваши материалы, тем меньше вы отвлекаетесь на мелочи и больше думаете о масштабных конструкциях. Конечно, это подвигает нас на создание все более крупных структур, пока они не начинают распадаться.
Вероятно, это что-то вроде инварианта. Если что-то умеешь делать, то раздвигаешь это до тех пор, пока не перестает получаться. Поэтому в программировании всегда будет что-то от работы ремесленника, ведь наши амбиции непрерывно растут. А для инженерных сооружений всегда есть физические пределы, дальше которых наращивать структуру невозможно. В ближайшее время вряд ли построят мост через Атлантику, а если его построить, он может рухнуть. Но его не строят просто потому, что это
Сейбел: Гай Стил говорил, что закон Мура действовал на протяжении всей его карьеры программиста, но вот насчет всей карьеры своего сына он уже не уверен. Он также рассуждал насчет программирования в ближайшем будущем. Не пора ли уже прекращать эти разговоры -“Построили мост через Ла-Манш, давайте строить через Атлантику”?
Пейтон-Джонс: Нет-нет. С ПО все иначе. Если вы написали программу в десять раз больше предыдущей, это не значит, что вам нужно запускать ее на компьютере, работающем в десять раз быстрее. Программный счетчик тратит 90% времени на 10% кода или как-то так. Участки программы, критичные с точки зрения быстродействия, могут быть невелики по объему.
Хотя, правда, часто случается так, что громоздишь одну абстракцию на другую, так что при нажатии всего одной кнопки на экране происходит много разных вещей вниз по цепочке, пока дело не дойдет до реальных изменений в регистрах.
Поэтому иногда нужно схлопывать эти слои путем сложных преобразований с помощью компилятора, чтобы не делать так много вещей. Границы абстракций могут быть полезны для людей, но машины к ним безразличны. Поэтому я не думаю, что даже после достижения границ возможностей компьютеров программы перестанут усложняться. К тому времени они уже будут работать очень быстро. Думаю, главное ограничение здесь - не скорость процессора, а наша способность понять, что должна делать программа.
Сейбел: Что вам особенно нравится в программировании?
Джонс: Мне нравится писать внутренне логичные программы. Если прилепить к программе что-то наспех, она заработает, но это не лучший вариант. Поэтому мне кажется, что хороший программист - тот, который стремится найти красивое решение. Не каждый может позволить себе роскошь отложить сдачу готовой работы, потому что не нашел красивого решения.
Еще программы хороши своей пластичностью — с ними можно делать что угодно! Но это значит также, что вы можете делать программы уродливые, недолговечные, трудные в обслуживании. Меня иногда пугает индустрия ПО, где все диктуется, с одной стороны, желанием покупателя увидеть продукт на следующей неделе, а с другой - стремлением распространять системы вширь, а не вглубь.
Системы слишком уж распухли. Если вы хотите сделать веб-сервис на ASP.NET, то должны освоить API и инструменты, уметь писать на трех разных языках, знать Silverlight и LINQ - и вы можете создавать акронимы до конца света. И про каждый из них есть толстая книга.
Есть противоречие, неразрешимое для меня. Это полезные системы, придуманные не просто так. Их тщательно продумывали умные люди. Но у каждой - широкий интерфейс. Глубокий или нет, неважно - он широкий. И в голове приходится держать кучу разных программ. Все равно что учить обычный язык с очень богатым словарным запасом.
И это мне не нравится. Я так и не запомнил таблицу умножения. Я всегда все делал на основе нескольких простых правил и придумал много хитростей, чтобы делать это быстро. Все умножают семь на девять, а я умножаю семь на десять, вычитаю, получаю шестьдесят три. Другие просто запоминают таблицу. А она ведь совсем небольшая. Поэтому я не люблю системы, которые заставляют
Сейбел: Мне иногда кажется, что вся эта сложность - именно из-за того, что системы разрабатывают умные люди. И им хочется играть в свои игры.
Пейтон-Джонс: Да, есть и такое. Но можно подойти к этому вопросу и более конструктивно. Перед нами - огромный, сложный мир, где так много надо сделать. Человек со зрением олимпийца, с могучим умом и невероятной проницательностью способен создать нечто стройное и цельное.
На практике нам приходится разбивать задачи на кусочки. За каждый кусочек отвечает человек, который исходит из собственного опыта и культурного багажа. То, что он создает на своем пространстве, хуже, чем могло бы быть, - человеку не хватает времени. В итоге весь ансамбль тоже выглядит хуже, чем мог бы. Плюс отрицательное влияние наследства прежних систем.
Это наследство - как ядро каторжника, которое мы волочим за собой. И в этом отношении удачей стал Haskell. Оглядываясь, я всегда вижу перед собой принцип, который мы в него заложили: “Избегать успеха любой ценой”. Теперь это что-то вроде мема - люди запомнили эту фразу и мне же ее цитируют.
В этом есть доля правды - именно потому, что мы не хотели быть слишком успешными и слишком поспешными, у нас было какое-то время, чтобы изменять Haskell на протяжении его жизни. Я даже переживаю из-за того, что Haskell стал более успешным, - мне приходит больше сообщений об ошибках, больше запросов новых функций. Все больше людей говорят: “Прошу вас, не ломайте мою программу”. Раньше такого не было.
Сейбел: Вы несколько раз упоминали о красоте кода. Каковы признаки красивого кода?
Пейтон-Джонс: Тони Хоар замечательно сказал: нужен код, совершенно очевидно свободный от ошибок, а не код, свободный от очевидных ошибок. Думаю, красивый код - это код, который совершенно очевидно правилен. Абсолютно прозрачный код.
Сейбел: А как насчет перлов - небольших замысловатых, но интересных фрагментов кода, - они тоже красивы?
Пейтон-Джонс: Иногда что-то правильно, но этого не понять без умственных усилий. Иногда нужно предварительное знание. Если взглянуть на код для АВЛ-дерева, не зная, в чем его смысл, не понятно, зачем нужны все эти вращения. Но если вы знаете, какой инвариант тут поддерживается, то видите: ага, если поддерживается этот инвариант, мы получаем логарифмическое время поиска. Вы смотрите на каждую строку кода и понимаете, что здесь поддерживается инвариант. Инвариант дает нам предварительное знание и позволяет судить о том, что код совершенно очевидно правилен.
Я полностью согласен с тем, что простого изучения кода может быть недостаточно. Если вы смотрите на код и видите, что он правилен, это еще не характеристика красивого кода. Возможно, кто-то должен объяснить, почему код правилен. Но после этого, поняв, что тут делается, выработав свою точку зрения, вы говорите: да, это на самом деле правильно.
Сейбел: Есть ли верхняя граница, если говорить о размере, вплоть до которой код все еще может считаться красивым?
Пейтон-Джонс: Не знаю, связано ли это с размером. Знание, необходимое, чтобы убедить себя, что он правильный, направлено в сторону большей уверенности в его коррекности. В очень больших программах всегда есть недочеты или даже несомненные ошибки. Но ликвидировать их сразу же бывает нецелесообразно. Это справедливо в отношении GHC и еще более - в отношении программ Microsoft.