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