JOSS

Не следует путать с Journal of Open Source Software.

JOSS

Семантика |

процедурный, императивный,

неструктурированный
Класс языка |  JOSS
Появился в |  1963; 62 года назад (1963)
Автор |  Джон Клифф Шоу[англ.]
Разработчик |  RAND Corporation
Испытал влияние |  ALGOL 58[вд]
Повлиял на |  TELCOMP, CAL, FOCAL, MUMPS, BASIC
Платформа |  JOHNNIAC, PDP-6
Медиафайлы на Викискладе
Часть сеанса JOSS в RAND в 1970 году, в котором пользователь выполняет несколько простых вычислений в `direct mode`. Обратите внимание на разницу между точкой в конце операторов и точкой для умножения

JOSS (акроним для JOHNNIAC Open Shop System)[1] — один из первых интерактивных языков программирования с разделением времени. В нём впервые появились такие возможности, которые впоследствии стали обычными в языках с 1960-х по 1980-е годы, включая: использование номеров строк в качестве адресов для редактирования инструкций и целевых объектов для ветвей; операторы, основанные на логических условиях; встроенный редактор исходного кода, который может выполнять инструкции в прямом (direct) или немедленном (immediate) режиме, названном диалоговым пользовательским интерфейсом.

Первоначально JOSS был реализован на машине JOHNNIAC в RAND Corporation и введён в эксплуатацию в 1963 году. Он оказался очень популярным, и пользователи быстро перегрузили машину. К 1964 году потребовалась замена на машину с более высокой производительностью. JOHNNIAC был снят с производства в 1966 году и заменён PDP-6, который впоследствии вырос до поддержки сотен компьютерных терминалов на базе IBM Selectric. Терминалы использовали зелёные чернила для пользовательского ввода и черные для ответа компьютера. Любая команда, которая не была распознана, вызывала ответ: `Eh?` или `SORRY`.

Система оказала огромное влияние, породив множество портов и ответвлений. Некоторые остались похожими на оригинал, например TELCOMP и STRINGCOMP, CAL, CITRAN, ISIS, PIL/I, JEAN (серия ICT 1900), Algebraic Interpretive Dialogue (AID, на PDP-10); в то время как другие, такие как FOCAL и MUMPS, развивались в специфических направлениях. Он также очень похож на интерпретаторы BASIC, использовавшиеся в микрокомпьютерах 1980-х годов, отличаясь в основном деталями синтаксиса.

## Содержание

* 1 История
* 1.1 Первоначальная идея
* 1.2 JOSS-1
* 1.3 Переход на JOSS-2
* 1.4 Использование JOSS-2
* 1.5 JOSS-3
* 2 Реализация
* 3 Язык
* 3.1 Прямой и косвенный режим
* 3.2 Операторы
* 3.3 Циклы и условия
* 3.4 Выражения и предложения
* 3.5 Диапазоны
* 3.6 Команды
* 3.6.1 Set
* 3.6.2 Let
* 3.6.3 Demand
* 3.6.4 Type
* 3.6.5 Page
* 3.6.6 Line
* 3.6.7 To
* 3.6.8 Do
* 3.6.9 Done
* 3.6.10 Stop
* 3.6.11 Go
* 3.6.12 Cancel
* 3.7 Math
* 3.8 Функции
* 3.8.1 Math
* 3.8.2 Boolean
* 3.8.3 Циклические функции
* 4 Управление файлами
* 5 Примечания
* 6 Литература

## История

[править | править код]

### Первоначальная идея

[править | править код]

В 1959 году Уиллис Уэр написал меморандум RAND на тему вычислений, в котором заявил, что будущие компьютеры будут иметь «множество персональных станций ввода-вывода, чтобы многие люди могли взаимодействовать с машиной одновременно»[2]. Меморандум вызвал интерес у ВВС США, основных спонсоров Rand, и в 1960 году они сформировали проект «Информационный процессор» для изучения этой концепции, которая вскоре стала известна как разделение времени. Проект не был конкретно связан с разделением времени, но был направлен на улучшение взаимодействия человека и компьютера в целом. Тогда идея заключалась в том, что постоянное взаимодействие между пользователем и компьютером в манере запрос-ответ более естественно[2]. Как позже выразился директор JOSS Кит Анкафер:

> Было две причины, которые, я думаю, привели к эксперименту. Во-первых, по крайней мере с 1950 года, когда я присоединился к Rand, отдел Rand по computer science всегда был сосредоточен на беспрепятственном взаимодействии с пользователем. Это было просто встроено в нас. Мы узнали об этом от Ганнинга. ... все, о чем мы думали. Во-вторых, видя, как математики борются с калькуляторами Маршана, было ясно, что они не могут использовать JOHNNIAC в чистом виде. Это было бы слишком тяжело. Им пришлось бы учиться на программистов. Это был бы просто разочаровывающий опыт для них. Мы хотели что-то, что выглядело бы для них естественным способом мышления, помогало в решении их проблем без особой подготовки и без необходимости становления программистом, потому что это отпугнуло бы их[3].

Оригинальный текст (англ.)

