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

Он работал исследователем в проекте MULTICS Bell Labs. Когда Bell Labs решила прекратить разработку MULTICS, Томпсон вместе с Денисом Ричи продолжил работу над UNIX — за что его вполне могли уволить. Также он изобрел язык программирования Би — предшественник языка Си, созданного Денисом Ричи.

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

Работая над операционной системой Plan 9 компании Bell Labs, он предложил ныне повсеместно используемую кодировку Юникода UTF-8.

В 1983 году Томпсон и Ричи получили премию Тьюринга «за развитие теории порождающих операционных систем и в особенности за внедрение операционной системы UNIX». Также Томпсон был награжден Национальной медалью за технологии и премией Tsutomu Kanai Института инженеров электротехники и электроники (IEEE) — оба раза за работу над UNIX.

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

Сейбел: Как вы научились программировать?

Томпсон: Меня всегда завораживала логика, и даже в школе я предпочитал решать арифметические примеры в двоичном исчислении и тому подобное. Мне это просто нравилось.

Сейбел: То есть так вы делали их для себя более интересными?

Томпсон: Нет-нет. Я разработал таким образом алгоритмы для сложения в разных базисах, узнал, что значит перенос, что обозначает каждый столбец и так далее. И у меня было небольшое десятичное арифметическое устройство, вроде счетов. Вместо каждого разряда там был ползунок от нуля до девяти. Вычитать надо было с помощью нижней колонки, а добавлять — с помощью верхней. Берешь стилус и сдвигаешь им ползунок на четыре, например, деления, при переполнении разряда переходя в соседнюю колонку. Позже, основываясь на этом варианте, я сделал двоичное устройство, а потом обобщил его до личного.

Сейбел: Как вы впервые узнали о двоичной арифметике?

Томпсон: В классе, как раз когда я начал этим заниматься, нас познакомили с двоичным счислением.

Сейбел: Вы стали жертвой «новой математики»?

Томпсон: Нет-нет. Я был жертвой плохой математики. Мы переезжали каждый год, я учился в очень, очень плохих школах, а потом в хороших. Так что мне иногда приходилось за год проходить двухлетнюю программу, а потом я год ничего не делал. На математике я просто бездельничал, так что начальное математическое образование у меня просто ужасное. И вот в одном классе как раз рассказывали про двоичную арифметику. Я заинтересовался, расширил ее до любого базиса и стал с ней играть. Вот так все и началось.

Сейбел: И это было еще в школе?

Томпсон: Да, в седьмом классе. Позже, где-то в выпускном классе, я сильно увлекся электроникой — собирал радио, усилители, осцилляторы и терменвоксы. И очень заинтересовался аналоговыми вычислениями. Это и впрямь было потрясающе. Все это время электроника была моей страстью. Я поступил на соответствующий факультет в Беркли и только там на первом курсе впервые увидел настоящие цифровые компьютеры.

Сейбел: В каком году это было?

Томпсон: Я поступил рано, и тогда в году было три семестра. Поступил я в сентябре 1960 года, так что это, видимо, весна или осень 1962-го. У них был аналоговый компьютер, за которым мне нравилось работать. И была еще барабанная вычислительная машина — G15. Была одна учебная лаборатория с ними, и тогда она была всегда открыта. Там мог заниматься любой, но почти никто не хотел, так что всегда было свободно. И главным образом сидел там я один. Я писал на ней собственные программы по масштабированию — собственно, почти все аналоговое вычисление сводится к масштабированию.

Сейбел: В каком смысле «масштабирование»?

Томпсон: Масштабирование времени и амплитуды. Обычно все, что нужно было сделать, — это построить функцию. Вводишь некоторые данные, затем получаешь функцию для этих данных и связываешь результаты. И ни в один момент нельзя забираться слишком высоко, иначе наткнешься на отсечку.

Точно так же измеряешь время: делишь на два частоту в одних случаях или удваиваешь ее в других. И когда так делаешь, меняется и линейное масштабирование. Так что если есть несложная задача, при которой масштабирование не нужно, то аналог — это отличное решение. Но когда появлется масштабирование, все становится очень, очень сложным. И вот я написал цифровые компьютерные программы для масштабирования установок аналогового компьютера. Без вычисления точной формы сигнала считаешь амплитуду и частоту формы сигнала в каждой точке. И таким образом понимаешь, где что-то идет не так и какая операция выполняется в данный момент.

Сейбел: А программы для цифрового компьютера были написаны на ассемблере или на Фортране?

Томпсон: В основном это был ассемблер. Интерпретируемый язык, который там был, оказался очень медленным. Поэтому пришлось перейти на ассемблер, и так я на самом деле узнал, что такое компьютер.

Сейбел: То есть загружаем программу, нажимаем на кнопку «пуск» и уходим. Это работало на перфокартах?

Томпсон: Нет-нет. Это был флексорайтер, то есть нечто вроде телетайпа или бумажной перфоленты. Записываешь на бумажную перфоленту и суешь во флексорайтер.

Сейбел: В этой лаборатории вас учили ассемблеру?

Томпсон: Нет.

Сейбел: Когда вы в следующий раз встретились с программированием?

Томпсон: На той машине G15 был установлен интерпретатор Intercom 501. И группа электроинженеров на нем программировала. У меня был приятель-выпускник, который написал интерпретатор для Intercom на большой машине IBM, предоставляющей лучшие вычислительные возможности во всем кампусе. Я получил листинг этого кода и однажды на каникулах, рождественских или еще каких-то, прочитал и проанализировал его. Я не знал язык, на котором он был написан, — это оказался NELIAC. И написана программа была просто отлично. И по ней я изучал программирование, NELIAC, Intercom и то, как разобраться в чем угодно. Я сидел и читал все каникулы — неделю. Потом я вернулся и стал задавать приятелю вопросы, иногда находя некоторые ошибки. Теперь я знал, как программировать, и добился в этом успехов. Потом я получил свою первую работу как программист.

Я учился, работал в лаборатории и брался за странные подработки. Я был помощником исследователя — должность мелкой сошки для студента, которая помогала написать программу для дипломной работы. И я был ассистентом, вел занятия. Программировал для компьютерного центра. Главным образом в компьютерном центре надо было сидеть в маленькой такой будке и слушать, как люди заходят и говорят: «Я изменил только в одном месте». «Ну, давайте посмотрим, что это за место и что у вас в итоге случилось».

Сейбел: Это помогло вам отточить мастерство отладки или все это было сплошной глупостью?

Томпсон: Отточило отладку только в том отношении, что после этого хорошо начинаешь понимать стандартные ошибки. Человек несколько дней корпел над своей программой, он приходит к тебе, а ты так небрежно ему: «Вот тут!»

Сейбел: По образованию вы электроинженер? По компьютерным наукам в то время еще никого не готовили?

Томпсон: Нет, в то время на всей территории Соединенных Штатов компьютерные науки только зарождались, двумя путями. Теоретически — через математику и практически — через электронику. В Беркли компьютерные науки в то время преподавались в рамках курса по электроинжинирингу. Математика тоже пыталась прорваться, но у них не было такого политического влияния, чтобы соревноваться с умудренными жизнью конкурентами.

