КДПВ взята отсюда
Введение
ФОРТ – простой и естественный компьютерный язык. Он получил заметное распространение там, где необходима высокая эффективность. В 60-х годах он прошел путь развития от университетов через бизнес к лабораториям. Это — история о том, как простой интерпретатор расширил свои возможности и смог стать полноценным языком программирования и операционной системой.
Эта работа была написана для конференции по истории языков программирования — HOPL II. В конечном итоге она была отклонена, вероятно, из-за стиля изложения.
ФОРТ распространился в шестидесятых годах в Америке — в университетах, бизнесе и науке, вместе с другими развитыми языками. В это время я был единственным программистом на нем, до самого конца этого периода он не имел названия. Все, что здесь описано — восстановлено по памяти, обрывочной документации и сохранившимся листингам программ.
ФОРТ в целом вряд ли оригинален, но он представляет собой уникальную комбинацию составляющих. Я благодарен тем людям и организациям, которые позволили мне разработать его – зачастую, сами того не зная. И я благодарен вам за интерес, заставляющий вас читать об этом.
ФОРТ – простой и естественный компьютерный язык. Сегодня [1991 год – прим. перев.] он считается языком программирования мирового уровня. То, что он достиг такого уровня без поддержки промышленности, университетов или правительства – следствие его эффективности, надежности и универсальности. Форт — язык, который выбирают, когда его эффективность важнее популярности других языков. Это частый случай в практических областях, таких как системы управления и связи.
Многие организации по ФОРТу и множество небольших компаний предлагают системы, приложения и документацию. В Северной Америке, Европе и Азии проводятся ежегодные конференции. Скоро будет представлен проект стандарта ANSI [ANS 1991].
Ни одна из книг о ФОРТе не описывает вполне его «вкус». Думаю, что наилучшая – все же первая из них – «Starting Forth» за авторством Leo Brodie [доступна, например, тут — https://www.forth.com/starting-forth/ — прим. перев.].
Классический ФОРТ, который мы обсуждаем, обеспечивает минимальную достаточную поддержку для того, чтобы программист разработал язык, наилучший для его приложения. Он предназначен для такого окружения, как рабочая станция, включающая клавиатуру, дисплей, компьютер и дисковод [в те времена накопители на дискетах часто были внешними, поэтому автор просто перечисляет компоненты минимальной компьютерной системы – прим. перев.].
ФОРТ по своей сути — контекстно-свободный текстовый язык. Он позволяет комбинировать «слова», разделенные пробелами, для конструирования новых «слов». Около 150 таких слов составляют систему, которая обеспечивает:
SAO 1958 Интерпретатор
SLAC 1961 Стек данных
RSI 1966 Ввод с клавиатуры, вывод на экран, редактор
Mohasco 1968 Компилятор, стек возвратов, словарь, виртуальную память,
мультипрограммирование
NRAO 1971 шитый код*, арифметику с фиксированной точкой
*Шитый код — способ компиляции программы, при котором она представляет собой массив вызовов подпрограмм, см. https://en.wikipedia.org/wiki/Threaded_code — прим. перев.
Такая система содержит от 3 до 8 килобайт программного кода, скомпилированного из 10-20 страниц исходного текста. Ее легко сможет разработать один программист даже на компьютере с ограниченными ресурсами.
Этот текст по необходимости описывает мою карьеру; но задумывался он как «биография» ФОРТа. Я буду обсуждать перечисленные выше возможности ФОРТа и названия «слов», связанных с ними. Значения многих «слов» очевидны. Некоторые – требуют описания, а некоторые — выходят за рамки этой работы.
Часть словаря языка ФОРТ, которая будет рассматриваться, перечислена ниже:
Интерпретатор
WORD NUMBER INTERPRET ABORT
HASH FIND ' FORGET
BASE OCTAL DECIMAL HEX
LOAD EXIT EXECUTE (
Терминал (работа с терминалом)
KEY EXPECT
EMIT CR SPACE SPACES DIGIT TYPE DUMP
Стек данных
DUP DROP SWAP OVER
+ - * / MOD NEGATE
ABS MAX MIN
AND OR XOR NOT
0< 0= =
@ ! +! C@ C!
SQRT SIN.COS ATAN EXP LOG
Стек подпрограмм
: ; PUSH POP I
Диск (работа с дисковыми накопителями)
BLOCK UPDATE FLUSH BUFFER PREV OLDEST
Компилятор
CREATE ALLOT , SMUDGE
VARIABLE CONSTANT
[ ] LITERAL ." COMPILE
BEGIN UNTIL AGAIN WHILE REPEAT
DO LOOP +LOOP IF ELSE THEN
МТИ, САО, 1958 год
Самым захватывающим временем был октябрь 1957 года, когда был запущен Спутник [ИСЗ «Спутник-1» — прим. перев.]. Я был на втором курсе в МТИ и работал на полставки в САО (Смитсоновской астрофизической обсерватории, целых 16 слогов, кошмар) в Гарварде. Обсерватория отвечала за оптическое сопровождение спутников – визуальные наблюдения с использованием Луны [имеется в виду Project Moonwatch — https://en.wikipedia.org/wiki/Operation_Moonwatch — прим. перев.] и камеры слежения за спутниками [Baker-Noon cameras — https://en.wikipedia.org/wiki/Schmidt_camera#Baker-Nunn — прим. перев.]. Застигнутые Спутником врасплох, они наняли студентов вычислять траектории на настольных калькуляторах Friden. John Gaustad рассказал мне о стоявшем в МТИ IBM EDPM 704, и одолжил мне свое руководство по FORTRAN II. В итоге моя первая программа, Ephemeris 4, оставила меня без работы.
Теперь, уже в роли программиста, я работал с George Veis над применением его метода наименьших квадратов к определению параметров орбит, стационарных позиций, и в итоге – к определению формы Земли. Конечно же, эта «работа на полставки» занимала по крайней мере 40 часов, и таки да, мой диплом накрылся.
John McCarthy читал В МТИ великолепный курс по языку LISP. Этот курс стал моим введением в рекурсию и в чудесное разнообразие языков программирования. Wil Baden отмечал, что LISP для лямбда-исчисления – то же самое, что и ФОРТ для постфиксной нотации Lukasewcleicz[нотация Лукашевича, известна также как обратная польская запись – прим. перев.].
Также был актуален АПЛ, с его странным разбором справа налево. Хотя я восхищаюсь им и подражаю его операторам, я не убежден, что они составляют оптимальный набор.
Программирование в пятидесятых была суровее, чем сегодня. Мой исходный код занимал 2 лотка с перфокартами. Чтобы пропустить их через машину, надо было повозиться, и в основном это делал я сам. Сборка занимала полчаса (прямо как на Си), но ограниченное компьютерное время означало лишь один запуск в день, кроме, может быть, третьей смены.
И вот я написал простой интерпретатор, читающий карты с входными данными и управляющий программой. Он также управлял вычислениями. Для каждого из пяти параметров орбиты были эмпирические уравнения для учета атмосферного сноса и отклонения формы Земли от сферы. Таким способом я мог составлять различные уравнения для нескольких спутников, не перекомпилируя программу.
В этих уравнениях участвовали множители, такие как P2 (полином второй степени) и S (синус). Большую часть времени занимали 36-битные вычисления с плавающей точкой, так что накладные расходы были невелики. Стек данных был не нужен, да я, вероятно, о нем и не знал.
Вот так и началась история интерпретатора ФОРТа – со слов
WORD NUMBER INTERPRET ABORT
Они еще не записывались словами, потому что были номерами операторов.
INTERPRET использует WORD для чтения слов, разделенных пробелами, а NUMBER – для преобразования слова [числа в текстовой записи – прим. перев.] в двоичную форму (в данном случае, с фиксированной точкой). Такой ввод в свободном формате был необычен, но более эффективен (меньше и быстрее), и более надежен. Ввод в стиле ФОРТРАНа форматировался в определенные колонки, и опечатки вызывали многочисленные задержки.
Этот интерпретатор использовал конструкцию IF… ELSE IF, закодированную на ФОРТРАНе, для поиска совпадений каждого символа. Вся обработка ошибок состояла просто в прерывании выполнения программы. Тогда, как и сейчас, слово ABORT спрашивало пользователя, что нужно делать. Поскольку входные карты нумеровались в порядке чтения, вы могли узнать, где была ошибка.
Стэнфорд, SLAC, 1961 год
В 1961 году я приехал в Стэнфорд, чтобы изучать математику. Хотя Стэнфорд и создавал свою кафедру информатики, я больше интересовался вычислениями. Меня впечатлило, что они смогли (осмелились?) написать свой собственный компилятор АЛГОЛа. И еще — судьба свела меня с компьютером Burroughs B5500. Я опять нанялся на работу на полставки на SLAC (Стэнфордский линейный ускоритель, 10 слогов), писать код для оптимизации удержания луча в будущем трехкилометровом ускорителе электронов. Это было естественное применение метода наименьших квадратов (в котором у меня имелся опыт) к фазовому пространству. Ответственным за нашу группу был Hal Butler, и наша программа TRANSPORT достигла успеха.
Другим применением метода наименьших квадратов была программа CURVE, написанная в 1964 году на АЛГОЛе. Это была универсальная программа нелинейного подбора данных с дифференциальной коррекцией. Ее статистическая строгость обеспечивала подробный анализ согласованности модели и экспериментальных данных.
Формат данных и уравнения модели интерпретировались, и для облегчения вычислений использовался стек. CURVE была впечатляющим предшественником ФОРТа. Чтобы обеспечить возможность работать не с простыми уравнениями, а с намного детальнее проработанными моделями, она вводила следующие слова:
+ - * NEGATE
IF ELSE THEN <
DUP DROP SWAP
: ; VARIABLE ! (
SIN ATAN EXP LOG
Написание было несколько другим:
NEGATE - MINUS
DROP - ;
SWAP - .
! - <
VARIABLE - DECLARE
; - END
( ...) - COMMENT ...;
Чтобы определить шестисимвольное входное слово (которое называлось ATOM по аналогии с LISP), интерпретатор использовал IF… ELSE IF. DUP, DROP и SWAP были машинными инструкциями; меня удивило то, что они писались по-другому. Слово «:» (двоеточие) было взято из формата меток в АЛГОЛе, и было «перевернуто» для разбора слева направо (чтобы не допустить обнаружение интерпретатором неопределенных слов):
ALGOL - LABEL:
CURVE - : LABEL
Фактически, двоеточие отмечало позицию во входной строке, которую надлежало интерпретировать позже. Интерпретация останавливалась словом «;» (точка с запятой). Одна из версий двоеточия называлась DEFINE.
Оператор записи «!» (восклицательный знак) появился в связи с VARIABLE; но чтение «@» было автоматическим. Обратите внимание – код стал достаточно сложным для того, чтобы требовать комментариев. Когда-то подпавшее под критику постфиксное условие начиналось отсюда:
ALGOL - IF expression THEN true ELSE false
CURVE - stack IF true ELSE false THEN
Если на вершине стека было ненулевое значение, это воспринималось, как булево истинное значение (true). THEN обеспечивал уникальное окончание, отсутствие которого меня всегда путало в АЛГОЛе. Подобные выражения интерпретировались так: IF сканировал ввод в поисках ELSE или THEN. Слово < вводило соглашение, что отношение оставляет на стеке булево значение – 1, если true, и 0, если false. Трансцендентные функции – это, конечно, вызовы библиотечных подпрограмм.
На вольных хлебах
Я ушел из Стэнфорда в 1965 году, чтобы стать вольнонаемным программистом в Нью-Йорке. Это не было чем-то необычным, и я находил работу, программируя на FORTRAN, ALGOL, Jovial, PL/I и различных ассемблерах. Я в буквальном смысле таскался с моей пачкой перфокарт и перепрограммировал ее по необходимости. Появлялись мини-компьютеры, а с ними – и терминалы. Интерпретатор прекрасно подходил для ввода через телетайп, и вскоре обзавелся кодом для работы с выводом. Так мы обрели слова:
KEY EXPECT
EMIT CR SPACE SPACES DIGIT TYPE
EXPECT – это цикл, вызывающий KEY для чтения нажатий клавиш. TYPE – это цикл, вызывающий EMIT для отображения символа.
С приходом телетайпа настало время перфоленты и самых неудобных, какие только можно вообразить, программ – требующих многих часов редактирования, пробивки, загрузки, сборки, печати, загрузки, тестирования, и потом – по новой. Помню ужасное воскресенье в небоскребе на Манхэттене, когда я не мог найти клейкую ленту (ничто другое не помогало), и ругался, что «должен быть лучший способ».
Я проделал приличную работу для Bob Davis в Realtime Systems, Inc (RSI). Я досконально изучил 5500 MCP — в достаточной мере, чтобы поддерживать его службу разделения времени (работу с удаленными терминалами), а также написал транслятор с FORTRAN на ALGOL и утилиты для редактирования файлов. Транслятор показал мне ценность пробелов между словами, которых не требует ФОРТРАН.
Интерпретатор все еще различал слова только по первым 6 символам (так как слово данных в Burroughs B5500 было 48-битным). Появились слова LIST EDIT BEGIN AGAIN EXIT.
Слова BEGIN… AGAIN писались как START… REPEAT и служили «скобками» для команд редактирования T TYPE I INSERT D DELETE F FIND, позже использованных в редакторе NRAO.
Слово FIELD использовалось в стиле СУБД “Forth” компании Mohasco. Отсюда одна из отличительных черт ФОРТа. Правило состоит в том, что ФОРТ подтверждает каждую строку ввода, добавляя OK, когда интерпретация завершена. Это может вызывать затруднения, поскольку, когда ввод завершается символом CR, должен отображаться пробел, потом OK, а CR в последнюю очередь. В RSI OK оказывался на следующей строке, но тем не менее передавал дружественное подтверждение по устрашающей линии связи [авторская шутка, основанная на том, что в те годы работа компьютеров с линиями связи была делом непривычным; для современного читателя шутка уже утратила актуальность и звучит, как минимум, странно — прим. перев.]:
56 INSERT ALGOL IS VERY ADAPTABLE
OK
Эта постфиксная нотация наводит на мысли об использовании стека данных, но его достаточная глубина равна всего лишь единице.
Mohasco, 1968
В 1968 году я пришел работать программистом в коммерческую компанию Mohasco Industries, Inc в Амстердаме, штат Нью-Йорк. Это была крупная компания по производству товаров для дома — ковров и мебели. Я работал с Geoff Leach в RSI, и он убедил меня переехать за ним в северную часть штата. Я только что женился, а в Амстердаме была прекрасная атмосфера маленького города, контрастирующая с Нью-Йорком.
Я переписал свой код на КОБОЛе и узнал, что такое на самом деле программное обеспечение для бизнеса. Боб Райко отвечал за обработку корпоративных данных и дал мне два связанных с этим проекта.
Он арендовал мини-компьютер IBM 1130 с графическим дисплеем 2250. Цель состояла в том, чтобы увидеть, может ли компьютерная графика помочь создавать узорчатые ковры. Ответ был «без поддержки цвета помочь не может», и вариант с 1130 отпал.
В это время у меня был новейший миникомпьютер: 16-битный процессор, 8K RAM, дисковый накопитель (первый в моей жизни), клавиатура, принтер, считыватель перфокарт и перфоратор, компилятор FORTRAN. Считыватель и перфоратор были запасным вариантом на случай сбоя диска. Я снова портировал свой интерпретатор (обратно на ФОРТРАН) и добавил кросс-ассемблер для работы с 2250.
Система была офигенна. Она могла рисовать анимированные трехмерные изображения, когда IBM едва могла рисовать статичные плоские картинки. Поскольку это была моя первая графика в реальном времени, я написал код Spacewar, той самой первой видеоигры. Я также переписал на ФОРТе свою шахматную программу, изначально написанную на АЛГОЛе, и очень впечатлился тем, насколько она стала проще.
Файл, содержащий интерпретатор, назывался FORTH, что означало программное обеспечение четвертого (следующего) поколения – FOURTH. Но название пришлось сократить, так как операционная система ограничивала имена файлов до 5 символов.
Эта среда программирования для 2250 намного превосходила FORTRAN, поэтому я расширил кросс-ассемблер 2250 до компилятора 1130. При этом появилось множество новых слов:
DO LOOP UNTIL
BLOCK LOAD UPDATE FLUSH
BASE CONTEXT STATE INTERPRET DUMP
CREATE CODE ;CODE CONSTANT SMUDGE
@ OVER AND OR NOT 0= 0<
Их написание все еще отличалось [от стандартного для ФОРТа – прим. перев.]:
LOOP был CONTINUE
UNTIL - END
BLOCK - GET
LOAD - READ
TYPE - SEND
INTERPRET - QUERY
CREATE - ENTER
CODE - символ цента
Это было единственное применение, которое я когда-либо находил для символа цента.
Счетчик и предел цикла хранились в стеке данных. DO и CONTINUE появились благодаря ФОРТРАНу.
BLOCK управлял количеством буферов, чтобы свести к минимуму обращения к диску. LOAD считывал исходный код из блока размером в 1024 байта. Размер в 1024 байта был выбран исходя из размера блока на диске, и оказался удачным. Слово UPDATE позволяло пометить блок в памяти и позже сбросить его на диск, когда понадобится освободить буфер (или по слову FLUSH). Оно реализовывало своего рода виртуальную память и неявно вызывалось при операциях записи.
Слово BASE позволяло работать с восьмеричными, шестнадцатеричными и десятичными числами. Слово CONTEXT было первым намеком на словари и служило для отделения слов редактора. Слово STATE устанавливало режимы компиляции и интерпретации. Во время компиляции количество символов и первые 3 символа слова компилировались [составлялись в идентификатор — прим. перев.] для последующей интерпретации. Как ни странно, слова могли прерываться спецсимволами – но от этого скоро отказались. Оператор чтения (@) имел много вариантов, поскольку чтение из переменных, массивов и диска нужно было различать. DUMP позволял копаться в памяти для отладки.
Но самое главное, теперь был словарь. Код интерпретатора теперь брал имя и искал его в связном списке. Слово CREATE создавало классическую словарную запись:
* Ссылка на предыдущее слово в словаре
* Количество и первые 3 символа слова*
* Код, который надо выполнить
* Аргументы
* Идентификаторы в ФОРТе упаковываются в 32 бита в виде: 1 байт — количество символов в слове, остальные 3 байта — первые 3 символа слова (гусары, молчать!) — прим. перев.
Поле кода было важным нововведением — как только слово было найдено, из накладных расходов интерпретатора оставался только один косвенный переход. О значении количества символов в отличительных словах я узнал от разработчиков компиляторов в Стэнфорде.
Слово CODE создало важный класс слов. В поле его параметра содержались машинные инструкции. Таким образом, теперь можно было создать любое слово в пределах возможностей компьютера. Слово ";CODE" определяло код, который должен был быть выполнен для нового класса слов, и вводило то, что ныне называется объектами.
Слово SMUDGE позволяло избежать рекурсии во время интерпретации определений. Из-за просмотра словаря в порядке от самых новых определений к самым старым, нежелательная рекурсия была обычным явлением.
Наконец, появился стек возвратов. До этого определения не могли были вложенными, или должны были хранить адрес возврата в стеке данных. В целом это было время великих инноваций в (прерывистом) развитии Форта.
Первую статью о ФОРТе (в виде внутреннего доклад Mohasco) мы с Geoff Leach написали в 1970 году. Она не потеряла актуальности и сегодня.
В 1970 году Bob заказал Univac 1108. Это был амбициозный проект по поддержке сети выделенных линий для системы ввода заказов. Я писал генератор отчетов на ФОРТе но был уверен, что смогу написать код и для ввода заказов. Чтобы повысить доверие к ФОРТу, я портировал его на 5500 (в виде отдельной программы!). Но корпоративным программным обеспечением был COBOL. Удивительно, что удалось достичь компромисса в виде установки системы ФОРТ на 1108 так, чтобы она взаимодействовала с модулями COBOL для обработки транзакций.
Я очень хорошо помню поездку в Скенектади той зимой, чтобы занять время в третью смену на 1107. В моей комнате отсутствовали пол и окно, и это было еженощным упражнением в выживании. Но система получилась невероятно успешной, и произвела впечатление даже на Univac (Les Sharp занимался интеграцией с проектом). Решающим критерием было время отклика, но я был также полон решимости поддерживать проект в пригодном для сопровождения виде (то есть сохранять его маленьким и простым). Увы, экономический спад заставил руководство отменить 1108. Я все еще думаю, что это было хреновое решение. Я первым подал в отставку.
Форт для 1108 надо было бы написать на ассемблере. Он буферизировал входные и выходные сообщения и распределял процессор между задачами, обрабатывающими каждую строку. Вот вам уже и классическая операционная система. Но он также мог парсить входные строки и выполнять (словом PERFORM) соответствующие модули КОБОЛа. Он следил за буферами барабана памяти и занимался упаковкой и распаковкой записей. Слова
BUFFER PREV OLDEST
TASK ACTIVATE GET RELEASE
появились как раз тогда.
BUFFER не читал диск, если было известно, что требуемый блок пуст. PREV и OLDEST — системные переменные, позволившие реализовать управление буферами по принципу “реже всего используемых”. TASK определял задачу во время загрузки, и ACTIVATE запускал ее, когда нужно. GET и RELEASE управляли разделяемыми ресурсами (барабан памяти, принтер). PAUSE — это слово, которым задача освобождала процессор. Оно включалось во все операции ввода-вывода и было невидимо для кода транзакции. Оно делало возможным простой алгоритм циклического планирования, который позволял избежать блокировки.
После заявления [вероятно, об увольнении — прим. перев.] я написал гневное стихотворение и книгу, которая никогда не была опубликована. В ней рассказывалось, как программировать на ФОРТе, и поощрялись простота и инновации. В ней также описана техника косвенного шитого кода, но впервые она была реализована в NRAO.
Я трудился над понятием метаязыка — языка, который говорит о языке. Теперь Форт мог интерпретировать ассемблер, который собирал компилятор, который компилировал интерпретатор. В конце концов я решил, что терминология не работает, но термин “метакомпиляция” для перекомпиляции самого ФОРТа все еще в ходу.
NRAO, 1971
George Conant предложил мне должность в НРАО (Национальная радиоастрономическая обсерватория, 22 слога). Я знал его в САО, и ему понравились Ephemeris 4. Мы переехали в Шарлоттсвилль, штат Вирджиния, и провели лето в Тусоне, штат Аризона, когда радиотелескоп на Китт-Пик был доступен для обслуживания.
Проект состоял в программировании миникомпьютера Honeywell 316 для управления новым банком фильтров для 36-дюймового радиотелескопа на миллиметровых волнах. У него была девятидорожечная магнитная лента и терминал на трубках Tektronix с «памятью» [вероятно, имеются в виду трубки с послесвечением или потенциалоскопы — прим. перев.]. George предоставил мне полную свободу в разработке системы, однако он не был доволен результатом. В НРАО все использовали ФОРТРАН, а теперь появился я со своим ФОРТом. Он был прав в том, что стандарты организации должны предусматривать один общий язык программирования. Другие программисты теперь тоже захотели свои собственные языки.
Как бы там ни было, я написал код ФОРТа на ассемблере на мэйнфрейме IBM 360/50. Затем я перекомпилировал его под 316. Затем я уже нативно скомпилировал его на 316 (хотя у меня и был терминал на 360, время отклика было ужасным). Как только система стала доступна, дальше было просто. Было два режима наблюдения: всечастотный и по спектральным линиям. Спектральные линии были интереснее всего, потому что я мог отображать спектры по мере сбора данных, и сглаживать формы линий по методу наименьших квадратов.
В Тусоне, где руководил Ned Conklin, систему приняли хорошо. Это был очередной шаг в сокращении количества данных сразу по мере их сбора. Астрономы стали использовать ее для обнаружения и картографирования межзвездных молекул, как только это стало модным направлением исследований.
Для поддержки в обсерватории наняли Bess Rather. Сначала ей пришлось изучить систему ФОРТ, а затем объяснить и задокументировать ее с минимальной помощью с моей стороны. В следующем году я перепрограммировал DDP-116 для оптимизации наведения телескопа. Потом Bess и я заменили DDP-116 и Honeywell 316 на DEC PDP-11.
Такая замена стала возможной благодаря разработке косвенного шитого кода. Это было естественное развитие моей работы в Mohasco, хотя позже я узнал, что DEC использовал прямой шитый код в одном из своих компиляторов. Вместо того, чтобы каждый раз компилировать все определение, компилятор просто брал из словаря адрес каждого использованного слова. Такое улучшение эффективности для каждой ссылки требовало всего двух байт, а интерпретатор мог выполнять код гораздо быстрее. На DEC PDP-11 этот интерпретатор по сути был макросом из двух слов:
: NEXT IP )+ W MOV W )+ ) JMP ;
Теперь ФОРТ был завершен. И я это знал. Я мог писать код быстрее, и он был более эффективным и надежным. Более того, он был переносимым. Я продолжил перепрограммировать DDP-116, занимающийся наведением 300-дюймового телескопа Green Bank, и HP mini, с которого начиналась радиоастрономия с очень длинной базой (VLBI). George дал мне ModComp, и я запрограммировал преобразование Фурье для интерферометрии и поиска пульсаров (на наборах данных длиной в 64K). Я даже продемонстрировал, что комплексное умножение на IBM 360 в ФОРТе было на 20% быстрее, чем на ассемблере.
В НРАО ценили то, что я написал. У них была договоренность с консалтинговой фирмой, чтобы определить побочные технологии. Вопрос патентования ФОРТа обсуждался довольно долго. Но поскольку патенты на программное обеспечение были противоречивы и могли решаться с привлечением Верховного суда, НРАО отказалась заниматься этим вопросом. Вследствие этого авторские права вернулись ко мне. Я не думаю, что идеи следует патентовать. Оглядываясь назад, следует согласиться, что единственный шанс ФОРТа — это оставаться в общественном достоянии. И там он процветал.
Шитый код изменил структурные слова (таких как DO LOOP IF THEN). Они получили элегантную реализацию с адресами в стеке данных во время компиляции.
Теперь у каждой реализации форта был ассемблер под архитектуру своего компьютера. Он использовал коды операций в постфиксной нотации, и формировал адреса в стеке данных, с ФОРТ-подобными структурными словами для ветвления. Мнемоники ассемблера определялись как классы слов с помощью ;CODE. Можно было закодировать вот это всё за один день.
Необычные арифметические операторы также доказали свою ценность.
M* */ /MOD SQRT SIN.COS ATAN EXP LOG
M* — это обычное аппаратное умножение двух 16-разрядных чисел в 32-разрядное произведение (аргументы, конечно же, в стеке данных). За ним идет */ с делением, чтобы реализовать дробную арифметику. /MOD возвращает как частное, так и остаток и идеально подходит для поиска записей в файле. SQRT выдает 16-битный результат из 32-битного аргумента. SIN.COS возвращает сразу и синус и косинус, что полезно для векторной и комплексной арифметики (БПФ). ATAN – обратная операция, и не имеет неоднозначностей по квадрантам. EXP и LOG вычисляются по основанию 2.
В этих функциях использовалась арифметика с фиксированной точкой — 14 или 30 бит справа от двоичной точки для тригонометрии, 10 для логарифмов. Это стало отличительной чертой ФОРТа, поскольку такая арифметика проще, быстрее и точнее, чем с плавающей точкой. Но при необходимости можно легко реализовать аппаратное и программное обеспечение и с плавающей точкой.
Аплодирую неоценимой работе Харта, составившего таблицы приближений функций с различной точностью. Они освободили прикладных программистов от ограничений существующих библиотек.
Появилось слово DOES> (писалось как ;:). Оно определяло класс слов (наподобие ;CODE), устанавливая, что определение должно интерпретироваться при ссылке на слово. Его было трудно реализовать, но оно оказалось особенно полезно для определения кодов операций.
Тем не менее, мне не удалось убедить Шарлоттсвилль, что ФОРТ им подходит. Мне не разрешили программировать VLA. В любой группе программистов 25% любят Форт и 25% ненавидят его. Споры бывают жесткими, а компромисс достигается редко. В итоге первые 25% объединили свои силы и создали Forth, Inc. Но это уже другая история.
Мораль
У истории ФОРТа есть некая мораль: настойчивый молодой программист борется против безразличия, чтобы открыть Истину и спасти своих страдающих товарищей. Становится лучше: посмотрите, как Forth, Inc идет ноздря в ноздрю с IBM во французской банковской системе.
Я знаю, что ФОРТ – и поныне лучший язык программирования. Я доволен его успехом, особенно в ультраконсервативной области искусственного интеллекта [напоминаю, 1991 год – прим. перев.].
Меня беспокоит, что те люди, кому следует, не ценят того, как ФОРТ воплощает их собственное описание идеального языка программирования.
Но я все еще занимаюсь исследованиями без лицензии. ФОРТ привел к архитектуре, которая обещает удивительное объединение аппаратного и программного обеспечения. А также и к еще одной новой среде программирования.