Джон Бэкус

3 апрель, 2007 - 17:07Андрей Зубинский

17 марта в возрасте 82 лет ушел из жизни человек, имя которого для многих стало понятным синонимом для непонятного словосочетания "программная инженерия".

Джон Бэкус

Сегодня почти все далекие от программирования люди слышали слово FORTRAN, а подавляющее большинство даже самых малограмотных кодировщиков знает аббревиатуру BNF. В принципе, этих двух достижений (а это действительно Достижение, когда созданное тобой нечто, изначально предназначенное для квалифицированных специалистов, "перерастает" все профессиональные ограничения и становится частью общеупотребительного языка) более чем достаточно для того, чтобы совершенно законно присвоить Джону Бэкусу титул "выдающийся", и, для завершения статьи, перечислить регалии великого разработчика. Но это будет неинтересно. Мы попробуем поговорить не столько о самом Джоне Бэкусе, сколько о менее известных его достижениях, о том, что скрывается за фасадом обыденных (а они уже практически обыденные) слов, таких как FORTRAN. Больше того, - мы даже упомянем инструменты, с помощью которых любой желающий может сегодня почувствовать себя "в шкуре" Джона Бэкуса начала 50-х годов прошлого века.

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

Именно благодаря невозможности приобрести желаемое Бэкус решил... научиться создавать аппаратуру самостоятельно. Причем не просто "делать", а именно создавать, проектировать такой, какой хотелось ее видеть только ему. А для этого надо было знать радиотехнику, потому выбор был очевиден - радиотехническая школа. Там Джон Бэкус сталкивается с весьма непростой, но скучной (точнее, однообразной в механизме решения) математической задачей расчета амплитудно-частотной характеристики усилителя. Удивительно, но эта задача увлекает юношу, и он решает заняться математикой всерьез. Ну а дальше все просто: Колумбийский университет, случайное знакомство в 1949 г. с примитивным электромеханическим вычислителем IBM SSEC (Selective Sequence Electronic Calculator), переросшее в три года работы. Именно тогда, в эти первые три года программирования машины с долговременной памятью на перфолентах, Бэкус создает то, что сегодня мы называем "плавающей точкой", а в те времена называлось "масштабирующий фактор" и позволяло оперировать числами или слишком большими, или слишком малыми для разрядной сетки машины. В конце 1953 г. IBM выпускает компьютер модели 704 со встроенной реализацией "масштабирующего фактора", уже называемой "плавающей точкой", и в том же году Бэкус пишет докладную записку своему непосредственному начальнику с просьбой одобрить создание языка программирования для этой машины. Собственно, с этого момента и начинается отсчет новой эпохи - той самой, в которой мы с вами запускаем наши компиляторы командной строки или IDE и бодро стучим по клавишам, представляя наши компьютеры чем-то, что способно исполнять выбранный нами язык программирования.

Кстати, для многих зависимых от заблуждений любителей возмущаться ужасающим дисбалансом между стоимостью CD-RW-диска и записанными на нем программами опыт Джона Бэкуса - единственное доступное избавление от зависимости. И для "процедур" нет никакой нужды пытаться за безумные деньги купить раритетные, чудом сохранившиеся останки компьютера модели 704 - симулятор немного более развитой модели - IBM 709 - доступен всем желающим . Равно как и документация на совершенно немыслимые 25 тысяч строк машинного кода, которые и есть компилятор FORTRAN. И попробуйте, пользуясь только симулятором (!), написать код и создать документацию такого класса!

К сожалению, в новой эпохе, время которой уже не отсчитывает дни жизни Джона Бэкуса, совсем немногие знают о его поздних по сравнению со сделавшими его знаменитым работах. В 1977 г., получая самую престижную награду компьютерного мира, The ACM Turing Award, Бэкус произнес речь, каждая фраза которой удивительно актуальна и сегодня. С первыми же словами выступления почти тридцатилетней давности и сейчас согласится любой программист: "Традиционные языки программирования чудовищно разрастаются, но не становятся сильнее. Наследственные дефекты на всех базовых уровнях приводят к тому, что языки становятся одновременно "жирными" и "слабыми": их примитивный стиль "одна операция в один момент времени" наследуется от единого для всех языков предка - архитектуры машины фон Неймана...". Более того, само название тьюринговской лекции Бэкуса многим покажется странным: "Можно ли освободить программиста от фоннеймановского стиля? Функциональный стиль и определяемая им алгебра программ". О каких же наследственных дефектах архитектуры говорил в 1977 г. Джон Бэкус?

Фоннеймановская модель вычислителя образуется тремя фундаментальными элементами: узлом обработки (в современных терминах - центральным процессором), узлом хранения (оперативной памятью) и соединяющим их каналом передачи информации. По сути, все современные вычислительные машины на аппаратном уровне очень близки к этой модели. Бэкус называл эту общность "машинами с операцией присваивания" и утверждал, что в ней изначально кроется несовершенство из-за разделения вычислений на математически чистую абстрактную часть (функции) и обязанную своим существованием реалиям аппаратных средств "приземленную" часть присваиваний. Иными словами, традиционная в математике запись

y = f(x)

в вычислительной технике содержит действительно традиционную математическую часть справа от операции присваивания ("="), и остальную, сугубо "компьютерную" часть (ведь математический символ равенства и операция присваивания - далеко не одно и то же). Бэкус обоснованно указывал и доказывал, что такое разделение кода является источником очень высокой сложности языков программирования, спецификации которых измеряются сотнями и даже тысячами страниц. В качестве альтернативы он предложил удивительный функциональный стиль программирования - вообще без переменных, т. е. без операций присваивания и без возможности присвоения данным имен. В модели Бэкуса все программирование строилось на основе множеств примитивных функций и исключительно гибких способов их комбинирования. Базовых примитивных функций для модели Бэкуса нужно совсем мало - "+", сложение двух чисел, и "-" - вычитание. Перечень операций комбинирования функций также невелик. Транспонирование списков - это образование списка из пар из двух списков, например, транспонирование списков a, b, c и d, f, e порождает список a,d, b,f, c,e. Комбинатор "α" применяет указанную функцию к каждому элементу списка, например, α+a,d, b,f, c,e приводит к формированию списка a+d, b+f, c+e. Бинарный комбинатор "°" определяет композицию функций, - например, операция f°g(x) эквивалентна f(g(x)). И, наконец, комбинатор "/" позволяет вставлять бинарную (оперирующую двумя операндами) функцию между элементами списка - /-a, b, c, d приводит к выполнению последовательности операций (a-(b-(c-d))).

Впоследствии из этих идей Джона Бэкуса было сформировано то, что в современном функциональном программировании принято называть монадами состояний (state monad), и на чем основываются подсистемы ввода/вывода практически всех языков функционального программирования.

Конечно, не стоит забывать, что в тьюринговской речи Бэкус говорил все-таки о сложности языков программирования. Если мы обратимся к истории создания FORTRAN авторства Бэкуса, то обнаружим в этом документе одно важное дополнение: "...на создание FORTRAN существенно повлияла экономика программирования в 1954 г.". Да, в те времена разработка сложного компилятора со сложного на уровне спецификаций языка была действительно задачей, требующей такой выдающейся личности, как Джон Бэкус.

Но время идет. Трансляторы с очень сложных нефункциональных языков существуют и работают, причем настолько неплохо, что именно с их помощью создан гибрид объектно-ориентированного и функционального языков OCAML (Objective CAML), на котором реализован симулятор оригинальной системы функционального программирования Джона Бэкуса.