Сейбел: Университет Беркли в итоге стал известен прежде всего такими вещами, как Системная лаборатория Беркли, то есть практикой, а не вкладом в теорию.

Томпсон: Именно так. Есть источники зарождения компьютерных наук, например Корнелл, и есть подход Беркли к компьютерным наукам. Сама атмосфера места очень значима. И я провел год в Беркли не потому, что имел какие-то амбиции. Просто мне больше нечего было делать, а это нравилось.

Сейбел: Сразу после учебы?

Томпсон: Да. Честно говоря, я работал в университете и не собирался продолжать обучение, даже не подавал заявку. Это за меня сделал один из преподавателей, который потом и сообщил мне, что я теперь в магистратуре.

Сейбел: По-прежнему по направлению электроинжиниринга?

Томпсон: Да. И мои последние годы были просто замечательными. Я не делал ничего, чего не хотел бы делать. Никаких требований, ничего такого. Чтобы нормально выпуститься, я летом прослушал курс, кажется, по американской истории — было какое-то требование по получению степени. Но за исключением этого я преподавал почти половину всех курсов, которые должен был изучать.

Общая теория вычислений в то время как раз оформлялась как самостоятельная дисциплина. Сортировка методом Шелла только что появилась, и никто не мог понять, почему она быстрее, чем п2. Все гоняли тесты и пытались выяснить, в чем же дело; очень просто было увидеть, что она действительно сортирует, но было непонятно, почему же, собственно, она такая быстрая. Брали асимптоту и считали, почему тут n1,3, и так далее. А это же не натуральное число. И из всего этого — сортировки Шелла, интеллектуальной привлекательности сортировки Шелла и попытки выяснить, почему она такая быстрая, — вышла вся скорость вычислений. Разделяй и властвуй, все эти п log n и так далее. Поразительное, захватывающее было время.

У меня были друзья, в том числе весьма молодые преподаватели — по математике, я с ним очень дружил, и по электроинжинирингу, а также выпускник, на которого я работал. Для меня придумывали класс, и я его обучал.

Сейбел: Вы официально изучали предмет или только по документам числились его преподавателем?

Томпсон: Нет, конечно, нигде я преподавателем не числился. Везде стоял код электроинжиниринга 199, который означал индивидуальные или групповые исследования и все такое. Они изобретали предмет, давали ему название и передавали мне. И на него приходили три-четыре студента.

Сейбел: Одним из которых на бумаге были вы.

Томпсон: Да.

Сейбел: Вам нравилось преподавать?

Томпсон: В некотором отношении. Мне приходилось преподавать в своей жизни дважды. Один раз я взял отпуск на год и преподавал в Беркли в 1975/76 гг., а еще год я читал лекции в Сиднее в 1988 г. Это очень интересно. Мне очень, очень нравится. Я занимался лабораторными исследованиями, а потом поехал в Беркли преподавать и сам изучал те предметы, которые преподавал, поскольку у меня ведь не было образования в области компьютерных наук. Обычно внештатный преподаватель ведет один предмет. У меня их было пять. Некоторые курсы я читал по два раза, и они, думаю, были наилучшими, потому что в первый год я учился, а на второй уже понял, как преподавать, и организовал свои занятия более успешно, опережая на два шага студентов в этом предмете. На третий год курс становился просто унылым. Я взялся вести один предмет третий раз подряд, и это было ошибкой. Я никогда не смог бы стать педагогом, потому что там нужно преподавать каждый раз одно и то же. Это не по мне. Но я люблю преподавание: сперва тяжело, потом весело и интересно. И затем унылый третий раз.

Сейбел: Какую самую первую интересную программу вы написали?

Томпсон: Первая длинная вычислительная программа, которую я написал, относилась к проблеме игры в пентамино. Знаете такую?

Сейбел: С кирпичиками?

Томпсон: Да, с кирпичиками. Я запустил программу на компьютере IBM 1620, который имелся на физическом факультете. Я знал, где находятся самые лучшие компьютеры, и все их запускал на ночь для своих целей. Да и в главном компьютерном центре у меня было порядка двадцати учетных записей под разными псевдонимами. Имеется 12 пентамино — это разные типы фигур из пяти кирпичиков. И таких фигур может быть 12.

Сейбел: Примерно как в тетрисе.

Томпсон: Да. Но здесь каждая фигура состоит из пяти клеток. Если их все разложить на доске, то есть две, скажем так, наиболее приятные конфигурации. Одна — прямоугольник 10 на 6, а вторая — 8 на 8 с отверстием 2 на 2 посередине. И я решил все конфигурации для этих двух досок, то есть как разместить на них фигуры. В общем случае я решал это, сравнивая шаблон досок и шаблон фигур: как фигуры вкладываются в шаблон доски. Программа не знала, что это пентамино.

Сейбел: В принципе, это был поиск методом грубой силы?

Томпсон: Так и есть.

Сейбел: Наверное, на ассемблере?

Томпсон: Видимо, так. Да, наверное, на ассемблере. Не помню, честно говоря.

Сейбел: Где-то в это время вы должны были изучить Фортран.

Томпсон: Да, конечно, в компьютерном центре мне пришлось преподавать Фортран и отлаживать программы на нем. Но я никогда на Фортране не программировал. Довольно давно я написал компилятор Фортрана для UNIX, язык Би был неудачной попыткой написать компилятор Фортрана.

Сейбел: А я думал, Би — это ваша версия BCPL.

Томпсон: Отчасти. Начиналось все, как... впрочем, не знаю как. С семантической точки зрения, однако, это оказался BCPL. А когда я начинал, то это должен был быть Фортран. И как раз тогда у меня впервые появилось описание BCPL. Мне понравилась его четкая семантика. Я отложил Фортран, и в итоге вышел синтаксис Си и семантика BCPL.

Сейбел: Есть ли большие различия в том, как вы занимались программированием и теоретизировали по его поводу в начале карьеры и сегодня? Считаете ли вы, что программирование в каком-то смысле повзрослело или что вы повысили класс или узнали что-то такое, что заставляет вас оглянуться и сказать: «Господи, я же просто не знал, что творил!»?

Томпсон: Вовсе нет. Иногда я действительно оглядываюсь назад, но говорю: «Эх, а тогда ведь я был намного сильнее». Начиная с момента, когда я неделю читал ту программу, и до 30-35 лет я глубоко понимал каждую строку написанного мною кода. Я мог писать программу весь день, а ночью продолжать сидеть и читать строку за строкой в поисках ошибок. На следующий день я возвращался к нему и, разумеется, находил ляп.

Сейбел: А в 35 лет вы могли вспомнить то, что написали десятью годами раньше?

Томпсон: Да. Это позже моя память стала более избирательной.

Сейбел: Есть ли в изучении программирования то, что сейчас вы бы сделали по-другому? Сожалеете ли вы о пути, который избрали; может быть, хотели бы, чтобы что-то было сделано вами раньше?