There were two perceptions that I think drove the experiment. One was, from at least 1950, when I joined Rand, there was always a focus in the computer science part of Rand toward smooth user interaction. It was just built into us. We learned it from Gunning. ... all we thought about. The other was, seeing the mathematicians struggling with Marchant calculators, not being able to use JOHNNIAC in its raw form. It was just too hard. They had to learn to be programmers. It was just a frustrating experience for them. We wanted something that would look to them as being a natural way of thinking about an aid to the solution of their problems without very much training, and without any perception of becoming a programmer, because that would have kept them away[3].

Официальное предложение разработать то, что впоследствии стало JOSS на компьютере JOHNNIAC, было принято в марте 1961 года[2].

### JOSS-1

[править | править код]

JOSS был почти полностью реализован Клиффордом Шоу, математиком, работавшим в растущем подразделении вычислений в Rand. Он был написан на символическом языке ассемблера под названием EasyFox (E и F в тогдашнем фонетическом алфавите вооруженных сил США), также разработанном Шоу[4].

Система JOSS была впервые официально запущена в мае 1963 года и поддерживала пять консолей: одну в машинном зале и ещё четыре в офисах по всему зданию[5]. Ранние консоли были основаны на передающей пишущей машинке IBM Model 868, поскольку на момент начала разработки Selectric ещё не был представлен на рынке[6]. Первое расписание было опубликовано 17 июня. В то время JOSS работал по три часа с 9:00 до 12:00 ежедневно[7]. В январе 1964 года было объявлено, что он полностью функционирует на восьми терминалах[1]. Окончательная версия была развернута в январе 1965 года[8].

К этому времени JOHNNIAC было уже более десяти лет. Его ламповая логика никогда не отличалась высокой надёжностью. Система была очень популярна, поэтому была перегружена даже когда работала хорошо. Пользователи были в восторге, один заявил:

> Люди подстраивают свою жизнь под JOSS… Бесполезно приходить в RAND до 10:00, когда JOSS запускается, на самом деле, полдень или после 17:00 — лучшее время, JOSS менее загружен. Когда JOSS начинает печатать ответы, щекотливое удовольствие сравнимо только с последующей болью, когда JOSS прерывается на тарабарщину или отключается, предав ваш код забвению. Нам сложно жить с JOSS, но мы не можем жить без него[9].

Оригинальный текст (англ.)

People adjust their lives to fit around JOSS… No use coming into RAND before 10:00 am when JOSS arrives, in fact noon or after 5:00 pm is a better time, JOSS is less busy. When JOSS starts typing answers, the titillating pleasure is equaled only by the ensuing anguish when JOSS breaks off into jibberish[sic] or goes away commending your code to oblivion. We can hardly live with JOSS, but we can’t live without it[9].

Другой выразился более кратко:

> Это лучше, чем пиво — мы подсели[1].

Оригинальный текст (англ.)

It's better than beer — we're hooked[1].

### Переход на JOSS-2

[править | править код]

В мае 1964 года было принято решение найти новую машину на замену JOHNNIAC и полностью выделить её для работы с расширенной версией JOSS. Машина также должна была поддерживать новые терминалы, изготовленные по спецификациям Rand, и должна быть доставлена к 31 октября 1965[7].

Всего было получено девять предложений. Digital Equipment Corporation (DEC) выиграла конкурс со своей новой системой PDP-6, на покупку было выделено финансирование ВВС США. DEC также согласилась построить тридцать терминалов на базе пишущей машинки IBM Selectric, модифицированной специальным механизмом для перехода к следующей странице при фальцованной веером подаче бумаги. Несколько других частей системы были поставлены другими компаниями[10].

PDP-6 прибыл в конце июля 1965 года и первоначально тестировался с использованием телетайпов модели 33 в качестве терминалов. Новая версия кода была разработана Чарльзом Л. Бейкером, Джозефом В. Смитом, Ирвином Д. Гринвальдом и Г. Эдвардом Брайаном. Система была впервые введена в эксплуатацию в октябре, хотя она требовала шесть часов планового обслуживания в неделю[11]. Первый прототип терминала прибыл в ноябре. В декабре к машине впервые удаленно подключили терминал в Лас-Вегасе[10]. В феврале 1966 года он был отправлен на базу ВВС Макклеллан, затем ещё один в августе в Академию ВВС и два в сентябре в ARPA и офис ВВС в Пентагоне. Первое постоянное дистанционное телетайпное соединение для телетайпов модели 35 было установлено на базе ВВС Лэнгли в феврале 1967 года[11].

JOHNNIAC был отключён 11 февраля 1966 года после установки и запуска новой машины. Официально он вышел на пенсию 18 февраля. Его последняя запущенная программа была написана на JOSS и отсчитывала секунды до отключения. Машина была отправлена в Музей округа Лос-Анджелес[12] и в итоге оказалась в Музее компьютерной истории за пределами Сан-Франциско[13]. После замены на систему JOSS-2 оригинал стали называть JOSS-1[14].

### Использование JOSS-2

[править | править код]

