vak: (Default)
[personal profile] vak
Была ли жизнь до Алгола и Фортрана? Бытует представление, что Фортран и Алгол были первыми языками, данными богом человеку, а до них ничего не было, и только святой дух витал над водами. Однако это не так, и третья глава книжки про ЭВМ "Киев" даёт нам возможность заглянуть в доисторическую эпоху, когда программирование в машинных кодах уже осточертело, а человеческие языки ещё не зародились.

Так называемый Адресный язык был придуман программистами для математиков. Или наоборот, математиками для программистов. Дело происходило в конце 50-х в Лаборатории вычислений киевского института Математики.Та самая лаборатория и та самая команда, где создавался первая советская ЭВМ МЭСМ.

МЭСМ заработала в 1951-м и продолжала активно эксплуатироваться до 1957 года. К ней мгновенно образовалась очередь математиков, желающих чего-нибудь посчитать. Известные люди, доктора и академики, у каждого своя важная народно-хозяйственная задача. И конечно, никто не смыслит в машинных кодах, и знать не желает систему команд ЭВМ. Тем более, что она секретная и нигде не описанная.

Сложилась практика, что математики присылают свои задачи программистам на своём математическом языке. То есть набор математических формул со словесными комментариями. Задачей сотрудников Лаборатории вычислений было переложить задачу на язык машины, выполнить на ЭВМ и сообщить численные результаты. Отладка программы и верификация результатов сильно затруднялась по той простой причине, что математики не имели возможности отследить правильность машинного кода. Нужна была некая промежуточная форма, понятная и математикам-постановщика задачи, и программистам-вычислителям. Так возник Адресный язык.

Поначалу ни о какой автоматической трансляции Адресного языка в машинный код речь не шла. ЭВМ была слишком слаба для такой задачи. Машинный код порождался человеком вручную, глядя в исходник на Адресном языке, и выписывая оператор за оператором. И тем не менее, это было эффективнее, чем делать это непосредственно из исходных математических формул. Только через несколько лет, в середине 60-х была поставлена задача построения транслятора Адресного языка, и частично решена для некоторых советских ЭВМ. Но к тому времени появились Алгол и Фортран, и интерес сместился. Пошла совсем другая история.

Посмотрим, как выглядел Адресный язык. Я буду стараться использовать термины из оригинального описания языка, и показывать аналогию с современностью (в основном Си).

Программа представляет собой последовательность строк. В каждой строке записывается одно или несколько действий. Между действиями в строке, если их несколько, ставится точка с запятой или запятая. Запятая ставится, если первое действие должно закончиться раньше, чем начнётся второе. Точка с запятой означает, что порядок действий не имеет значения. То есть их можно выполнять как бы параллельно, для эффективности.

Пример:
        действие
действие, действие -- последовательное выполнение
действие; действие -- параллельное выполнение
Строки могут помечаться метками. Метка ставится слева и отделяется троеточием. Меткой может быть не только имя или число, но и произвольный набор символов (что нынче смотрится несколько странно).

Оператор безусловного перехода - это просто метка в строке. Никакого "goto" не нужно. Тоже необычно. Причём это может быть не просто метка, а произвольное арифметическое выражение, в качестве результата выдающее число, служащее меткой. Пример действия, помеченного меткой, и безусловного перехода на эту метку:
метка...    действие
метка -- безусловный переход на метку
Оператор присваивания состоит из двух выражений, разделенных знаком "=>". Вычисляется значение первого выражения, после чего засылается в память по адресу, полученному от второго выражения. В современных языках наоборот, присваивание работает справа налево.

Вторая форма: обмен значениями, когда два выражения разделяются знаком "<=>". Значения по левому и правому адресам меняются местами.
        выражение => выражение      -- присваивание
выражение <=> выражение -- обмен значениями
Арифметические выражения не отличаются от современных. Они состоят из операндов, знаков операций и скобок. Допускаются встроенные функции: синус, косинус и прочие.

В адресном языке вводится операция выделения содержимого адреса. Операция обозначается символом кавычки, который ставится слева от адреса-операнда. Называется штрих-операция первого ранга. В современном языке Си такая операция называется разыменованием и обозначается звёздочкой.
        'адрес      -- чтение значения по адресу, как *ptr в Си
Две кавычки, или штрих-операция второго ранга, означает двойное разыменование. Cначала читаем значение по адресу, интерпретируем его как другой адрес, и потом по нему снова читаем значение. Штрих-операцию второго ранга можно также обозначать верхним индексом ² вместо двух кавычек. Аналогично третий ранг - индексом ³ и так далее.
        ''адрес     -- чтение значения по адресу, прочитанному по адресу, как **ptr
²адрес -- то же самое, **ptr
³адрес -- аналогично трижды, ***ptr
Окончание выполнения программы обозначается восклицательным знаком.
Это как "exit(0)" в Си.
        !
Возврат из текущей подпрограммы в вызвавшую её программу обозначается перевёрнутой буквой "𐐒". Ровно как "return;" в Си.
        𐐒
