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