Питер Сейбел - Кодеры за работой. Размышления о ремесле программиста
В этом году я закончил раздел, посвященный уловкам и приемам работы с побитовыми операциями, а эти вещи долго считались черной магией среди компьютерных специалистов. Я решил: пора сказать о том, что у этих приемов есть и теоретический аспект, благодаря которому можно понять эти идеи и то, как они используются. Вы можете абсолютно уверенно использовать их сами. Кроме того, вы можете создавать программы и делать удивительные вещи, о которых в прошлом году не имели особого представления. До нынешнего времени все это было в глубоком подполье, но этому мы также должны учить людей - это знание заслуживает того, чтобы быть доступным всем.
Я пишу много программ и не могу утверждать, что являюсь показательным примером, но точно знаю, что мне удается создавать много программ, успешно выполняющих различные задачи, и мне было бы намного труднее, если бы пришлось тратить время на изучение работы с программами и процедурами, написанными кем-то другим. Мне гораздо проще разобраться с рядом базовых понятий, после чего повторно использовать код путем редактирования текста кода, который раньше работал.
Сейбел: Как изменились ваши взгляды на программирование с того времени, когда вы только начинали им заниматься?
Кнут: Мы уже обсудили с вами литературное программирование; это само по себе коренное изменение в понимании своей функции: не просто расстановка в нужном порядке инструкций, а объяснение того, что происходит. Дейкстра прошел ту же эволюцию. В конце концов, его программы были даже более литературными, чем мои, - в том смысле, что они даже не добрались до компьютера. Они были просто литературными.
Он был также одним из главных вдохновителей структурного программирования, где мы работали с шаблонами, которые можно было использовать для масштабирования наших программ, так чтобы мы могли создавать более крупные программы и тем не менее держать все под контролем. Вы пишете в десять раз более крупную программу, но вам не нужно из-за нее спать в десять раз меньше обычного, поскольку у вас есть инструменты, позволяющие надежно соединять элементы в более крупную систему. Это было очень непривычно.
Это очень важный момент - необходимость осознания абстрактных понятий, позволяющих нам работать с крупными системами, не теряя уверенности в том, что у нас все под контролем, что мы знаем, что делаем, несмотря на то, что эти понятия чертовски сложны.
Есть множество других вещей, которые могут считаться важными изменениями, но мне не кажется, что они что-либо значительным образом изменили. Это лишь оболочка, еще одна разновидность синтаксического сахара, различные диалекты уже существующих языков. У всех разные вкусы. Кто-то, например, обладает более логическим мышлением, чем я. Они используют в изобилии вводные слова, любят, чтобы все всему соответствовало, и всегда говорят: “Сейчас я начинаю делать вот это”, - а в конце: “А сейчас я заканчиваю делать вот это”. Мне это не очень-то по душе. Это не похоже на мой образ мышления. Но это образ мышления других людей, а какого-то одного - самого лучшего - образа мышления не существует.
Для меня одной из самых главных революций в языках программирования стало использование указателей в языке Си. Если у вас есть необычные структуры данных, то нередко появляется необходимость в том, чтобы одна часть структуры указывала на другую часть, и люди пробовали по-разному реализовать эту функцию в языках более высокого уровня. Например, Тони Хоар разработал ясную четкую систему, но язык Си привнес следующее (что сначала показалось мне большой ошибкой, но в конце концов я это полюбил): если х - это указатель, и вы пишете х+1, это означает не следующий байт после х, а следующий узел после х в зависимости от того, на что указывает х: если он указывает на большой узел, то х+1 пройдет большой путь; если х указывает на что-то маленькое, то и х+1 продвинется немного. Для меня это одно из самых потрясающих усовершенствований нотации.
Сейбел: По сравнению с тем, что было прежде, безусловно, это шаг вперед. Но за время, прошедшее с появления указателей, многие пришли к мнению, что указатели в чистом виде весьма опасны и что лучше бы иметь ссылки, которые ведут себя как указатели, но при этом более безопасны.
Кнут: Указатели уже настолько вышли из моды, что мне приходится вступать по этому поводу в споры. Если говорить о моем 64-разрядном компьютере, то, если действительно заботиться о производительности моего компьютера, мне приходится признать, что лучше отказаться от использования указателей, поскольку на моей машине 64-битные регистры, но всего 2 гигабайта оперативной памяти. Поэтому у указателя никогда не бывает больше 32 значащих битов. Но каждый раз, когда я использую указатель, это стоит мне 64 бита, и это удваивает размер моей структуры данных. Более того, это еще идет и в кэш-память, и половины кэш-памяти как не бывало, а за это приходится платить - кэшпамять дорогая.
Поэтому я на самом деле пытаюсь сейчас пробовать новые варианты, то есть мне приходится вместо указателей использовать массивы. Я создаю сложные макросы, то есть создаю видимость использования указателей, хотя на самом деле их не использую. Можно сказать, что это незначительное явление, и оно выходит из моды. Но для меня это было важным новшеством в нотации на низком уровне. Когда я пишу код, занимаюсь отладкой или еще чем-то в этом духе, то всегда испытываю огромную благодарность Томпсону и Ричи. Не знаю, кто именно первым это придумал.
Сейбел: Есть ли в вашем программистском арсенале другие важные инструменты?
Кнут: Файлы изменений - их я придумал после того, как уже стал использовать методы литературного программирования, и я не знаю их аналогов в инструментариях других программистов, поэтому позвольте объяснить их вам.
Когда я написал ТеХ и METAFONT, люди стали просить их у меня. У всех этих людей было 200-300 различных комбинаций языков программирования, операционных систем и компьютеров, поэтому я хотел сделать так, чтобы мой код с легкостью можно было адаптировать к любой системе. И мы разработали такое решение: я пишу главную программу, которая работает в Стэнфордском университете, после чего создается дополнение - файл изменений (change file), который может адаптировать эту главную программу для работы на чьем угодно компьютере.
Файл изменений очень прост. Он состоит из ряда небольших фрагментов изменений. Каждое изменение начинается с нескольких строк кода. Вы сравниваете до тех пор, пока не находите первую строку файла главной программы, которая совпадает с первой строкой вашего изменения. Когда вы добираетесь до конца той части изменения, которую нужно было соотнести с главным файлом, появляется часть, в которой написано: “Замените это вот этими строками”.