К концу 1966 года новая система JOSS-2 стала полностью функциональной и была полностью посвящена выполнению JOSS-2 24/7. Новая машина имела примерно в 30 раз большую скорость вычислений, в пять раз больше места для хранения данных на одного пользователя и множество новых функций в самом языке[15][1]. Согласно подсчётам, новая платформа могла бы поддерживать одновременное использование до 100 терминалов[16]. Владельцем системы оставались Военно-воздушные силы, а Rand и другие выступали в качестве консультантов. Процессорное время оплачивалось внешними пользователями по цене около 1 USD за минуту. Учитывалось только время фактического выполнения программы; время, затрачиваемое на набор текста и печать, было бесплатным[17].

К 1970 году насчитывалось от 500 до 600 пользователей из Rand и на различных объектах ВВС США по всей стране[18]. Многие из них были случайными пользователями, для чего и была предназначена система. Для их поддержки нестандартные терминалы были оснащены специальными «штекерами JOSS», чтобы их можно было возить из офиса в офис и подключать к специальным розеткам. Вокруг Rand было установлено двести розеток, а шасси терминала было спроектировано так, чтобы оно было достаточно узким, чтобы проходить через двери, оставляя при этом место для кофе[19]. Переключение выключателя питания на терминале приводило к его подключению в новом месте[16].

Специальные терминалы для JOSS были разработаны потому, что инженеры считали, что «телекоммуникационные функции Model 33 являются загадкой для неподготовленного человека» и будут слишком запутанными для изучения случайными пользователями[20]. На практике же механизмы на базе Selectric оказались слишком хрупкими для постоянного использования, и их часто ремонтировали в полевых условиях сотрудники IBM. В 1970 году треть терминалов были полностью переделаны, а вывод из компьютера замедлился для повышения надёжности. К этому времени ВВС решили использовать вместо них модель 35, поскольку она была легко доступна и стоила намного дешевле[21][11].

Пользователи были полны энтузиазма, и чтобы удовлетворить их, Рэнд начал публиковать Информационный бюллетень JOSS под редакцией Ширли Маркс. В конечном итоге с ноября 1967 г. по июнь 1971 г. было опубликовано 44 выпуска[22].

### JOSS-3

[править | править код]

В начале 1970-х программисты одного из заводов IBM на западном побережье построили JOSS-3 для IBM 370/158, работавшей под управлением OS/360. Существует мало информации об этой системе, за исключением того, что именно на этой машине JOSS окончательно ушёл в отставку[23]. Согласно примечанию в историческом обзоре, Rand не решилась разрешить IBM использовать имя JOSS, в результате чего «версия IBM никогда не использовалась широко»[24].

## Реализация

[править | править код]

Для вывода математических символов на своих терминалах IBM Selectric JOSS использовал нестандартный пишущий шарик, подобный этому

JOSS-II на PDP-6 был разделен на две части в соответствии с особенностями внутренней памяти машины. Машина была оснащена двумя банками основной памяти, по 16 тысяч 36-битных слов в каждом банке. Сама система JOSS, включавшая в себя операционную систему, код управления пользователями и файлами, обработчик терминалов и интерпретатор, занимала большую часть памяти первого банка. Второй банк использовался для пользовательских программ. Хотя это был относительно большой объём памяти для той эпохи, система использовалась настолько интенсивно, что пользовательского хранилища объёмом 16 тысяч слов было недостаточно, поэтому данные копировались на магнитный барабан[16]. Барабан управлялся внешним оборудованием и не требовал внимания со стороны главного процессора[25].

Для поддержки возможности выполнения нескольких пользовательских программ аппаратное обеспечение PDP-6 было модифицировано для проверки 20-го бита адресных ссылок. Если этот бит был установлен, адрес находился в «пользовательском пространстве» и изменялся таким образом, что нулевой адрес указывал на базовый адрес этого пользователя. Таким образом, пользовательские программы можно было перемещать в памяти, не вызывая проблем для системы, а операционная система могла переключаться между пользователями, просто изменяя один внутренний регистр[16].

Постоянное хранилище обеспечивалось жёстким диском Storage Products емкостью 5,7 млн слов. Как и в случае с барабаном, фактический ввод/вывод в барабан и из барабана обрабатывался извне, хотя в этом случае движение данных вызывалось действиями пользователя для загрузки и сохранения своих программ. Ленточный накопитель, совместимый с IBM, использовался для перемещения данных на накопитель и с него по мере необходимости. Операция также не зависела от ЦП. Также были доступны два устройства DECtape, которые работали так же, как диск IBM[26].

Терминалы присоединялись через специальный «концентратор», который состоял из механического переключателя Строуджера, который мог подключать любую из 300—400 возможных вилок терминала к любому из 40 выходов. Ещё восемь линий были выделены для входов Teletype Model 33, отличавшихся от вилок Selectrics в стиле JOSS. Затем эти 48 линий подключались к электронному мультиплексору, подключённому к центральному процессору. Мультиплексор управлялся прерываниями, то есть простаивающие терминалы не использовали циклы[26].

Специальные терминалы JOSS были изготовлены компанией DEC. Они состояли из механизма Selectric, встроенного в специальное шасси, содержащее систему связи, источник питания и другие компоненты. Нестандартный пишущий шарик использовался для предоставления основных математических символов, таких как ≠, что отменяло надобность в таких двухсимвольных комбинациях, как <>. Система связи была основана на 6-битном символьном коде в 8-битном пакете со стартовым и стоповым битами. Данные передавались со скоростью 120 бит/с, чтобы соответствовать максимальной скорости 15 символов в секунду механизма Selectric. Коды shift-in и shift-out использовались для перемещения ленты с зелёного на чёрный и обратно. Эти коды также детектировались системой связи и изменяли состояние индикаторов на передней панели, чтобы указать, кто контролирует терминал в данный момент: пользователь или компьютер[27].