Томпсон: Да-да, конечно. В школе мне обязательно следовало заниматься машинописью. Я плохо печатаю даже сейчас, но кто знал. Я никогда ничего не планировал. У меня нет дисциплины. Я делал то, что хотел делать завтра, на следующей неделе, всю жизнь. Если бы у меня были способности к планированию или предвидению, то курс машинописи я бы непременно по возможности прошел. И я бы, конечно, более углубленно изучил математику, потому что часто сталкивался с такими вещами, где помощи приходилось ждать только от математики. Вот такие частности, словом. Но если вернуться назад, то я уверен, что меня не хватило бы на то, чтобы сделать что-то принципиально по-иному. Обычно я ничего не планировал — просто делал следующий шаг. И начав заново, я точно так же делал бы следующий шаг.

Сейбел: Сразу после выпуска вы попали прямо в Bell Labs — как это вышло? На том этапе карьеры вы вроде не были классическим академическим исследователем.

Томпсон: Так уж меня занесло. Трудно сказать. На самом деле я, можно сказать, не учился. Формально — да, конечно. Один из моих преподавателей — собственно, мой хороший друг — прямо-таки натравил на меня рекрутера из Bell Labs. Но я не искал работу. У меня не было абсолютно никаких амбиций. И он назначил мне встречу на его маленьком рекрутерском стенде, а я то ли проспал, то ли сказал ему, что мне неинтересно. Но он не сдавался. В какой-то момент он позвонил мне и сказал, что хотел бы зайти. И пришел ко мне домой. И сказал, что хотел бы, чтобы я прошел собеседование в Bell Labs. Я отказался. Но он сказал: «Поездка бесплатная. Ты можешь делать все что угодно». А я ему: «Ладно, тогда вот что я тебе скажу. Работа мне не нужна. Но бесплатная поездка — это прикольно, у меня есть друзья на Восточном побережье. К ним и поеду». А он мне: «Отлично». Вот так я и попал на собеседование. Я приехал, два дня потратил на Bell Labs, а потом взял напрокат машину и поехал по Восточному побережью повидать школьных друзей, которые разъехались кто куда.

Сейбел: Очевидно, в вас было что-то, что заметили парни из Bell Labs и сказали: «Этот человек должен работать у нас».

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

Сейбел: Чем вы начали заниматься, поступив на работу?

Томпсон: Bell Labs занималась проектом MULTICS, и меня брали работать над MULTICS. Это я и делал. Я работал с машинами, загружал MULTICS, немного писал. В какой-то момент Bell Labs решила, что MULTICS не для них, и они отказались от проекта.

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

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

Сейбел: Время на это у вас было — ваши боссы знали, что вы делаете, и одобряли этот проект как хорошее исследование, или вы занимались операционной системой сверхурочно?

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

Сейбел: Как вы создаете программы? Царапаете на миллиметровке, запускаете утилиту для работы с UML или просто начинаете писать?

Томпсон: Зависит от масштаба проекта. Большую часть времени все хранится у меня в голове, никаких бумаг, и я концентрируюсь на сложных частях. Простые части отходят на второй план, их достаточно записать: они так и слетают с кончиков пальцев, когда все готово. Но над сложными я сижу и даю им некоторое время, чтобы созреть, — примерно месяц. В какой-то момент начинает складываться основание, образуется пирамида. И как только пирамида у меня в голове делается достаточно высокой, я начинаю с ее основания.

Сейбел: Но вы не просто создаете отдельные элементы — вы знаете, какова должна быть итоговая структура.

Томпсон: Допустим, кто-нибудь мне описывает что-то таким образом: «Вот это компьютер, а вот коды операций». Я могу представить себе структуру программ и то, насколько в соответствии с ней эффективны или неэффективны действия, основанные на этих кодах операций, потому что вижу основание и представляю себе иерархию. То же самое я могу делать и с программами. Если мне показывают функции из библиотеки или базовые вещи из нижнего уровня, я могу понять, как построить на этом разные программы и чего не хватает, какие программы будет сложно написать. Так что я могу представить себе всю пирамиду — останется только разобрать ее и определить, где основание.

Современное программирование во многих отношениях пугает меня: они пишут слой, за ним еще один, потом еще один, и все эти слои только и делают, что обращаются друг к другу. Меня смущает программа, которую обязательно читать сверху вниз. Там написано: «Сделай то-то». Отправляешься искать «то-то», находишь, а там написано: «Сделай еще что-то». Ищешь еще что-то, а там надо сделать еще вот это, и так до самого верха. И ничего не делается. Это просто перенос задачи на все более и более глубокий уровень. Я не могу этого ни понять, ни принять.

Сейбел: Почему же тогда не читать снизу вверх? Листья ведь где-то есть.

Томпсон: Но вы же не знаете, что является в данном случае листьями, а что нет. Если описание хорошее, то можно прочитать написанное английским языком и все понять, так что код можно не читать. Но если дается просто какой-то кусок кода и говорят: «Прочитай и сделай его лучше» или: «Прочитай и заставь его делать еще что-то». Тогда обычно приходится читать сверху вниз.

Сейбел: Вы что-нибудь записываете, прежде чем начать писать код?

Томпсон: Да, обычно это структуры данных. Я не записываю никаких алгоритмов или блок-схем, если вы это имеете в виду. Только то, к чему приходится обращаться практически в каждой строке кода, — структуры данных.

Сейбел: Если вы пишете программу на Си, значит ли это, что код на Си будет определять эти структуры данных?

Томпсон: Нет, это будут квадратики со стрелками и так далее.

Сейбел: Итак, у вас большая общая картина — пирамида. Насколько вы следуете плану в процессе написания кода?

Томпсон: Я не привязываюсь к коду. Если на полпути я понимаю, что другая декомпозиция лучше, то переключаюсь на нее. Я знаю многих, у которых написанная строка кода остается такой до конца жизни, если там, конечно, нет ошибки. Особенно если они пишут функцию для какого-то API, набросают этот API где-нибудь на бумажке или в списке рассылки — и все. Он никогда не меняется, как бы плох ни был. А я всегда с удовольствием все менял, если находил другой, более подходящий путь или иную декомпозицию. Я никогда не питал большой любви к имеющемуся коду. Код сам по себе — почти чепуха, его можно переписывать. Даже если ничего не изменяется, он все равно по какой-то причине портится.

Сейбел: Как вы понимаете, что вот этот код нужно отбросить?

Томпсон: Когда с ним становится тяжело работать. Я отбрасываю код гораздо быстрее, чем другие. Я отказываюсь от него, как только хочу к нему что-то добавить, но возникает ощущение, что добавить к нему что-то будет непросто. Тогда я выбрасываю его, начинаю заново и нахожу другую декомпозицию, при которой куда проще сделать то, что я собирался. Я не думаю долго над тем, выбросить код или нет.

Сейбел: Это же справедливо и для работы с чужим кодом?

Томпсон: Зависит от того, есть ли у меня на это право. Если да, то не важно, чей это код. Если нет и код чужой, то приходится терпеть. Или не делать это.

