Фокал

Материал из свободной русской энциклопедии «Традиция»
Перейти к: навигация, поиск
FOCAL
Парадигма:
императивный
Тип исполнения:
интерпретатор
Типизация:
один тип — вещественный
Дата появления:
1959





Диалекты:
FOCAL-69 ("классический"), FOCAL 1971, FOCAL 11, FOCAL-81
Реализации:
музейный FOCAL-81 для POSIX-систем


FOCAL (аббр. FOrmula CALculator) — универсальныйинтерпретируемый язык программирования высокого уровня, ориентированный на решение вычислительных задач в режиме диалога с пользователем. (Для сравнения FORTRANFOrmula TRANslator.)

Происхождение[править]

Фокал, так же как Фортран или Бейсик - язык первого поколения: типы данных - только встроенные (один единственный - вещественные числа); для управления порядком действий используются только метки и переходы к ним (условный, безусловный, к подпрограмме); из структур данных - только массив. И оператор цикла для его обхода. Время появления таких языков: с середины пятидесятых годов прошлого века до середины шестидесятых, когда начали распространяться идеи структурного программирования. Фокал разработан как дополнение к Фортрану - для более оперативного решения относительно простых задач вычислительного характера в режиме непосредственного диалога пользователя с машиной посредством подключенного к ней телетайпа. Т.е. он был призван играть роль "программируемого калькулятора", которых тогда, разумеется, еще не было. Язык имеет предельно простой синтаксис, крайне лаконичен, легко реализуется, нетребователен к ресурсам целевой машины. Последние два обстоятельства послужили причиной переноса его в конце шестидесятых годов на появившиеся тогда мини-ЭВМ (в частности на 12-и разрядную PDP-8 с ОЗУ 4К слов, автор Ричард Мерилл) что ошибочно считается датой появления языка. На мини-ЭВМ, как правило не имевших внешних запоминающих устройств, интерпретатор Фокала сам обеспечивал всё необходимое программное окружение и не нуждался в операционной системе. (Впрочем, так же как и реализованные для них версии Бейсика.)

В нашей стране Фокал эксплуатировался на аналоге PDP-8 — мини-ЭВМ Электроника-100 и аналогах PDP-11 от супермини-ЭВМ Э-79 до настольного компьютера ДВК-1/2/3 и бытового БК-0010. В последнем интерпретатор Фокала был зашит в ПЗУ (в поздних моделях БК — доступнен на картридже). Были также доступны расширения Фокала для этих машин, написанные различными энтузиастами. Расширения содержали разнообразные дополнительные команды и функции для работы с графикой, звуком, запуска двоичных программ, обработки строк и пр.

Существенно расширенная версия Фокал использовалась в качестве включающего языка в ДИАСП — Диалоговой Системе Проектирования — специализированной САПР, предназначенной для целей микроэлектроники.

В 1990-е годы энтузиастами была предпринята попытка переноса Фокала на IBM PC (Turbo Focal), но она не вышла из стадии бета-версии, которая распространялась по каналам BBS.

Сравнительное описание[править]

Фокал просто обречен на сравнение с Бейсиком — эти два языка похожи очень во многом: имеют сходное строение и синтаксис; эксплуатировались на одних и тех же машинах; использовались для решения одного и того-же круга задач; имели примерно одинаковые возможности и сходные ограничения… Но Фокал это подручный инструмент для специалистов, а Бейсик — средство для обучения начинающих. Фокал ориентирован на экономию ресурсов - как машины так и пользователя, а Бейсик — на интуитивную понятность с опорой на «естественный» язык. Фокал может быть реализован только чистой интерпретацией, а Бейсик (в исходном виде — упрощенное подмножество Фортрана) изначально был ориентирован на компиляцию. Причем с перфокарт, о чем говорят сохранившиеся и в диалоговых версиях перфокарточные рудименты — операторы DATA и READ.

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