## Язык

[править | править код]

### Прямой и косвенный режим

[править | править код]

JOSS представила идею единого редактора командной строки, который работал и как интерактивный язык, и как программный редактор. Команды, которые были введены без номера строки, выполнялись немедленно, в том, что JOSS назвал «прямым режимом». Если же перед командой стоял номер строки, вместо выполнения она копировалась в область хранения кода программы, которую JOSS назвал «косвенным режимом» (indirect mode). Если номер был уникальным, новая строка добавлялась в программу. Если номер был неуникальным, существующая строка с таким номером заменялась или удалялась из программы, если вводился только существующий номер строки, без команды[28].

В отличие от большинства разновидностей BASIC, JOSS сохранял в файлах весь пользовательский ввод, а не только программный код. JOSS при загрузке программы, по сути, снова вводил строки. Это означало, что программные файлы могли содержать как операторы программы, так и инструкции прямого (direct) режима. Например, было обычным делом видеть программы, в которых перечислялись строки операторов, а затем файл заканчивался на `Go.` для немедленного запуска программы, как только она завершит загрузку. Были некоторые функции, которые можно было использовать только в прямом режиме, такие как `Let` и `Form`, которые вводились без номеров строк, но все же выполнялись при загрузке программы[29].

Инструкции прямого и косвенного режимов можно было свободно смешивать в рабочей области. Это позволяло вставлять комментарии в исходный код, добавляя строки прямого режима, начинающиеся с `*`[30] или помещая этот символ в конец строки кода, а затем добавляя комментарий после него. Пустые строки также игнорировались, что позволяло разбивать программу для ясности[31].

type "Hello" *Выведет "Hello"
1.1 type "Hello" *запишет команду по адресу 1.1
1.1 type "World" *перезапишет команду по адресу 1.1
*удаление команды по адресу 1.1:
1.1

### Операторы

[править | править код]

Каждая строка в программе JOSS должна начинаться с номера строки. Номера строк — это числа с фиксированной точкой, состоящие из двух двузначных целых чисел, разделенных точкой. Как и в BASIC, номера строк используются как в качестве меток для целевых операторов `To` и `Do`, так и для редактирования. Ввод строки кода с новым номером строки вставляет её в программу. Ввод строки с существующим номером строки заменяет предыдущую версию. Ввод пустой строки с существующим номером строки удаляет эту строку.

Часть номера строки слева от точки называется страницей (page) или частью (part), а часть справа называется строкой (line). Таким образом, номер строки `10.12` относится к странице 10, строке 12. Ветви могут быть нацелены либо на страницу, либо на строку внутри страницы. В более позднем формате, объединённые вместе страница и строка называются шагом.

Страницы используются для определения подпрограмм. Подпрограммы возвращают управление назад, когда следующая строка находится на другой странице. Например, если подпрограмма для вычисления квадратного корня числа находится на странице 3, у неё может быть три строки кода 3.1, 3.2 и 3.3, и она будет вызываться с использованием `Do part 3.` Код вернётся к оператору после Do, когда дойдёт до следующей строки на другой странице, например, 4.1. Для возврата из подпрограммы используется `Done` (эквивалент `RETURN` в других языках программирования). Нет необходимости использовать `Done` в конце подпрограммы.

Каждая строка должна начинаться с ключевого слова команды, следующего за номером строки. Не существует понятия команды по умолчанию, как в случае с BASIC с его необязательным оператором `LET`. В одной строке можно разместить несколько операторов, разделённых двоеточием или точкой с запятой. Каждая строка должна заканчиваться точкой.

### Циклы и условия

[править | править код]

JOSS использует суффиксальную нотацию для обозначения условных операторов, «сделайте это действие, если это условие верно», в отличие от большинства языков, которые помещают условие впереди (префиксная нотация), «если это условие верно, сделайте это действие». Подобно BASIC, но в отличие от FORTRAN или FOCAL, к любому оператору может быть добавлено условие. Например, чтобы напечатать строку только при выполнении условия, можно объединить if с `Type`:

1.1 Type "Hello, World!" if X=5.

JOSS поддерживает шесть инфиксных сравнений, `=`, `≠`, `≥`, `≤`, `>`, `<` и логические операторы `or`, `and`, и `not`[32].

Циклы обрабатывались аналогичным образом, используя команду `For` и специфичный формат для указания границ цикла и значения шага: `start(step)end`. Например, для выполнения цикла от 1 до 10 с шагом в 2 используется формат `1(2)10`. Подобно `If`, `For` можно применить к любому другому оператору:

1.2 Type "Hello, Wikipedia!" for i=1(2)10.

Обратите внимание, что for применяется только к одному оператору; если необходимо запустить несколько операторов в цикле, они должны быть выделены в отдельную страницу и вызваны с помощью do:

1.3 Do part 5 for i=1(1)100.
5.1 Type "Hello, Wikipedia!".
5.2 Type "This is JOSS.".