Сейбел: Если вы унаследовали чей-то код, то при его переписывании может возникнуть такая опасность: возможно, вы упустили какую-то тонкость в его работе или просмотрели какой-то функциональный элемент, который раньше был, а сейчас его не осталось. У вас так бывало?

Томпсон: Ну да, бывало, но это неизбежный элемент отладки. Если что-то забыл или не сделал, то сразу, как только это понял, доделываешь. Это просто элемент отладки. Код не получается с первого раза. Его расширяешь.

Сейбел: Построив систему, возвращаетесь ли вы, чтобы каким-то образом ее документировать?

Томпсон: Зависит от того, для чего она предназначена. Если она написана исключительно для меня, то нет, не возвращаюсь. Если я забуду аргументы, то добавлю строку о том, как это использовать. И в комментарии заголовка поясняю, что вся функция делает. Но очень кратко. Если это часть системы, или библиотеки, или еще чего-то, что должно быть опубликовано, то я потрачу время на документацию. В других же случаях нет.

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

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

Сейбел: То есть вы бы хотели читать код так же, как его пишете, а именно снизу вверх?

Томпсон: Да. Таким образом я могу удержать его у себя в голове и запомнить. В противном случае я читаю его и могу даже понять, но сразу после чтения он выветривается у меня из головы. Если я понимаю структуру кода, то он становится частью меня и я воспринимаю его полностью.

Сейбел: В своей речи при получении премии Тьюринга вы упомянули, что если бы Дэна Боброу заставили использовать PDP-11, а не более мощный PDP-10, то в тот день награду вместо вас и Дениса Ричи мог бы получать он.

Томпсон: Я просто пытался сказать, что наша награда — результат счастливого случая.

Сейбел: Думаете, вам повезло быть привязанными к менее мощной машине?

Томпсон: Безусловной удачей оказалось то, что компьютер был мал и эффективен. Но, думаю, этот код мы бы написали в любом случае. Нам сильно помогло то, что дело происходило в самый разгар революции мини-компьютеров. «Десятка» была большим мэйнфреймом, управляемым компьютерным центром. Автономные вычисления вместо централизованных, думаю, и явились элементом счастливого случая. И это сыграло свою роль в PDP-11.

Сейбел: Выиграла ли UNIX от того, что была написана на Си, в то время как другие ОС — например TENEX и ITS — создавалась на языке ассемблера и, следовательно, их нельзя было так запросто переносить на другое оборудование, как UNIX?

Томпсон: Были и другие хорошие языки системного программирования, на которых писались такие вещи.

Сейбел: Например?

Томпсон: NELIAC был версией Алгола-58 для системного программирования.

Сейбел: BLISS тоже относится к той эре?

Томпсон: BLISS, кажется, был позже. В этих языках акцент делался на то, чтобы они хорошо компилировались. Думаю, с самого начала было вполне ясно, что из-за хорошей компиляции нельзя так уж убиваться. Нужно делать это хорошо, но вовсе не обязательно безупречно. Дело в том, что пока вы дорастаете до безупречной компиляции, закон Мура вас все равно обгонит. Вы можете повысить качество на 10%, но пока вы это делали, быстродействие компьютеров выросло вдвое и, возможно, появилось еще что-то более значимое для оптимизации, вроде кэшей. Думаю, по большей части стремление к совершенству здесь — пустая трата времени. Это очень тяжело: вы порождаете столько же ошибок, сколько устраняете. Нужно остановиться и не тратить 100% времени на 10% работы.

Сейбел: Вы, наверное, слышали о статье Ричарда Гэбриела «Worse Is Better» (Чем хуже, тем лучше).

Томпсон: Нет.

Сейбел: Он сравнивал два стиля — стиль Массачусетского технологического института (MIT), где на первом месте правильность, и стиль Нью-Джерси (то есть Bell Labs), где высоко ценят простоту реализации. Его теория состоит в том, что стиль Нью-Джерси, который он также называет «Чем хуже, тем лучше», обеспечивает возможность немедленного запуска проекта и исправления в нем ошибок на ходу.

Томпсон: Думаю, у MIT всегда был некий комплекс неполноценности по поводу UNIX. Я выступал с лекцией о UNIX в MIT, и меня представлял, кажется, Майкл Детрузос. Он объяснял, почему UNIX не была написана в MIT, хотя именно так и должно было быть. Почему у них были возможности, люди и все такое, но тем не менее ничего не произошло. И тут меня осенило, что все это время в них сидит дух соперничества. У меня ничего подобного не было. Мы сделали UNIX, а они сделали MULTICS, настоящего монстра. Это явно синдром второй системы.

Сейбел: Где MULTICS была вторичной по отношению к операционной системе MIT CTSS?

Томпсон: Да. Слишком много лишнего. Почти неприменимо. Они по-прежнему уверяют, что это был потрясающий успех, хотя очевидно обратное.

Сейбел: Как я понимаю, большинство специалистов MIT придерживается именно такого мнения о MULTICS. Они предпочитали построенные ими же системы ITS и те, что были основаны на Лиспе. Похоже, после MULTICS получилась вилка. UNIX вышла в свет, как вам хорошо известно, и в MIT все эти любители Лиспа стали срочно работать на PDP-10 и строить основанные на Лиспе системы, которые в конце концов, думаю, и породили Лисп-машины.

Томпсон: Да-да. Я знал всех этих ребят. Я считал, что это сумасшедшая работа. Не думал, что Лисп — настолько уникальный язык, чтобы делать под него свою машину. И я, видимо, был прав. Все это время я говорил: «Вы с ума сошли». Вот PDP-11 — отличная Лисп-машина. PDP-10 — отличная Лисп-машина. Зачем строить машину под Лисп, которая не будет быстрее? Да и вообще нет никакого смысла строить машину под Лисп. Это глупо, в конце концов.

Сейбел: Были ли у MULTICS такие черты, которые вам нравились, но тем не менее не были перенесены в UNIX?

Томпсон: Вещи, которые мне понравились настолько, что я их оттуда позаимствовал, — это иерархическая файловая система и оболочка — отдельный процесс, который можно было заменить другим процессом. До того во всех системах был «исполнительный компонент» — это так тогда называлось, — который был встроенным языком обработки. Он исполнялся в каждом процессе отдельно. А каждый раз когда вы что-то печатаете в оболочке, она порождает новый процесс и запускает то, что вы напечатали, а когда тот заканчивается, то вы возвращаетесь, и таким образом всегда находитесь недалеко от оболочки.

Сейбел: И все это вы перенесли в свою систему, там не осталось ничего, о чем бы вы жалели?

Томпсон: Нет.

Сейбел: Судя по тому, что я читал по истории UNIX, вы действительно использовали тот процесс проектирования, который здесь описали. Вы долго думали, а потом, когда жена и ребенок на месяц уехали, сказали: «Отлично! Теперь я могу написать код».

