Введение
ФОРТ – простой и естественный компьютерный язык. Он получил широкое распространение там, где необходима высокая эффективность. В 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 потоки выполнения, арифметику с фиксированной точкой
Такая система содержит от 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 года, когда был запушен «Спутник». Я был на втором курсе в МТИ и работал на полставки в САО (Смитсоновской астрофизической обсерватории, целых 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. Он стал моим введением в рекурсию и в чудесное разнообразие языков программирования. Will Baden отмечал, что LISP для лямбда-исчисления – то же самое, что и ФОРТ для постфиксной нотации Лукашевича [известной также как обратная польская запись – прим. перев.].
Также был актуален АПЛ, с его странным разбором справа налево. Хотя я восхищаюсь и подражаю его операторам, я не убежден, что они составляют оптимальный набор.
Среда программирования в пятидесятых была суровее, чем сегодня. Мой исходный код занимал 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, должен отображаться пробел, а CR включается с помощью OK. В 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. Считыватель и перфоратор были запасным вариантом вместо диска. Я снова портировал свой интерпретатор (обратно на ФОРТРАН) и добавил кросс-ассемблер для Burroughs B2250.
Система была офигенна. Она могла рисовать анимированные трехмерные изображения, когда 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 символа слова
* Код, который надо выполнить
* Аргументы
Поле кода было важным нововведением — как только слово было найдено, из накладных расходов интерпретатора оставался только один косвенный переход. О значении количества символом в отличительных словах я узнал от компиляторописателей из Стэнфорда.
Слово CODE создало важный класс слов. В поле его параметра содержатся машинные инструкции. Таким образом, теперь можно создать любое слово в пределах возможностей компьютера. Слово ";CODE" определяет код, который должен быть выполнен для нового класса слов, и вводит то, что ныне называется объектами.
Слово SMUDGE позволяло избежать рекурсии во время интерпретации определений. Из-за просмотра словаря в порядке от самых новых определений к самым старым, нежелательная рекурсия — обычное явление.
Наконец, появился стек возвратов. До этого определения не могли были вложенными, или должны были хранить адрес возврата в стеке данных. В целом это было время великих инноваций развитии пунктуации Форта.
Первую статья о ФОРТе (в виде внутреннего доклад Mohasco) мы с Джеффом написали в 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 и я заменили IBM 116 и IBM 316 на DEC PDP-11.
Такая замена стала возможной благодаря разработке косвенных потоков. Это было естественное развитие моей работы в Mohasco, хотя позже я узнал, что DEC использовал код с прямыми потоками в одном из своих компиляторов. Вместо того, чтобы каждый раз заново интерпретировать текст определения, адрес каждой словарной статьи компилировался. Такое улучшение эффективности для каждой ссылки требовало всего двух байт, а интерпретатор мог выполнять код чрезвычайно более быстро. На DEC PDP-11 этот интерпретатор по сути был макросом из двух слов:
: NEXT IP )+ W MOV W )+ ) JMP ;
Теперь ФОРТ был завершен. И я это знал. Я мог писать код быстрее, и он был более эффективным и надежным. Более того, он был переносимым. Я продолжил перепрограммировать IBM 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 год – прим. перев.].
Меня беспокоит, что те люди, кому следует, не ценят того, как ФОРТ воплощает их собственное описание идеального языка программирования.
Но я все еще занимаюсь исследованиями без лицензии. ФОРТ привел к архитектуре, которая обещает удивительное объединение аппаратного и программного обеспечения. А также и к еще одной новой среде программирования.
Автор: Dmitri Makarov