С началом «бума персональных ЭВМ» круг людей, обученных по-бейсиковски резко расширился. По их настоятельным требованиям в их любимый (а часто и единственный) язык были включены разнообразные средства и концепции, позаимствованные из других языков. (В том числе плохо совместимые как с исходной концепцией языка, так и между собою.) Начиная с концепции типов данных и средств работы со строками. А рыхлая структура языка позволила это сделать. В результате чего из маленького и простого, хотя и несколько аляповатого языка, Бейсик превратился в громоздкого труднообозримого монстра, но живёт и здравствует и по сей день. Фокал напротив активно сопротивлялся бездумному включению в него средств, не соответствующих духу и структуре языка. Но в результате перестал удовлетворять современным требованиям; постепенно выпал из сферы общественного внимания и в настоящий момент поддерживается исключительно энтузиастами. В частности, попытка сделать турбо-версию Фокала оказалась неудачной не по техническим, а чисто по идеологическим причинам: интегрированная турбо-среда не делала и без того предельно диалоговый язык более удобным, а напротив вызывала когнитивный диссонанс с простым и строгим дизайном языка. Это выглядело примерно так же, как если-бы к слесарной ножовке по металлу приделать рукоятку, обитую пурпурным бархатом и украшенную висюльками ювелирной работы.


Грамматика Фокала и Бейсика аналогичны.

В исходном виде оба языка строчно-ориентированные. То есть диалог с оператором (или ввод программы) производится построчно. Если в начале строки присутствует номер — строка помещается в память, если нет — выполняется сразу. Сохраненные в памяти строки упорядочиваются по номерам и составляют собственно программу. Обслуживание программы (запуск её на выполнение, сохранение на машинном носителе или загрузка с него, а так же удаление или распечатка на терминале) в Фокале производится операторами самого языка, а не внешними по отношению к языку средствами, как в Бейсике (командами операционной системы - в пакетных версиях; специальными командами, действующими только в "нулевой" строке - в диалоговых версиях; через систему меню или с помощью "горячих клавишей" в турбо-версиях). Поэтому в частности любая (полноценная) реализация Фокала (начиная с самых ранних) позволяет писать самоподгружающиеся (а при наличии файловой системы и самомодифицирующиеся) программы, а для Бейсика подобное, как правило, исключено.

Номера строк как в Фокале, так и в Бейсике играют так же роль меток для операторов передачи управления. Но в Бейсике номер строки - целое число, в результате чего программа имеет вид безструктурного массива строк; а в Фокале это вещественное число. В результате чего программа получается структурированной - распадается на группы строк, каждая из которых - "естественная подпрограмма". (Целая часть - номер группы, дробная - номер конкретной строки в ней.) Поэтому с одной стороны синтаксис работающих со строками операторов (и обслуживающих программу Write, Modify, Erase и операторов передачи управления Go, Do, If) получается предельно простым: дробное число в них указывает конкретную строку, целое - целую группу, а вся программа, как правило, указывается ключевым словом Ales (что значит "всё"). А с другой - "сам бог велел" использовать группу (а так же отдельную строку, тоже являющуюся "естественной подпрограммой") для размещения подпрограммы, выполняющей одно законченное сложное действие.

Три структурные единицы программного текста (вся программа, группа строк, отдельная строка) при передаче им управления как подпрограмме (оператором DO или функцией FSUbr - см. далее) возвращают управление по достижении их конца автоматически. Т.е. даже в том случае, если там нету оператора возврата Ret. Это свойство используется, в том числе, при отладке программ: не требуется какой-то специальный отладчик с точками останова, пошаговым режимом, средствами слежения за значениями переменных и т.п. - вполне достаточно штатных средств. Достаточно вызывать строчки по одной (в т.ч. с использованием трассировки) и смотреть, что они делают.

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

В обоих языках программная строка состоит из «операторов», каждый из которых выполняет одно законченное элементарное действие. Оператор обязательно начинается с ключевого слова, и может содержать что-то ещё. В Фокале, в отличии от Бейсика, все ключевые слова подобраны на разные буквы алфавита и могут сокращаться до одной буквы (остальные всё равно игнорируются).

Основные операторы Фокала[править]