Томпсон: Да... Мы собрались группой и поговорили о файловой системе. Нас было трое или четверо. Единственный, кто сейчас не очень хорошо известен, — это Радд Кэнеди (Rudd Canady). В те дни в Bell Labs были потрясающие удобства: можно было позвонить по телефону и потом получить распечатку вызова. То есть оставляешь заявку на то, чтобы оно было записано, и на следующий день в твоем почтовом ящике появится распечатка. И после того как мы обсудили файловую систему с помощью доски и мела, Кэнеди снял трубку, набрал номер и зачитал данные с доски.

Распечатка пришла, и получившееся оказалось так близко к проектной документации, которую мы тоже сделали, что были просто невероятные совпадения. И я взял и реализовал эту файловую систему, только на PDP-7. В какой-то момент я решил, что мне необходимо тестирование. И написал разные загрузочные штуки. Но у меня были проблемы при написании программ для файловой системы. Хотелось чего-нибудь интерактивного.

Сейбел: И вам просто хотелось поиграть с написанием файловой системы? В тот момент, получается, вы не собирались писать именно ОС?

Томпсон: Нет, это была просто файловая система.

Сейбел: И вы, таким образом, написали ОС, чтобы создать наилучшую среду для тестирования файловой системы.

Томпсон: Да. Примерно на полпути я понял, что это была настоящая система разделения времени. Я писал оболочку для запуска файловой системы. И еще пару программ, запускавших ее. Тут я подумал: «Осталось только сделать редактор, и у меня есть целая операционная система».

Сейбел: Какую самую страшную ошибку вам приходилось отлавливать?

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

Сейбел: То есть память портилась из-за аппаратных ошибок, а не из-за вышедшего из-под контроля указателя?

Томпсон: Мог быть указатель. Могло быть оборудование. Или и то, и другое. Та ошибка, которая мне сейчас вспомнилась как один из худших примеров, случилась на PDP-11. Там не было блока умножения, но его можно было докупить отдельно и подключить как периферию ввода/вывода. Сохраняешь числитель и знаменатель и запускаешь. Проходит цикл ожидания, затем выдается ответ — частное и остаток. И это было сделано под PDP-11 без управления памятью, а потом к нам пришло первое экспериментальное оборудование для PDP-11 с управлением памятью, и в результате блок умножения конфликтовал с управлением памятью.

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

Сейбел: Как же в итоге удалось ее отследить?

Томпсон: Я написал программу, которая должна была поставить мировой рекорд по нахождению знаков числа е. Предыдущие мировые рекорды были ограничены не вычислениями — количеством циклов в секунду, — а вводом/выводом. Я придумал новый алгоритм, узким местом которого были вычисления (ввод/вывод был тривиальным). Он был феерически тяжелым в отношении умножения и деления. И мы заметили, что машина каждый раз буквально обрушивалась, когда я запускал на ней эту свою программу. А потом и установили связь.

Сейбел: И это дало вам возможность понять, что проблема в умножителе. Вы сразу же нашли причину?

Томпсон: Сначала мы решили, что ошибка возникает, когда сохраняешь множитель в блоке умножения, потом обращаешься за ним, а его там нет. Мы обратились в компанию DEC, там ничего не нашли и не захотели связываться. Их слишком нормальным сотрудникам не хотелось иметь дело с гибридной машиной. В те дни у нас были принципиальные схемы машин, и мы, собственно, нашли ошибку по этой схеме. Потом мы позвонили в DEC и сказали им: «Соедините вот этот и вон тот проводки».

Сейбел: К счастью, сейчас оборудование так не сыплется.

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

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

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

Сейбел: Сегодня некоторые говорят: «Да, конечно, у ассемблера больше всего шансов повредить память из-за программных ошибок, но и Си склонен к этому больше, чем некоторые другие языки». Можно сделать так, что указатели будут указывать черт знает куда, и получится выход за границу массива. Вы не считаете, что это проблема?

Томпсон: Нет, ее можно обойти языковыми оборотами. Некоторые пишут хрупкий код, а некоторые — очень крепкий структурно, и тут все зависит от человека. Думаю, хрупкий код можно написать на любом языке. Я определяю хрупкий код так: допустим, требуется добавить функциональность, так вот в хорошем коде ее нужно добавить только в одно место, а в хрупком придется затронуть сразу десять мест.

Сейбел: Если появляется брешь в безопасности из-за переполнения буфера, то что вы можете ответить на критику Си и C++, где утверждается, что они частично за это ответственны, что многих проблем можно было бы избежать, если использовать язык, который проверяет границы массивов или в котором есть сборка мусора?

Томпсон: Ошибки есть ошибки. Вы пишете код с ошибками, просто потому что вы так пишете. Если язык безопасен в смысле безопасности времени выполнения, то операционная система упадет, а не переполнит буфер, став при этом уязвимой. Например, ping of death — атака на IP-стек операционной системы. Мне кажется, что будут еще атаки такого рода. Это будут не атаки типа «полностью захватить машину и стать суперпользователем». Это будут ping of death.

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

Томпсон: Есть две возможности стать суперпользователем: одна состоит в переполнении буфера, а другая — в том, чтобы указать программе сделать то, чего она делать не должна. В большинстве случаев реализуется вторая возможность, а не переполнение буфера. Вы можете стать суперпользователем без всяких переполнений. Так что ваш аргумент не работает. Все, что нужно сделать, — это уговорить su дать вам оболочку; все пути и так уже там есть, без каких-либо ошибок времени выполнения.

Сейбел: Ладно. Не будем говорить о том, что ведет к краху программы, уязвимости или чему-то подобному; есть такой класс ошибок, которые случаются в Си и C++, но почему-то не случаются, скажем, в Java. Есть ли для определенных типов приложений какие-то преимущества, весомые по сравнению с тем, что эти ошибки будут происходить и вызывать неприятности?

Томпсон: Думаю, этот класс ошибок доставляет не так уж много проблем. Разумеется, каждый раз когда я пишу один из вызовов функции, которая не проверяет длину строки, strcpy и тому подобное, я знаю, что фактически пишу ошибку. Но каким-то образом я принимаю решение о том, оправданна ли эта ошибка, нужно ли экономить аргументы. Сейчас обычно я их экономлю. Но имеется семантическая проблема: если вы обрезаете строку и используете обрезанную строку, то появляется новая проблема. Ошибка по-прежнему там, просто буфер еще не переполнен.

Сейбел: Какие инструменты вы используете при отладке?

Томпсон: В основном вывод на печать. При разработке программы я размещаю очень много операторов вывода на печать. И пока я их не убрал или не закомментировал, вывод на печать достаточно надежен. Мне редко приходится возвращаться к этому снова.

Сейбел: И что именно вы печатаете?

Томпсон: Все, что нужно, все, что удобно иметь под рукой. Инварианты. Но по большей части я печатаю во время разработки. Так я и выполняю отладку. Я не пишу программы с чистого листа — я беру программу и изменяю ее. Даже в большой программе я вывожу: «main, left, right, print, hello». Да, «hello» — это не то, что я ожидаю от этой программы. Я вывожу на печать то, что ожидаю увидеть, и отлаживаю эту часть. При разработке я запускаю программу двадцать раз в час.