Вызов подпрограммы производится оператором П с параметрами.
        П{a, b, c} имя      -- в Си это равносильно имя(a, b, c)
Имя подпрограммы должно быть объявлено где-то в качестве метки. За ним обычно следует несколько строк, сохраняющих значения полученных параметров, в виде присваиваний с левой частью в форме символа ∅. Затем тело подпрограммы, завершающееся оператором возврата 𐐒: Например, подпрограмма с двумя параметрами a и b, возводящая a в квадрат и записывающая его в b:
pow2... ∅ => a
∅ => b
'a * 'a => 'b
𐐒
Условный оператор имеет вид:
        P{выражение} действие1 ↓ действие2  -- предикатная формула (если-то-иначе)
Это в точности соответствует в Си оператору "if (выражение) { действие1 } else { действие2 }". Причём действие1 и действие2 здесь могут состоять из нескольких операторов Адресного языка, разделённых запятыми и/или точками с запятой. Часть P{выражение} называется предикатной функцией. Её условное выражение вычисляет "истина" или "ложь", по которым принимается решение о выполнении действия1 или действия2.

Оператор цикла имеет вид:
        Ц{a (b) c => x} метка
Последний оператор тела цикла помечается меткой, как в Фортране. Если тело цикла состоит только из одной строки (следующей), метку можно не ставить. В языке Си это соответствует конструкции:
        for (x = a; x <= c; x += b) {
...
метка: }
Есть также форма цикла с условием вместо заданного последнего значения:
        Ц{a (b) P{z} => x} метка
В языке Си это эквивалентно:
        for (x = a; z; x += b) {
...
метка: }
Последняя конструкция, совершенно неожиданная в древнем языке - фактически аналог templates из нынешнего Си++. Называется формула замены:
        З{a->b, c->d, e->f} начало, конец
Это означает, что берётся фрагмент кода, описанный где-то в программе, заключённый между метками "начало" и "конец", и подставляется в текущее место программы. В этом фрагменте символы a заменяются на b, символы c на d и символы e на f. Причём символы это не обязательно имена переменных: могут быть значки арифметических операций, к примеру. То, что мы сейчас называем шаблонами.

Пример: Пусть требуется для ряда значений переменной x, размещённых по адресам α+1, α+2, ..., α+n, вычислить значение некоторой функции f(x) и поместить в адреса β+1, β+2, ..., β+n. Адресная программа такого алгоритма может быть записана в виде:
        1 => i
