Так или иначе, вышло, что есть четыре набора макросов, несовместимых друг с другом, и я решил заняться стандартизацией — или всеобщим примирением. Я заметил, что куда-то ушел дух товарищества, взаимопомощи, потому что уже нельзя было просто подсесть к чужому терминалу. И я сказал: «Ну вот, мы попробовали то и это, возникло много идей. Давайте придумаем общие и удобные для всех сочетания клавиш».
Я бегал с блокнотом по всему зданию, говорил со всеми этим парнями по несколько раз, пытаясь найти общий знаменатель. Я пытался как-то организовать те сочетания клавиш, которые они выбрали, пытался сделать так, чтобы они легко запоминались и складывались хоть в какую-то систему. Я не заботился об удобстве печатания вслепую, меня такие вещи вообще мало интересуют: я заботился о легкости запоминания. Вот почему Meta-C, Meta-L, Meta-U означают «с заглавной буквы», «строчные буквы», «заглавные буквы»[66].
Сейбел: Это в своем роде ирония, учитывая то, каким образом команды направляются от мозга к пальцам. Вы, наверное, тоже сталкивались с этим: кто-нибудь спрашивает о сочетании клавиш, которое вы используете сто раз в день, — и вы не способны ответить.
Стил: С этим сталкивалась моя жена. Это как-то прошло мимо меня — я не слишком ловко управляюсь с клавиатурой. Жена 20 лет не пользовалась Emacs, пока я не поставил эту программу на ее Макинтош. Она что-то ввела и спросила: «А как сохранить? Я забыла, как сохраняют файлы». Ее пальцы делали это автоматически, и она не помнила само сочетание. Тогда она проделала это, следя за своими пальцами, и сказала: «Ах да, Ctrl-X, Ctrl-S». To есть она печатала неосознанно.
Сейбел: Вы установили стандартные сочетания клавиш. Как это прошло? Люди были довольны?
Стил: Им пришлось, конечно, приложить усилия. Потом я занялся реализацией. Одновременно появилась и другая идея: можно заставить макросы ТЕСО работать быстрее, если сжать пробелы и убрать все комментарии. Интерпретатор ТЕСО обрабатывал символы последовательно, поэтому приходилось ждать, пока он пройдет очередной комментарий. Вот мы и решили создать примитивный компилятор ТЕСО, который бы сжимал пробелы, убирал комментарии и делал еще кое-что для ускорения работы.
И я поначалу решил разработать уплотнитель макросов на основе идеи Муна. То есть идея была не моя. Я стал думать, как организовать первые несколько функций, взял в качестве примера уже имевшиеся пакеты макросов, сделал своего рода синтез. Тут появился Стеллмен и сказал: «Чем ты занят? Выглядит интересно». Он подключился к этому делу, и все пошло в десять раз быстрее — Ричард знал ТЕСО досконально.
Выходит, я всерьез работал над реализацией Emacs 4-6 недель, не больше. Потом стало ясно, что Стеллмен все понял в этой программе, и я могу возвращаться к моим магистерским делам. Стеллмен сделал 99,999% всей работы. Но начал ее я.
Сейбел: Сменим тему. Компьютерные науки сегодня тесно связаны с математикой. Насколько важно для программиста-практика вникать, скажем, в математику из Кнута? Или лучше так: «Мне тут нужно отсортировать, пролистаю-ка я Кнута до того места, где он говорит „это наилучший алгоритм", и реализую его»?
Стил: Не знаю... У меня нет математического образования, и мне понятно у Кнута не все, особенно из области высшей или непрерывной математики. Здесь я плаваю. Комбинаторика, перестановки, теория групп — другое дело, все это я часто использую. Это мое рабочее орудие. Не каждому программисту нужна математика, но она упорядочивает понятия, с которыми программисты сталкиваются ежедневно.
Приведу пример из моей недавней работы над параллельными языками в рамках проекта Fortress. Предположим, вам надо сложить сколько-то чисел. Вы можете начать с нуля и прибавлять числа одно за другим — это традиционный последовательный подход.
Заметим, что у операции сложения есть нейтральный элемент. Вы должны начать с нуля. Тривиальное замечание, но все же сделаем его.
А можно сделать по-другому — расположить все числа в ряд и складывать их попарно. Вы получите ряд сумм, и в конце концов останется лишь одна сумма. Если количество чисел нечетное, последнее из них прибавляется к общей сумме и так далее. Этот метод тоже вполне применим. Для чисел с плавающей запятой надо быть строже в расчетах, хотя порой это не требуется — слишком велики издержки.
Результат получится тот же самый, по крайней мере, если мы имеем дело с целыми числами, как если бы мы начинали с нуля и прибавляли числа по одному, — в силу ассоциативности сложения. Иными словами, неважно, каким образом вы группируете числа.
Есть и третий метод. Допустим, имеется сколько-то процессоров. Вы распределяете пары по процессорам. Алгоритм «начать с нуля и прибавлять числа по одному» трудно распараллелить, а вот при методе разбивки на пары у вас как бы образуется дерево, разные части которого обрабатываются разными процессорами. Они делают это независимо друг от друга, и лишь в конце операции должны взаимодействовать между собой, чтобы вы получили сумму.