Сейбел: Вы печатаете инварианты; а используете ли вы утверждения, которые проверяют эти инварианты?

Томпсон: Редко. Мне проще убедить себя, что они правильны, и либо закомментировать вывод на печать, либо отбросить их.

Сейбел: Почему же тогда вам проще напечатать, что инвариант верен, чем использовать assert для автоматической проверки?

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

Сейбел: Когда мы говорили о том, как вы создаете программы, вы упоминали процесс разработки снизу вверх. Вы строите эти кирпичики отдельно друг от друга?

Томпсон: Иногда.

Сейбел: А вы пишете тестовые модули для тестирования низкоуровневых функций?

Томпсон: Да, я так часто поступаю. Все зависит от программы, над которой я работаю. Если программа — это транслятор из А в Б, то я предложу целый спектр возможных А и соответствующих Б. Для регрессионного тестирования исполню все варианты А и проверю, насколько им будут соответствовать Б. Компилятор, транслятор, поиск регулярных выражений. Что-то вроде этого. Но есть программы, которые совсем не похожи на эти. Я никогда много не занимался тестированием и в этих программах мало понимаю. Я проведу несколько проверок, но они редко будут значительными, потому что, например, их будет тяжело проводить внутри самой программы. Главным образом это будут просто регрессионные тесты.

Сейбел: Под более сложными для тестирования программами вы понимаете, например, драйверы устройств и сетевые протоколы?

Томпсон: Вообще, они ведь запускаются каждый раз, когда вы запускаете систему.

Сейбел: То есть, по-вашему, таким образом можно избавиться от части ошибок?

Томпсон: Да, конечно. Что может быть лучше для тестирования операционной системы, чем постоянно запускать ее?

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

Томпсон: В первый раз я делаю программу насколько возможно простой. И очень часто этого достаточно. Строить очень сложный алгоритм для того, что никогда не будет запущено, просто глупо. Это трата времени и порождение ошибок. И поддерживать это невозможно, потому что придется исписать математическими формулами 50 страниц, чтобы рассказать другому парню, что ты, собственно, делаешь.

То, что сделано просто и методом грубой силы, 99% времени будет работать отлично. Если вы действительно создаете инструмент, который используется часто и местами проявляет квадратичную сложность, то иногда приходится вложиться в него как следует. Но чаще всего нет. Чем проще, тем лучше.

Сейбел: Некоторым просто нравится доводить код до блеска — так сказать, код для кода.

Томпсон: Да мне тоже нравится, но здесь во многом ради кода приходится жертвовать алгоритмом. Я имею в виду, что обычно сложный алгоритм требует сложного кода. А я лучше буду использовать простой алгоритм и простой код, чем какой-нибудь ужас. А если нужно как-то кратко охарактеризовать мой код, то могу сказать, что он простой, легко меняющийся и маленький. Ничего особо интересного. Его может прочесть любой.

Сейбел: Есть ли еще такие задачи, для решения которых в целях производительности приходится работать вручную с ассемблером?

Томпсон: Это редкость. Это музейная редкость — разве что вы можете таким образом получить порядковую разницу. Если вы можете усердно работать и заставить маленький кусочек большой программы исполняться в два раза быстрее, то и всю программу можно заставить исполняться в два раза быстрее, если только подождать год-другой. Если вы пишете компилятор, то, безусловно, 99% кода, который вы пишете, будут исполнены один или два раза. Но будет крохотная часть в операционной системе, которая работает 24 часа в день. А еще более крохотная — в самом внутреннем цикле такой системы. Так что, возможно, только 0,1% оптимизации, которую вы применили к компилятору, обернется для ваших пользователей каким-то эффектом. Но притом эффект может оказаться глубоким, так что, возможно, вы все равно захотите эту оптимизацию выполнить.

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

Томпсон: Да, да.

Сейбел: Так что, возможно, часть причин, по которым программы пишут прямо на ассемблере, ныне менее важна, потому что компиляторы стали лучше.

Томпсон: Нет. Думаю, главным образом машины стали намного лучше. А компиляторы — все такой же отстой. Посмотрите на код, который выходит из GCC, это же ужасно. Просто плохо. И еще чертовски медленно. В самом компиляторе более 20 проходов. Это просто чудовищно медленно, но компьютеры-то стали в 1000 раз быстрее, с тех пор как вышел GCC. Поэтому кажется, что он стал быстрее: он ведь не стал настолько медленнее, насколько повысилось быстродействие компьютеров, на которых он запущен.

Сейбел: Кстати было бы упомянуть сборку мусора. С появлением Java сборка мусора наконец-то пошла в массы. Как однажды сказал Деннис Ричи, Си активно сопротивляется сборке мусора. Хорошо ли, что сейчас наблюдается явная тенденция к языкам со сборкой мусора? Заслуживает ли эта технология настолько массового использования?

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

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

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

Сейбел: Кем вы себя считаете — ученым, инженером, художником, ремесленником или кем-то еще?

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

Сейбел: Ладно, если не учитывать то, как вы сами себя называете, то с какой профессией больше всего связана ваша? Физик, мостостроитель, художник, плотник?

Томпсон: Что-то ближе к низкому уровню. Например, ремесленник, но с творческой жилкой.

Сейбел: Как вы определяете талантливого программиста?

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

Сейбел: Представляю себе. Это что-то вроде устного экзамена. А случалось ли вам встречаться с людьми, которые просто по личным качествам не могли такой экзамен выдержать, но при этом обладали весьма приличными способностями к программированию?

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

Сейбел: Чем вы занимаетесь в Google?

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

Сейбел: Это ведь ключевая идея знаменитой гугловской системы обработки MapReduce, которая заключается в том, что нет совместного владения, есть пересылка сообщений, а не разделяемая память?

Томпсон: Ну, это процесс с хорошо известной семантикой, не включающий цикл обратной связи. Если у вас есть для него надежная инфраструктура, то с ее помощью можно решить множество задач.

Сейбел: И вы работаете в рамках этой структуры?

Томпсон: Нет, мы просто хотим переложить бремя ответственности с плеч отдельных программистов. Это сложная задача. Все оборудование здесь имеет массу слоев, обрабатывающих ситуации, когда не работает то-то и то-то. Что будет, если я не работаю, — кто меня убьет, кто стартует, кто что будет делать. Думаю, больше 50% создаваемого кода имеет вид «что, если».

Сейбел: То есть ваша задача — сделать так, чтобы половины такого кода больше не было?

Томпсон: Чтобы он был где-то скрыт. Он будет систематическим образом прилагаться к другому коду. То есть мы на это надеемся. Задача-то трудная.

Сейбел: Вам нравится работать в Google?

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

Сейбел: То есть вы главным образом заняты производством. Можете ли вы сравнить работу в Google Labs с вашей прежней деятельностью в Bell Labs? Что между ними общего?

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