k... P{'i ≤ n} ↓ !
f('(α + i)) => β + 'i
'i + 1 => i
k
Заметим, что язык недоопределён. Предположим, у нас есть компилятор с адресного языка, и мы подаём ему на вход
вышеприведённый текст. Компилятор выдаст следующие ошибки:
i: значение не определено
n: значение не определено
α: значение не определено
β: значение не определено
f: функция не определена
Доопределим программу, введя новый синтаксис для привязки имен к адресам или встроенным функциям. Имя, за ним двоеточие и число - задаёт численное значение для имени. Это может быть адрес в памяти или вещественная константа. Например:
        i: 1
Аналогично дадим возможность давать имена встроенным функциям, например:
        f: sin
Получаем законченную программу, которую можно было бы попытаться обработать (несуществующим) компилятором:
        i: 1
n: 5
α: 10
β: 20
f: sin
1 => i
k... P{'i ≤ n} ↓ !
f('(α + i)) => β + 'i
'i + 1 => i
k

Date: 2021-08-09 01:34 (UTC)
juan_gandhi: (Default)
From: [personal profile] juan_gandhi

Чудесно! И все это на военные деньги, и все это секретно, и все так старались тщательно...

Date: 2021-08-09 02:05 (UTC)
paserbyp: (Default)
From: [personal profile] paserbyp
Помню как написал первую программу для игры в крестики-нолики на подобном языке для https://ru.wikipedia.org/wiki/Промінь_(компьютер)
Edited Date: 2021-08-09 02:05 (UTC)

Date: 2021-08-09 09:13 (UTC)
paserbyp: (Default)
From: [personal profile] paserbyp
Что-то типа ассемблера, где было три составляющие: команда и два оператора, если я ничего не забыл и ничего не перепутал. Набиралась программа с помощью штырьков, которые вставлялись в специальную доску…
Edited Date: 2021-08-09 09:14 (UTC)

Date: 2021-08-09 02:56 (UTC)
From: [personal profile] dijifi
Макро, а не templates…

Date: 2021-08-09 04:40 (UTC)
From: [personal profile] dijifi
Если мы говорим о 50х - 60х, то точно макро. Если о 90х и позже - то могут быть и шаблоны.

Date: 2021-08-09 08:10 (UTC)
x86128: (Default)
From: [personal profile] x86128
Разве макро это не исполнимый код времени компиляции результатом работы которого является снова код на исходном языке программирования? (как интеграл или дифференциал в математике)
Шаблон же про то, что заменили одно на другое, возможно по условию, результат в положили обратно в код. (как подстановка неизвестных и правила сокращения дробей)

Date: 2021-08-09 17:25 (UTC)
From: [personal profile] dijifi
Это детали имплементации. Я вижу что спецификация описывает простую текстовую замену, как в макро

Date: 2021-08-09 06:21 (UTC)
ufm: (Default)
From: [personal profile] ufm
Идея с "," и ";" - отличная, на самом деле.

Date: 2021-08-09 17:23 (UTC)
From: [personal profile] dijifi
Интересно что в стандартном Си с точностью наоборот, запятая не вставляет séquence point

Date: 2021-09-01 16:03 (UTC)
From: [personal profile] flamedancerii
зависит от контекста, как оператор как раз вставляет, а вот как разделитель параметров функции - нет.

Date: 2021-08-09 06:33 (UTC)
dluciv: (Default)
From: [personal profile] dluciv

Машинный псевдокод, с которым по уровню примерно сравнима LLVM. По-моему авторы в точку попали.

Date: 2021-08-09 09:05 (UTC)
x86128: (Default)
From: [personal profile] x86128
Еще можно добавить модули (подключаемые библиотеки) для этого понадобятся пространства имен и области видимости.

Надо придумать конструкции которые задают блоки адресов чтобы исключить их случайное пересечение.

Для защиты областей памяти можно рассмотреть возможность адаптации концепций передачи владения и заимствования подобно языку Rust:
1) каждое значение (или ссылка на значение) имеет переменную, которая называется владельцем значения,
2) у значения может быть только один владелец в один момент времени,
3) когда владелец покидает область видимости, значение удаляется.

это позволит сделать большую часть аллокаций памяти на стеке и исключить возможность возникновения null-указателей.

Date: 2021-08-09 09:29 (UTC)
From: [personal profile] yury_yuschenko
В СССР были созданы все условия для "уничтожения" Адресного языка программирования (1955г.).
Начиная с 1965г. прекращена начатая разработка компилятора для БЭСМ-6, как и для последующих советских компьютеров.
Был запрет на развитие языка, включая публикации и доклады на научных конференциях.
Последняя публикация по адресному языку датируется началом 1965г.

Несмотря на это:
1. Программисты СССР и социалистических стран использовали Адресный язык на протяжении более 20 лет.
2. "Адресный язык" "переобулся" в термин "Автокоды". Например К.М.Лаврищевой для компьютера "Днепр-2" был разработан компилятор с языка высокого уровня "Автокод". Этот "Автокод" по своей сути является базовой/основной частью Адресного языка. Языки с названием "Автокод" реализовывались на многих всех советских компьютерах.

Отдельно следует отметить, что в СССР были созданы условия для максимального сокрытия достижений Института Математики, а за рубежем эти достижения не могли быть известны по причине наличия железного занавеса во времена холодной войны.
Это стало одной из причин того, что про уникальность, дальновидность и мощнейшие средства Адресного языка программирования не известно ни за рубежом ни во всём постсоциалистическом пространстве.
Историки ИТ о компьютере "Киев" пишут исключительно основные технические характеристики. Посему широкому кругу людей совершенно не известно про уникальность программного обеспечения этого компьютера и том какое влияние оказал этот компьютер на развитие как технической базы ИТ, так на развитие технологий программирования.
Edited Date: 2021-08-10 12:05 (UTC)

Date: 2021-08-09 09:55 (UTC)
vit_r: default (Default)
From: [personal profile] vit_r
Спасибо. Ещё одно доказательство того, что слабые к защите от ошибкок свойства языка не выживают. (Безобразие с темплейтами не имеется ввиду, потому что это уже нововведение нашего времени.)

Date: 2021-08-09 17:29 (UTC)
From: [personal profile] dijifi
С этого момента Си выглядит как Адресный язык + структурное программирование

Date: 2021-08-09 22:02 (UTC)
From: [personal profile] dijifi
Надо ещё и CPL вспомнить как концепцию

Date: 2021-08-09 22:27 (UTC)
From: [personal profile] dijifi
Поэтому в наши дни перед тем, как стандарт утверждать, лучше иметь работающую имплементацию. Или даже две. Кронос, например, так делает.

Date: 2021-08-16 12:36 (UTC)
denis_juriev_chronicles: (Default)
From: [personal profile] denis_juriev_chronicles
Спасибо за очень интересную и содержательную публикацию.

Date: 2021-08-18 21:44 (UTC)
mtve: (Default)
From: [personal profile] mtve
вот здесь https://sinews.siam.org/Details-Page/obituaries-vera-nikolaevna-kublanovskaya упоминается некий язык "Прораб", примерно 1955-й год:
"At about that time Leonid Vitalievich Kantorovich (1912-1986) was organizing a group in Leningrad to develop a universal computer language, Prorab, for BESM, the first electronic computer in the USSR, which was completed in 1954 in Moscow"

но чего-то он не гуглится.

Date: 2021-08-19 16:33 (UTC)
mtve: (Default)
From: [personal profile] mtve
Cпасибо! Очень интересно, хотя и звучит немного преувеличено. В биографиях Канторовича вроде бы это не упоминается.