Эта заметка была впервые опубликована в Usenet автором, Эдом Натером (utastro! Nather) 21 мая 1983 года. Вполне вероятно, что на момент публикации вы еще даже не родились на свет. Полагаем, эту историю необходимо сохранить — хотя бы потому что теперь от настоящего «железа» мы отделены толстым слоем абстракций. Читайте и получайте удовольствие! В одной из недавних статей [относительно 1983 года — прим. перевод.], посвященных так называемому «программированию для крутых мачо», автор ничтоже сумняшеся утверждал: «Настоящие программисты пишут на Фортране». Что ж, вполне возможно, что в нашу эру легкого пива, портативных калькуляторов и «удобного» программного обеспечения это действительно так. Однако в старые-добрые времена, когда сам термин «программное обеспечение» казался забавным, а компьютеры были начинены всевозможными барабанами и электронными лампами, всё было совсем иначе. Реальные программисты умели писать в машинных кодах. Да-да, вы верно поняли: они использовали те самые, «грубые, непостижимые, неотесанные» 16-битные числа. Напрямую. Чтобы целое новое поколение программистов не потеряло знание о славном прошлом своих «отцов», я считаю своим долгом как можно тщательнее рассказать, как «настоящий» программист писал код. Имя ему будет Мэл — потому что его на самом деле так звали. Я познакомился с Мэлом, когда устроился на постоянную работу в Royal McBee Computer Corp — ныне несуществующую дочернюю компанию одной фирмы по производству печатных машинок. Royal McBee разработала LGP-30 — небольшой, относительно дешевый (по меркам тех лет) компьютер с барабанной памятью — и готовилась начать производство новой машины, RPC-4000, существенно доработанной и улучшенной модели на (бадум-тсс!) все той же барабанной памяти. Однако стоили новые модели непомерно дорого, и рынок их отверг. Полагаю, именно по этой причине вам никогда не приходилось слышать ни об этой компании, ни о самой машине. (На самом деле, здесь автор чуть лукавит. Машинка от компании Royal «засветилась» в романе Стивена Кинга «Мизери». Впрочем, на Кинге (и еще паре авторов беллетристики) славная история Royal заканчивается. — прим. перевод.) Конкретно я занимался написанием компилятора FORTRAN для этой чудо-машины, а Мэл был моим «проводником» по его электронным премудростям. Так вот, Мэл компиляторы не одобрял. «Если программа не может переписать свой собственный код», — спрашивал он, — «какая вообще в ней польза?». Среди заслуг Мэла числилось написание (шестнадцатеричными машинными кодами) самой популярной программы, которой владела компания — блэкджека. На компьютерных выставках потенциальные покупатели могли сразиться с LGP-30. Надо ли говорить, что игра имела оглушительный успех? На каждой выставке стенд с LGP-30 был переполнен — в то время как продавцы IBM-машин лениво болтали друг с другом, лишенные аудитории. А что касается реальных продаж наших компьютеров — мы старались не поднимать этот вопрос. Теперь работа Мэла состояла в переписывании блэкджека под RPC-4000. (Портирование? А что это такое?) Новый компьютер имел схему адресации «один плюс один»: каждая машинная инструкция, помимо кода операции и адреса операнда, имела дополнительный адрес, указывающий, где на вращающемся барабане расположена следующая инструкция. В современных терминах — за каждой инструкцией следовала команда GO TO. Каково, а? Забейте этой дурью трубку Паскаля и как следует затянитесь, чтобы осмыслить! Мэлу нравился RPC-4000. На нем можно было оптимизировать код, размещая инструкции на барабане таким образом, чтобы по завершении одной вторая могла бы выполниться немедленно. У нас была специальная программа для этих целей, оптимизирующий ассемблер, однако Мэл отказался ее использовать. «Никогда не знаешь, куда и что он запихнет», — объяснял он, — «и придется использовать дополнительные константы». Прошло немало времени, прежде чем я понял эту ремарку до конца. Мэл знал числовое значение каждого кода операции и мог назначать собственные адреса на барабане. А каждую написанную им инструкцию можно было рассматривать как числовую константу. К примеру, он мог взять инструкцию сложения (если, конечно, она имела нужное значение) и умножить на неё другое число. Так что работать с кодом Мэла мог только сам Мэл. Я сравнивал программы Мэла, оптимизированные вручную, с результатами оптимизирующего ассемблера на том же исходном коде. И результат Мэла всегда оказывался лучше. Думаю, всё из-за того, что метод разработки «сверху вниз» еще не был изобретен. А если бы и был, Мэл все равно отказался бы его использовать. В первую очередь Мэл писал самые сложные фрагменты программных циклов, чтобы первыми разместить их на оптимальных адресах барабана. Наш оптимизирующий ассемблер был не настолько хитер и дальновиден. Кроме того, Мэл никогда не использовал циклы, чтобы создать задержку в выполнении кода — даже если неуклюжему Flexowriter’у для корректной работы требовался перерыв между выходными символами. Мэл размещал инструкции на барабане таким образом, чтобы каждая из них проходила мимо считывающей головки строго в нужный момент. Барабану требовался один полный оборот, чтобы отыскать следующую — вот и необходимая задержка. Никогда не забуду, какой термин он придумал для этой процедуры. Слово «оптимум», несмотря на его абсолютную природу, часто используют в относительных выражениях: «недостаточно оптимально» или, например, «совсем не оптимально». Мэл пошел еще дальше. В рамках своего подхода он назвал максимально возможную задержку «абсолютным пессимумом». Закончив переписывание блэкджека и протестировав его на компьютере («Даже инициализатор оптимизирован» — хвалился Мэл), он ни с того ни с сего получил от отдела продаж запрос на доработку. В программе использовался весьма элегантный (оптимизированный) генератор случайных чисел для операций перетасовки карт и раздачи рук из «колоды». Кому-то из продавцов показалось «несправедливым», что покупатели периодически проигрывают. Соответственно, Мэлу дали задание доработать программу так, чтобы при нажатии на сенсорную кнопку на консоли компьютера программа «подыгрывала» покупателям. Мэл возмутился. Он чувствовал, что это нечестный ход (так оно и было!), реализация которого, к тому же, посягает на его программистскую неприкосновенность. Он наотрез отказался менять программу. Главный продавец, начальник и некоторые коллеги по очереди уговаривали Мэла внести изменение в код. В конце концов, Мэл сдался и доработал игру. Правда, в обратном направлении: при включенном переключателе программа жульничала и выигрывала, а при выключенном вела игру честно. Мэл был в восторге от своего решения. Он утверждал, что его подсознание «неуправляемо этично» и категорически отказался от любых дальнейших исправлений. После того, как Мэл ушел из компании в поисках более «экологичной» работы, Большой Босс попросил меня взглянуть на код и попытаться устранить из него «совесть» Мэла. Я согласился, но без особого желания. Работа с программой Мэла грозила вылиться в целое приключение. Я часто ловил себя на том, что думаю о программировании как об отдельном виде искусства, реальную ценность которого может оценить лишь посвященный. В коде могут быть великолепные перлы, блестящие находки, скрытые от обывательского взора, порой даже навсегда, в силу природы процесса. Многое можно узнать об авторе программы, прочитав его код, пусть даже в шестнадцатеричных числах. Я лично считаю, что Мэл был невоспетым гением. Наверное, самым большим шоком для меня стал один невинный безусловный цикл. Серьезно, в нем не было ни одного условия выхода. Здравый смысл подсказывал мне, что программа будет крутиться в нем бесконечно долго. Однако в реальности компьютер вошел в цикл и без проблем из него вышел. Две недели ушло у меня, чтобы понять, как Мэл это устроил. В компьютере RPC-4000 был один действительно современный инструмент, называемый индексным регистром. Он позволял программисту организовать циклы с применением так называемых индексированных инструкций. Каждый проход число в индексном регистре прибавлялось к адресу операнда, что позволяло получить адрес следующего элемента данных в массиве. Оставалось только каждый раз увеличивать содержимое индексного регистра на единицу. Мэл никогда этим не пользовался. Вместо этого он помещал инструкцию в машинный регистр, добавлял к ее адресу единицу и сохранял. Измененную инструкцию затем можно было выполнить прямо из регистра. Цикл был организован с учетом дополнительного времени на выполнение такой инструкции. Как только она «кончалась», следующая оказывалась прямо под считывающей головкой барабана, готовая к чтению и исполнению. Но этом в цикле тоже не было условия выхода. Я заметил, что бит, указывающий на использование индексного регистра (бит находился между адресом и кодом операции в слове инструкции), был установлен. Это была важная подсказка: Мэл никогда не пользовался индексным регистром, оставляя его значение нулевым. Подход Мэла буквально ослепил меня изяществом и совершенством. Он расположил все данные, с которыми работал, в верхних адресах памяти, поэтому после обработки последнего элемента инкрементирование адреса инструкции приводило к переполнению. Бит переноса добавлял единицу к коду операции, подменяя его значение инструкцией перехода. Разумеется, следующая программная инструкция хранилась по нулевому адресу, и программа успешно продолжала свой путь. Я не поддерживаю связь с Мэлом, поэтому не знаю, поддался ли он водовороту изменений, захлестнувшему мир программирования в последние годы. Мне лично хочется думать, что он до сих пор работает по-старому. Я был настолько впечатлен работой Мэла, что перестал искать «баг», приводящий к жульничеству в блэкджеке. Боссу я сказал, что не справился — он кивнул и будто бы не удивился такому исходу. Когда я ушел из компании, программа блэкджека по-прежнему мухлевала при включенной кнопке. Я считаю, что поступил правильно. Мне было стыдно взламывать код Настоящего Программиста. К сожалению, история не сохранила для нас никаких-либо других упоминаний «настоящего программиста» Мэлвина Кея (Melvin Kaye). История Эда Натера (R. Edward Nather, 1947-2014) — своеобразный памятник программистам, видевшим код не как нагромождение инструкций и функций, а как цельное произведение интеллектуального искусства. Напоследок напишем пару слов о самом Натере. В научных кругах он был известен в первую очередь как астроном, профессор Техасского Университета (Остин) и специалист по астросейсмологии, белым карликам и наблюдению за взаимодействием потухших бинарных звезд. Кроме того, Натер в течение 10 лет являлся директором Whole Earth Telescope. Интернет-популярность ученому принесла публикация истории о Мэле в Usenet. Что касается программы для игры в блэкджек — предлагаем вам ознакомиться с инструкцией по ее применению за авторством Мэла. Для тех же, кому оригинальной статьи оказалось маловато приводим следующую ссылку: История Мэла с объяснением технических деталей (на английском языке).