Сейбел: Я знаю, что в Google есть правило, когда каждый новый сотрудник проверяется на знание языков, прежде чем ему разрешают вносить код в репозиторий. То есть вас должны были проверять на знание Си.

Томпсон: Да, но меня не проверяли.

Сейбел: Не проверяли! Вы не можете вносить код в репозиторий?

Томпсон: Да, не могу.

Сейбел: Вы просто не стали этим заниматься или у вас есть какие-то философские возражения относительно стандарта кодирования Google?

Томпсон: Не занимался. А потом понял, что мне это не нужно.

Сейбел: То есть вы работаете в своей песочнице? Большей частью пишете на Си?

Томпсон: Да, в основном на Си. И тестирование, и так поиграться — на Си, а стандарт Google — C++, и только C++. Не велико искусство программировать на C++, но мне не нравится. Вызывает внутреннее сопротивление.

Сейбел: Вы работали в AT&T с Бьерном Страуструпом. Вы каким-то образом участвовали в разработке C++?

Томпсон: Похоже, у меня сейчас будут проблемы.

Сейбел: Не без того.

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

В интервью я именно так и сказал, что не использовал этот язык просто потому, что он был нестабилен и менялся каждый день. Когда это интервью прочитал Страуструп, он с криком ворвался в мою комнату, вопил, что я его унизил тем, что там сказал, а сказал я, оказывается, что это плохой язык. Хотя я ничего подобного не говорил. И опять по кругу. С того раза я таких вещей стараюсь избегать.

Сейбел: Как вы сейчас считаете: хороший это язык или плохой?

Томпсон: Безусловно, у него есть сильные стороны. Но в принципе я считаю, что этот язык плохой. Многое он делает только наполовину, к тому же это просто куча взаимоисключающих идей. Все, кого я знаю лично или по работе в компании, выбирают подмножество этого языка, и это разные подмножества. Так что это не лучший язык для передачи алгоритма — для того чтобы сказать: «Вот, я написал, пользуйтесь». Он слишком велик, слишком сложен. И, очевидно, порожден комиссиями.

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

Сейбел: Как вы считаете, это связано с тем, что ему нравились все идеи, или же это был способ заставить принять язык, который каждому давал то, что он хочет?

Томпсон: Скорее второе, чем первое.

Сейбел: Похоже, многие говорят: «Черт возьми, C++ — это ужас!» При этом все его используют. Например, это один из четырех официальных языков Google. Почему же тогда его продолжают использовать, раз он так плох?

Томпсон: Не знаю. Думаю, он доживает последние дни в Google. Сейчас здесь больше его противников, чем сторонников.

Сейбел: И они переходят на Java?

Томпсон: Не знаю. Почти нет. Они жалуются, но не меняют язык. Вчерашние студенты — новобранцы Google — об этом знают. Поэтому сложно заниматься чем-нибудь другим. Вот почему его продолжают использовать — не нужно тратить массу времени на обучение и переобучение. С ним отдача быстрее.

Сейбел: Есть ли другие языки, на которых вам нравилось программировать?

Томпсон: В общем, все забавные языки, с которыми мне доводилось иметь дело. Например, для решения уравнений и всего такого — такие как Maple и Macsyma. Для строк — Снобол. В общем, я имел дело с десятками языков, если только с их помощью могло получиться что-то интересное мне.

Сейбел: А с какими инструментами разработки вам больше всего нравилось работать?

Томпсон: Я люблю уасс. Мне очень нравится уасс. Она делает как раз то, чего от нее хочешь. А вот ее дополнение Lex — просто ужас. Не делает ничего из того, что надо.

Сейбел: А вы им все равно пользуетесь или пишете лексические анализаторы вручную?

Томпсон: Пишу вручную. Так намного проще.

Сейбел: Доводилось ли вам заниматься литературным программированием по примеру Дональда Кнута?

Томпсон: Нет. Это отличная идея, но на практике реализовать ее почти невозможно.

Сейбел: Почему?

Томпсон: Получаются две версии одной и той же программы, которые часто рассинхронизируются и начинают конфликтовать. И исправить это нет никакой возможности. Если что-то хорошо написано на языке программирования, то это читабельно. И достаточно. Комментарии здесь не нужны. Комментарии, пожалуй, хороши для алгоритмов, или, например, если вы делаете что-то очень хитроумное, тогда они должны быть скорее в форме предупреждений. Я не любитель развернутых комментариев, это общеизвестно.

Сейбел: Когда я беседовал с Кнутом, он сказал, что ключ к техническому писательству — говорить одно и то же дважды взаимно дополняющими друг друга способами. Думаю, он считает это достоинством, а не изъяном литературного программирования.

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

Сейбел: Вы читали какую-нибудь из его литературных программ?

Томпсон: Только то, что было в его ранних статьях. Из недавнего — ничего.

Сейбел: Есть ли книги, которые вы считаете особенно важными для себя либо можете порекомендовать другим?

Томпсон: Я не читаю книги по программированию для начинающих, так что затрудняюсь что-то рекомендовать. Если мне приходится учить новый язык или что-то в этом духе, я стараюсь найти книгу по нему. Я предпочитаю сжатые информативные книги, которые описывают только синтаксис и семантику, а не такие, где сплошная болтовня и где мне пытаются объяснить, какой стиль хороший, а какой плохой.

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

Сейбел: Когда вы придумывали UNIX, у вас был план сделать четыре части, из которых впоследствии возникнет операционная система. Тогда ваши жена и ребенок уехали на месяц, не мешая вам работать. Предполагаю, что в тот месяц вы работали не разгибаясь. Зачем мы делаем это? По необходимости? Или просто получаем от этого удовольствие?

Томпсон: Так поступаешь, когда увлечен. Вообще не представляю, чтобы я мог не написать UNIX. Кроме того, когда жена и ребенок рядом, ты прикован к 24-часовому циклу. Когда они уехали, 24-часовой цикл стал для меня менее обязательным. Мне вовсе ни к чему следовать за солнцем. Поэтому я обычно сплю по 6 часов в соответствии с 27- или 28-часовым циклом. В плавающем режиме. Когда я сплю до естественного пробуждения, я в лучшей форме, чем когда просыпаюсь от детского плача.

Сейбел: Так бывает, когда увлекаешься проектом и встаешь с желанием поскорее сесть за компьютер и писать код. Но иногда люди перерабатывают, потому что охвачены идеей срочно выпустить продукт, так что всем приходится работать по 80-100 часов в неделю.

Томпсон: Так сгорают на работе. Когда я был увлечен, то получал от программирования удовольствие и никогда не испытывал стресса.

И бывал в других ситуациях, когда установленные кем-то жесткие сроки порождают стресс. В этом нет ничего забавного, мне это не нравится.

Сейбел: Да, сгораешь на работе, и это, безусловно, плохо, но ведь в итоге работа сделана за более короткое время — может, оно того стоит?

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

Сейбел: Со стремлением успеть к дедлайну напрямую связано умение оценить, сколько времени у вас отнимет та или иная деятельность. Можете ли вы оценить, сколько времени будете писать тот или иной кусок кода?