Как и в BASIC, любые параметры цикла for могут быть константами, переменными или другими выражениями.

Поскольку такого рода диапазоны могут быть применены к любой строке кода, можно определить ограничения и циклы при вызове программы. Например, рассмотрим программу:

1.1 Type X.

Если этот участок кода будет вызван командой `Do` (аналог `RUN` в BASIC):

Do part 1.

Он выведет:

Однако можно изменить это поведение, добавив к вызову конструкцию цикла:

Do part 1 for i=1(1)5.
Do part 1, 5 times.

Полученный вывод будет:

Это позволяет создавать формулы в программах, не помещая их в циклы. Циклы, при желании, могут быть добавлены пользователем при запуске программы.

### Выражения и предложения

[править | править код]

Уникальной особенностью JOSS является обработка логических выражений. Большинство языков программирования позволяют формировать математические выражения из нескольких частей: например, `Set x=(1+2)·3.` установит в переменную x значение 9. J,OSS расширил эту концепцию, чётко определив понятие «предложение» («proposition») — выражение, которое возвращает логическое значение (истинное или ложное), вместо числового. В основном они используются в операторах `If`, как в приведенных выше примерах, но логическое значение также можно хранить в переменных[33] или преобразовывать значение true в 1, а значение false в 0 с помощью функции `tv` (значение истинности)[34].

В дополнение к предложениям в JOSS также вводит понятие «условных выражений». Они состоят из строк утверждений вместе с кодом, который выполняется, если это утверждение истинно. Это позволяет записывать многоступенчатые деревья решений в одну строку. Они служат цели, аналогичной тернарному оператору в современных языках, таких как C или Java, где они используются для возврата значения из компактной структуры, реализующей if-then-else. JOSS допускает любое количество условных выражений, так что это скорее компактный оператор switch, чем компактный if-then[35].

В этом примере воссоздается функция функции `sgn`[36]:

Let s(x)=[x=0:0; x>0:1; x<0:-1].

Эта строка определяет функцию «s», которая принимает один параметр «x» и последовательно выполняет три проверки. Если какая-то проверка пройдена, будет возвращено её значение, указываемое через двоеточие[37].

### Диапазоны

[править | править код]

Ещё одной продвинутой особенностью JOSS является концепция диапазона как встроенного типа, который можно хранить и которым можно манипулировать. Диапазоны обычно используются в качестве входных данных для циклов for, где они являются частью синтаксиса самого цикла. Например, в BASIC можно написать цикл for, используя этот базовый синтаксис:

FOR I=1 TO 5 STEP 2

Эта строка выполнит цикл, который присваивает значения 1, 3, 5, а затем завершается.

JOSS использует особенный формат для определения границ цикла. Эквивалентный код в JOSS будет таким:

I=1(2)5

В этом коде нет for. Это потому, что в JOSS диапазоны являются отдельными конструкциями языка, а не частью цикла, в отличие от BASIC. Диапазоны могут быть определены и использованы во многих контекстах вне циклов. Например, вот условное выражение, вычисляющее факториал параметра x[35]:

Let f(x)=[x=0:1 ; fp(x)=0:prod(i=1(1)x:i)].

В этом примере есть два основных предложения, разделённых точкой с запятой. Первое (левое) утверждает, что если параметр x равен 0, условие должно немедленно вернуть 1. Если это предложение не подходит (условие ложно), вычисление переходит ко второму предложению(правому). Оно проверяет, равна ли дробная часть x нулю (то есть является ли это число целым), и если да, то вызывает функцию `prod` для умножения диапазона значений. Параметр, принимаемый в данном примере функцией `prod`, также является предложением, но в данном случае он заменяется итератором цикла, который выполняется от 1 до x с шагом 1. Если предложение истинно (а оно истинно для всех значений цикла), оно возвращает индекс i. Это приводит к отправке в `prod` ряда значений от 1 до x[35].

Комбинация этих функций позволяет писать сложные функции с помощью нескольких команд. Такого рода функциональность стала распространённой только в гораздо более современных языках, которые обычно используют итераторы или функцию map для получения тех же результатов. Способность JOSS объединять решения и циклы в компактной форме отсутствовала в других языках той эпохи, включая такие ответвления, как FOCAL.

### Команды

[править | править код]

#### Set

[править | править код]

Команда `Set` присваивает результаты выражения указанной переменной. Эквивалент `LET` в BASIC.

01.30 Set p=3.14156.
01.60 Set i=l*(r/100)*t.

`Set` необязательна в прямом (direct) режиме, и выражение можно записать как `x=5.` без команды Set. В отличие от BASIC, в JOSS необходимо всегда прописывать команду Set при работе в косвенном (indirect) режиме[38].

#### Let

[править | править код]

`Let` используется для определения пользовательских функций[39]. Эквивалент в BASIC: `DEF FN`[30].

Let t(x)=sin(x)/cos(x).
Set j=t(1.1).
Type j.

`Let` также может быть использована для присвоения переменной константного значения с помощью формулы:

Let x=5.

После этого переменную можно использовать так же, как созданную с помощью `Set`. Однако есть существенная разница: когда на такую переменную ссылаются в коде, её значение (правая часть) будет вычисляться каждый раз. `Set` вычисляется только один раз, поэтому он намного быстрее[40].