оператор описание аналог в Бейсике
Comment комментарий (текст следом за командой игнорируется) REM
Set присваивание значения переменной (или элементу массива) LET
eXecute выполнить — вычисление выражения без присваивания результата
Ask ввод INPUT
Type вывод PRINT
Oper переключение ввода/вывода между внешними устройствами
Go безусловный переход GOTO RUN (команда)
If условный переход IF … ELSE
Do переход к подпрограмме GOSUB RUN (команда)
Ret возврат из подпрограммы RETURN
For цикл FOR … NEXT
Quit останов программы или выход из интерпретатора STOP соответствует частично
Write вывод или сохранение программы LIST SAVE(команды)
Erase удаление строк программы DELETE (команда)

В программной строке может быть как один так и несколько операторов — столько, сколько поместится. Но в Бейсике помещается максимум два-три оператора, а в Фокале — пять-десять. В частности за счет того, что в фокаловских операторах нет лишних «шумовых» слов, предназначенных сделать их похожими на фразы «естественного» языка. В Фокале операторы разделяются символом ;, а в Бейсике - чем попало: в некоторых версиях символом :, а в некоторых \ (символ ; был задействован в операторе PRINT обозначать переход на следующую строку и разделять операторы оказалось нечем).

Выражения как в Фокале так и в Бейсике строятся из числовых констант, переменных, обращений к функциям, знаков операций и скобок, изменяющих естественный порядок их выполнения. Операций в Фокале ровно пять: + - * / ^ - сложение, вычитание, умножение, деление и возведение в степень. В Бейсике изначально было то-же самое, разве что возведение в степень обозначалось **, но в поздних версиях была введена концепция типов данных и количество операций резко возросло.

Имена переменных в Фокале, как и во всех языках, состоят из букв и цифр и начинаются обязательно с буквы. (Впрочем буквой в Фокале считается всё, что не цифра и не разделитель.) Переменная заводится "в явочном порядке" - в момент первого присваивания ей чего-либо - и существует до тех пор, пока все переменные разом не будут уничтожены с помощью оператора Erase. Наряду с переменными можно также использовать одно- и двухмерные массивы. Их элементы заводятся так же, как и простые переменные в момент первого присваивания (т.к. на самом деле это "переменные с индексами"). Это неэффективно, зато удобно. К тому же, сам собою отпадает вопрос о границах массива. (Для сравнения - в Бейсике массив должен быть предварительно объявлен оператором DIM; нумерация его элементов - с единицы, а не с нуля - уступка "обывательскому" сознанию.) Но в качестве побочного эффекта имеет место возможность обращаться к одной и той же переменной с разным количеством индексов, к тому же зависящая от реализации. Впрочем как правило гарантируется, что Х(0,0), Х(0) и Х - это одна и та же переменная.

Функции в Фокале только встроенные - возможности вводить новые функции с произвольными именами нет. Точнее говоря, нет возможности присваивать произвольные имена подпрограммам. Вызвать подпрограмму не как процедуру (оператором Do) а как функцию - из середины выражения - с передачей параметра (только одного) и возвратом результата - с помощью спецфункции FSBr. (В Бейсике изначально было то же самое. Разве что, такая подпрограмма объявлялась заранее и могла быть только одна.)

Имена всех встроенных функций, так же как и ключевые слова, распознаются по первым уникальным буквам. Но во-первых в отличие от ключевых слов, специально подобранных на разные буквы алфавита - по нескольким; а во-вторых все они (для упрощения распознавания) обязательно начинаются на букву F. А вот переменные на эту букву заводить нельзя, увы.

Набор встроенных функций как правило включает:

FSIn FCOS FTAn - тригонометричесские
FASin FACos FATan - обратные тригонометричесские
FSQrt FExp FLOg - корень, Е в степени Х, логарифм
FRnd - генератор случайных чисел
FABs FItr FMOd FSGn - модуль, целая и дробная часть числа, знак
FSBr - вызов подпрограммы как функции
FX - обращение к внешним устройствам
FCHr FCLk - посимвольный ввод/вывод, таймер

А так же другие функции - исходя из возможностей аппаратуры и фантазии разработчиков. Например:

FTMp - дата/время
FMAx FMIn - минимум и максимум
FBip FK FM - управление звуком, курсором, мышью
FT FL - рисование точки, линии...

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

Поэтому же в Фокале нету операций сравнения. В условном операторе значение выражения сравнивается с нулём, и чтобы сравнить два числа, приходиться вычитать одно из другого, что не очень удобно и ненаглядно. Но, во-первых, подавляющее большинство кодировок не предоставляет возможности обозначить все такие операции одним символом, как требуют принципы языка; а во-вторых, пришлось бы, либо ограничить применение этих операций только условным оператором (как в Бейсике), либо они тянут за собой логический тип данных и операции с ним. И это при том, что вещественное число само по себе - логическое значение трёхзначной (с нейтральным элементом, который можно и не использовать) или вообще нечеткой логики. В качестве инверсии можно использовать смену знака, а в роли операций И и ИЛИ - функции FMAx и FMIn.

Примеры программ[править]

Стандартный пример Hello World

C Программа выводит на экран тестовую строку
1.1 T "Hello World !" !;Q

В операторах ввода/вывода Ask и Type допускаются текстовые константы - текст, заключенный в кавычки любого типа. А так же восклицательный знак, обозначающий переход на следующую строку. Они выводятся в качестве приглашения к вводу или пояснений к выводимым числам.


Решение квадратного уравнения вида \(ax^2 + bx + c = 0\).

 1.1 T " Решаем квадратное уравнение вида: A*X^2 + B*X + C = 0 "!
 1.2 T "Введите коэффициенты A B C"!
 1.3 A " A=",A, " B=",B, " C=",C
 1.4 S D=B*B-4*A*C; Т "дискриминант D=",D," "; I (D)1.9,1.8
 1.5 T !,"Корни уравнения: X1=", (-B+FSQRT(D))/(2*A) !
 1.6 T "                   X2=", (-B-FSQRT(D))/(2*A) !
 1.7 T "Всё"! ; Q
 1.8 T " - нулевой"! "Поэтому корень только один: " (-B)/(2*A) ! ; G 1.7
 1.9 T " - отрицательный"!"Поэтому у этого уравнения корней нет"!; Q

Условный оператор If вычисляет значение выражения и производит передачу управления по одной из трех меток - для случаев если значение этого выражения меньше, равно и больше нуля соответственно. Последние метки могут отсутствовать - тогда выполняется остаток строки.


Шуточная программа

 1.1 A " Который час? ",N; F i=1,N,1;T  "ку-ку"!

Циклический оператор For содержит переменную - "параметр цикла" и три выражения (вычисляемые до начала цикла) - начальное значение параметра цикла, конечное значение и шаг. (Шаг может отсутствовать, тогда он буде 1 или -1 в зависимости от того что больше - конечное значение или начальное.) Тело цикла - остаток строки. Если тело цикла в одну строку не помещается - его вполне можно разместить в отдельной группе (для того они собственно и нужны), а после оператора цикла - передача ей управления с помощью оператора Do. Тело цикла - естественная подпрограмма: если передать оттуда управление оператором Go другой строке - то по достижении её конца, управление опять вернется заголовку цикла для произведения следующей итерации. За то досрочно выйти таким методом из цикла (как это делается в других языках) - невозможно. Для досрочного выхода из цикла необходимо присвоить его параметру значение больше конечного.



Литература и публикации[править]

  • В. А. Абрамов, А. В. Стрижков, А. Р. Федоров; «Диалоговый язык ФОКАЛ». М."Высшая школа", 1991. Серия «Программное обеспечение МикроЭВМ», книга 4. ISBN 5-06-001785-0
  • Г. И. Фролов, Г. А. Куправа, Ю. Г. Чаиров и др.; Под редакцией Л. Н. Преснухина; «Программирование на языке ФОКАЛ». М.Изд-МИЭТа, 1984
  • А. Н. Писаревский, Л. Г. Осетинский, М. Г. Осетинский; «ФОКАЛ — диалоговый язык для миниЭВМ». Л."Машиностроение". Ленинградское отделение. 1985

Ссылки[править]