Томпсон: Зависит от того, для себя я пишу или для производства. Если пишу для себя, то могу. Я могу смириться со странностями. Я могу не делать лишние десять процентов. Я могу избегать зияющих дыр, которые, как я знаю, там есть. И все такое. Я могу сделать продукт, потом подчистить его на досуге и продолжать использовать. Возможно, это другое определение готовности. Но если делаешь продукт для производства, то тут вмешиваются другие люди, нужна координация усилий — этого я просчитать не могу.

Сейбел: В одном из интервью 1999 года вы сказали, что невысоко ставите Linux, и фанаты Linux приняли это в штыки. Что вы можете сказать сейчас, спустя десятилетие, когда эта система почти что завоевала мир?

Томпсон: Она гораздо надежнее — здесь нет никаких сомнений. И я как-то заглянул в ее код. Не так углубленно, как, например, в Plan 9. Они всегда нас опережали, просто у них намного больше ресурсов для работы с оборудованием. Так что, когда мы работали с каким-то элементом оборудования, я смотрел на драйверы Linux и писал в сравнении с ними драйверы для Plan 9. Сейчас у меня нет причин заглядывать в драйверы, я запускаю Linux. И иногда смотрю в код, но редко, так что не могу сказать, выросло качество или нет. Но надежность, несомненно, значительно возросла.

Сейбел: Вы когда-нибудь читаете код просто ради интереса?

Томпсон: Раньше я часто так делал. Когда я только пришел сюда, делал это, чтобы попрактиковаться и уловить рабочую атмосферу. Думаю, это нужно делать. Есть много того, что не говорится, но тем не менее следует знать.

Сейбел: Вы брали программу, чтобы полностью понять ее, или просто просматривали, как и что сделано?

Томпсон: То и другое. Сначала я пытался разобраться в больших библиотеках, рассматривал основные программы. В Google очень странный стиль программирования. Они берут вызов подпрограммы, запаковывают его как RPC и сохраняют как нечто статичное. То есть каждый может обратиться к нему в любой момент по любому поводу. И потом они вызывают групповой слушающий код и кто-то где-то получает сообщение, идет и находит вот это и выполняет этот вызов подпрограммы.

Сейбел: Это механизм распределенных вычислений.

Томпсон: Да. И это все, что делает это место. Его очень сложно читать. Выругаешься и начинаешь читать связующий код. А потом этот код. А потом общий код межпроцессного взаимодействия. Так и начинаешь осознавать, как читать код и понимать его. А до этого ничего не понимаешь.

Сейбел: Работая в команде, какую структуру вы предпочитаете?

Томпсон: Просто работать с хорошими и совместимыми людьми.

Сейбел: Работая с совместимыми людьми, предпочитаете ли вы четкое распределение ответственности: «Этот кусок кода пишу я, он мой и я несу за него ответственность», — или коллективную ответственность: «Мы все владеем этим кодом, и любой может делать то, что считает подходящим»?

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

Сейбел: Сегодня кое-кто ратует за парное программирование — двое за одной клавиатурой. Вы работали таким образом?

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

Сейбел: И как, результат был лучше или дела шли быстрее?

Томпсон: Результат точно не лучше. Возможно, ускоряется отладка: пока печатаешь, кто-то может отловить ошибку из-за твоего плеча. Так что ошибок должно получаться меньше. Но я не принимаю это за принцип — просто так получается.

Сейбел: Вам по-прежнему нравится программировать?

Томпсон: Да, я люблю небольшие программы. Небольшие — то есть те, с которыми можно управиться за месяц. А взяться за какую-нибудь чудовищную задачу, на которую нужен год, — тут я пас.

Сейбел: Так было всегда или просто уже не хватает энергии на долгосрочные проекты?

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

Сейбел: Вы в основном занимались исследованиями, то есть у вас был простор для работы. Изменилась ли ситуация, когда это стало работой? Не пропал ли интерес?

Томпсон: Нет. Интерес всегда был, главным образом потому, что я выбрал то, что хотел. И даже когда это стало профессией, в колледже-то было доступно множество вариантов профессий. Мне казалось, что многие вокруг что-то делают, чем-то заняты, и им можно помочь, написав небольшую программу. Это было для меня идеально. Я мог заниматься небольшими подработками, выбирая себе время и тот тип работы, который мне был особенно интересен.

Одна из первых подработок была у профессора-гуманитария, который каталогизировал труды Гомера. У него были «Илиада» и «Одиссея» на перфокартах. Ему были нужны частота употребления слов и их количество, то есть сравнительный статистический анализ этих двух поэм. И это было интересно. Это была работа с текстом, которую в те дни компьютеры просто не выполняли. Да, это и была моя первая странная подработка.

Сейбел: В интервью 1999 года вы рассказали, как убедили сына заниматься биологией, а не компьютерами, потому что те исчерпали себя. Это было почти десять лет назад. Что вы об этом думаете сейчас?

Томпсон: То же самое. В компьютерной сфере не происходит ничего, что нельзя было бы предсказать. Последним значительным событием стал, думаю, Интернет, а в 1999 году он уже работал. Да, все растет, скорость персональных компьютеров продолжает экспоненциально расти, но что радикально нового?

Сейбел: Когда читаешь историю UNIX, кажется, что вы, ребята, изобрели операционную систему, просто чтобы поиграть с этим компьютером. То есть для того, чтобы сделать какую-то простую штуку — написать игру или что-то подобное на компьютере, пришлось сначала писать целую операционную систему. Чтобы хоть что-то начать делать, нужны были компиляторы и серьезная инфраструктура. Уверен, все это само по себе было интересно. Но не является ли сложность современного программирования, о которой мы уже говорили, нынешним эквивалентом все того же «Итак, в первую очередь ты должен создать собственную операционную систему!» По крайней мере, сейчас этого делать не нужно.

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

Сейбел: Я все думаю о вашем совете сыну — заняться биологией вместо компьютеров. Нет ли в программировании чего-то такого — интеллектуального удовольствия от определения процесса, который эти волшебные машины могут для вас выполнить, — вроде как ты работаешь с железом, но на очень абстрактном уровне?

Томпсон: Это затягивает. Но вы ведь не предложите своему ребенку попробовать крэк. Думаю, все изменилось. Может, я просто старею, но кажется, что когда накладываешь слой на слой, а затем еще слой, это не приносит такой радости, как, например, создание детерминированного конечного автомата. Да, разумеется, дело и в алгоритмах: со временем они становятся все сложнее. Новый алгоритм — это нечто основанное на пятидесяти мелких алгоритмах. А когда я был молодым, достаточно было писать один такой маленький алгоритм — и это было интересно. Их можно было понять, не прибегая к сложным вычислениям, когда алгоритмы надо делить на блоки, когда вот этот блок решается тем алгоритмом, о котором читал, но на самом деле почти ничего не знаешь, и так далее. Так что все изменилось. Я действительно так считаю и во многом из-за того, что постоянно надстраиваются новые слои, с которыми мы и имеем дело. А может, я просто слишком стар, чтобы их понять.