Обычно система предлагала использовать `Let` только в прямом (direct) режиме, сохраняя их результаты для использования в программе, вставляя их вверху или внизу файла. Это позволяло избежать многократного вызова `Let` во время выполнения, вызывая его только один раз в процессе загрузки[41].

#### Demand

[править | править код]

`Demand` принимает список переменных и сохраняет а них пользовательский ввод. Необязательный квалификатор `as` добавляет пользовательское приглашение. Эквивалентно `INPUT` в BASIC.

01.01 Type "What is your age?".
01.02 Demand A.
01.03 Type "You are", A.
01.04 Demand H as "What is your height?".
01.05 Type H,"? That tall?".

#### Type

[править | править код]

Команда `Type` принимает на вход несколько разделённых запятыми элементов и последовательно выводит их. В своей основной форме он эквивалентен `PRINT` BASIC. Однако `Type` включает в себя ряд необязательных форм, которые сильно перегружают его, выполняя ряд несвязанных задач вывода[42].

При использовании для печати значений параметры могут быть переменными, литеральными строками, заключёнными в двойные кавычки, и специальным символом `_`, выводящим перевод строки[43]. `Type` также поддерживает форматированный вывод с использованием форматных строк. Подробнее см. в разделе `Form` ниже[42].

Type также используется как эквивалент оператора `LIST` языка BASIC, выводящего программу. Например, `Type step 1.1.` распечатает одну строку кода, в то время как `Type part 1.` распечатает страницу, а `Type all.` распечатывает всю программу целиком[42].

Кроме того, его также можно использовать для печати списков внутренних значений. `Type all values.` создает список всех переменных и их значений, а `Type size.` распечатывает размер программы. Список ключевых слов также включает `size`, `time` и `users`[42].

#### Page

[править | править код]

`Page` запускает подачу новой страницы на специальных JOSS терминалах[33]. JOSS обычно отправляет сигнал перевода страницы, когда терминал достигает 54-й строки на бумаге, поэтому если нужно, чтобы блок данных не был разделён, можно использовать следующую конструкцию[44]:

1.10 Page if $>44.

Данная конструкция сделает перенос, если номер текущей строки больше 44.

`$` это псевдопеременная, возвращающая номер текущей строки[44].

#### Line

[править | править код]

`Line` вызывает переход на новую строку на специальных терминалах JOSS[33].

#### To

[править | править код]

Команда `To` переводит выполнение программы на указанную страницу или шаг, используя `To part 1.` или `To step 1.1.` соответственно[45]. Является эквивалентом команды `GOTO` в BASIC.

01.01 Demand A as "TYPE A NUMBER".
01.05 To step 1.01.
01.10 To part 1.

#### Do

[править | править код]

`Do` похож на `To`, но `Do` вызывает подпрограмму. Как и в случае с To, можно использовать `Do part` и `Do step` для вызова конкретной страницы или конкретного шага соответственно. Если в качестве аргумента указан шаг, выполнится конкретна эта строка, после чего управление передаётся коду, следующему за командой Do. Если в качестве аргумента передана страница, выполнение начинается с первой строки страницы и продолжается до тех пор, пока не будет достигнут конец страницы или не встретится оператор Done, после чего управление, как и в случае с шагом, передаётся команде, следующей за командой Do

01.15 Do step 7.24.
01.16 Do part 8.

У `Do` есть специальная короткая форма для выполнения подпрограммы несколько раз. При этом используется модификатор times вместо обычного for в случае простых циклов. Таким образом, следующие строки эквивалентны[42]:

Do part 1 for i=1(1)5.
Do part 1, 5 times.

JOSS поддерживает указатель на текущую исполняемую строку (счётчик команд), который изменяет команда `Do` Однако есть специальная «скобочная» версия, которую можно использовать в прямом (direct) режиме для проверки определённых участков кода без изменения основного указателя. Например, если программа остановилась из-за ошибки и неясно, какой раздел вызвал проблему, можно протестировать конкретную подпрограмму с помощью[46]:

(Do part 2.)

Последующий вызов `(Cancel.)` вернёт основной указатель команд.

#### Done

[править | править код]

Команда `Done` возвращает управление из подпрограммы. `Done` используется только для раннего возврата и часто используется с условным выражением, поскольку подпрограммы возвращают управление автоматически, когда достигнут конец страницы. Эквивалент `RETURN` в BASIC.

*Routine to ask the user for a positive value and repeat until it gets one
01.10 Demand X as "Enter a positive value greater than zero".
01.20 Done if X>0.
01.30 To step 1.1

#### Stop

[править | править код]

Команда `Stop` завершает выполнение программы и возвращает управление среде редактирования. Эквивалентен `END` в BASIC. Команда `STOP` в BASIC предназначена для возможности продолжения выполнения программы с того же места с помощью команды `CONT`. В системе JOSS, ориентированной на рабочее пространство, отсутствует прямой эквивалент команды `STOP` из BASIC.

01.10 Type X.
01.20 Stop.

#### Go

[править | править код]

Доступна только в прямом (direct) режиме. Вызов `Go` эквивалентен вызову `RUN` и `CONT` в BASIC в зависимости от того, остановлена ли программа в данный момент из-за ошибки или команды `Stop` [47].

#### Cancel

[править | править код]

Доступна только в прямом (direct) режиме, `Cancel`, используется, когда программа остановлена из-за ошибки, и пользователь хочет сбросить программу. `Cancel` очищает счётчик команд. Обычно `Go` продолжает выполнение программы, но использование `Cancel` заставляет `Go` начинать программу сначала[48].

Если выполнение было приостановлено во время выполнения `(Do.)`, можно выполнить команду Cancel в скобках `(Cancel.)`, чтобы сбросить только это подвыполнение и вернуть счётчик основной счётчик команд (см команду Do). Тогда вызов `Go` продолжит выполнение с того места, на котором была остановлена программа до выполнения `(Do.)`.

### Math

[править | править код]

JOSS хранит все числа в формате radix-10 с плавающей запятой[49].

JOSS содержит шесть математических операторов[49]:

* `+` для сложения
* `-` для вычитания
* `·` для умножения (интерпункт, не точка)
* `/` для деления
* `*` для экспоненты
* `|...|` для взятия модуля (выражение записывается внутри)

Математические выражения могут использовать () и [] взаимозаменяемо в соответствующих парах для установления приоритета. Например:

1.30 Set A=|-10·[5+1]·(1+5)|.

Запишет в переменную A значение 360[32].

### Функции

[править | править код]

Язык содержит следующие встроенные функции:

#### Math

[править | править код]

* `sin()` — синус угла (угол в радианах)
* `cos()` — косинус угла (угол в радианах)
* `arg()` — принимает на вход координаты точки X и Y т возвращает угол между этой точкой и осью x.
* `log()` — натуральный логарифм
* `exp()` — натуральное основание в степени аргумента
* `sqrt()` — квадратный корень
* `sgn()` — знак аргумента. 0 если аргумент нулевой, −1 если аргумент отрицательный, +1 если аргумент положительный
* `ip()` — целая часть аргумента. `ip(22026.4658)` вернёт 22026
* `fp()` — дробная часть аргумента. `fp(22026.4658)` вернёт .4658
* `dp()` — нормализованная часть числа, `dp(22026.4658)` вернёт 2.20264658
* `ep()` — экспоненциальная часть числа по основанию 10, `ep(22026.4658)` вернёт 4

#### Boolean

[править | править код]

* `tv()` — возвращает 1 если аргумент истинен и 0 в противном случае

#### Циклические функции

[править | править код]

В JOSS также определён ряд функций, чтобы программисту не приходилось писать цикл `For` для выполнения простых задач, таких как суммирование ряда чисел. Параметрами могут быть либо список простых выражений, разделённых запятыми, либо конструкция диапазона, командой которой может быть любой оператор или вызов функции.

* `max()` — Максимальное значение среди введённых выражений
* `min()` — Минимальное значение среди введённых выражений
* `sum()` — Сумма всех введённых выражений
* `prod()` — Произведение всех введённых выражений
* `first()` — Первый элемент из списка значений, удовлетворяющий условиям

## Управление файлами

[править | править код]

Система JOSS хранила пользовательские программы в выделенном пространстве на жестком диске. В этом пространстве можно было хранить несколько файлов. Имя файла было составным и состояло из целого числа и пятибуквенного имени в круглых скобках, например, `123 (hello)`. Целая часть является эквивалентом каталога, а имя — название файла внутри него, поддерживаемым самой JOSS[50].

Файлы записываются конструкцией `File all as item filename.` и загружаются конструкцией `Recall item filename.`. Также можно прочитать или сохранить конкретные части рабочей области, например, `File part 1 as item filename.` для сохранения одной процедуры (страницы) в файл[51]. Кроме того, с помощью конструкции `Use item filename.` можно было установить файл по умолчанию, на который ссылались все ссылки. Файлы можно было удалить с помощью `Discard`[51].

1.1 Demand p,q.
1.2 Stop if q<0 or r(q,2)=0.
1.3 Set a=1.
1.4 Do part 2 while q>1 and a≠0.
1.5 Type a in form 3.
1.6 Stop.

2.1  Do part 20.
2.1  Do part 11 if p<0.
2.2  Do part 12 if p≥q.
2.3  Do part 13 if p=0.
2.4  Done if a=0.
2.5  Set p=p/4 while r(p,4)=0.
2.6  Do part 14 if r(p,2)=0.
2.7  Do part 20.
2.8  Set a=-a if r(p,4)=r(q,4)=3.
2.9  Set s=p, p=q, q=s.
2.95 Do part 20.

11.1 Set a=-a if r(q,4)=3.
11.2 Set p=|p|.
11.3 Do part 20.

12.1 Set p=r(p,q).
12.2 Do part 20.

13.1 Set a=0, p=1, q=1.

14.1 Set a=-a if r(q,8)=3 or r(q,8)=5.
14.2 Set p=p/2.

20.1 Type p, q in form 1 if a=1.
20.2 Type p, q in form 2 if a=-1.

Form 1: "  L(%.0f,%.0f)  ="
Form 2: "  -L(%.0f,%.0f)  ="
Form 3: "  %.0f\n"

Обратите внимание, что это не оригинальный пример, а код для современного симулятора. Есть некоторые синтаксические отличия от оригинального языка JOSS.

## Примечания

[править | править код]

1. ↑ 1 2 3 4 5 Bryan, 1966, p. 2.
2. ↑ 1 2 3 Marks, 1971, p. 1.
3. ↑ 1 2 Norberg, 1989, p. 7.
4. ↑ Ware, 2008, p. 62.
5. ↑ Marks, 1971, p. iii.
6. ↑ Shaw, 1965, p. 3.
7. ↑ 1 2 Marks, 1971, p. 2.
8. ↑ Smith, 1967.
9. ↑ 1 2 Shaw, 1965, p. 14.
10. ↑ 1 2 Marks, 1971, p. 3.
11. ↑ 1 2 3 Marks, 1971, p. 9.
12. ↑ Marks, 1971, p. 4.
13. ↑ JOHNNIAC (неопр.). Computer History Museum. Дата обращения: 20 ноября 2022. Архивировано 17 ноября 2022 года.
14. ↑ Ware, 2008, p. 15, 109.
15. ↑ Marks, 1971, p. 5.
16. ↑ 1 2 3 4 Bryan, 1966, p. 3.
17. ↑ Marks, 1971, p. 32.
18. ↑ Marks, 1971, p. 10.
19. ↑ Marks, 1971, p. 15.
20. ↑ Marks, 1971, p. 14.
21. ↑ Bryan, 1966, p. 12.
22. ↑ Marks, 1971, p. 47.
23. ↑ Ware, 2008, p. 65.
24. ↑ Ware, 2008, p. 16.
25. ↑ Bryan, 1966, p. 4.
26. ↑ 1 2 Bryan, 1966, p. 5.
27. ↑ Bryan, 1966, p. 6.
28. ↑ Gimble, 1967, p. v.
29. ↑ Gimble, 1967, p. vi.
30. ↑ 1 2 Gimble, 1967, p. 65.
31. ↑ Marks, 1971, p. 42.
32. ↑ 1 2 Gimble, 1967, p. 70.
33. ↑ 1 2 3 Gimble, 1967, p. 77.
34. ↑ Gimble, 1967, p. 24, 69.
35. ↑ 1 2 3 Gimble, 1967, p. 75.
36. ↑ Marks, 1971, p. 41.
37. ↑ Gimble, 1967, p. 25.
38. ↑ Gimble, 1967, p. 68.
39. ↑ Gimble, 1967, p. 74—75.
40. ↑ Gimble, 1967, p. 45.
41. ↑ Gimble, 1967, p. 63.
42. ↑ 1 2 3 4 5 Gimble, 1967, p. 66.
43. ↑ Gimble, 1967, p. 7.
44. ↑ 1 2 Gimble, 1967, p. 49.
45. ↑ Gimble, 1967, p. 67.
46. ↑ Gimble, 1967, p. 58.
47. ↑ Gimble, 1967, p. 57.
48. ↑ Gimble, 1967, p. 53.
49. ↑ 1 2 Gimble, 1967, p. 69.
50. ↑ Gimble, 1967, p. 59.
51. ↑ 1 2 Gimble, 1967, p. 61.

## Литература

[править | править код]

* Bryan G. E.. JOSS: Introduction to the System Implementation (англ.). — Lawrence Radiation Laboratory, Berkeley California: DECUS, 1966. — 4 November.
* Gimble E. P.. JOSS: Problem Solving for Engineers (англ.). — Rand, 1967. — May.
* Marks S.. The JOSS Years: Reflections on an experiment (англ.). — Rand, 1971. — December.
* Norberg A.. An Interview with Keith Uncapher (англ.). — Лос-Анджелес, США: Charles Babbage Institute, 1989. — 10 July.
* Sammet J.. Programming languages : history and fundamentals (англ.). — Prentice-Hall, 1969. — P. 217–226. — ISBN 0-13-729988-5.
* Shaw J. C.. JOSS: Experience with an experimental computing service for users at remote typewriter consoles (англ.). — Rand, 1965. — May.
* Smith J. W.. JOSS: Central Processing Routines (англ.). — RAND, 1967.
* Ware W.. RAND and the Information Evolution (англ.). — Rand, 2008. — ISBN 9780833048165.

Языки программирования

* История
* Хронология

* 1C
* Ада
* Алгол
* Ассемблер
* APL
* Бейсик
* Си
* C++
* C#
* D
* Delphi
* Кобол
* Erlang
* F#
* Форт
* Фортран
* Go
* Groovy
* Haskell
* Java
* JavaScript
* Julia
* Kotlin
* Лисп
* Lua
* MATLAB
* Оберон
* Objective-C
* OCaml
* Паскаль
* Perl
* PL/SQL
* PHP
* Python
* Racket
* Ruby
* Rust
* Scala
* UNIX Shell
* Smalltalk
* Swift
* Visual Basic .NET
* Zig

*[Bryan G. E.]:
*[Gimble E. P.]:
*[Marks S.]: Marks, Shirley
*[Norberg A.]: Norberg, Arthur
*[Sammet J.]: Sammet, Jean
*[Shaw J. C.]:
*[Smith J. W.]:
*[Ware W.]: Ware, Willis