Каким должен быть язык программирования? Анализ и критика Описание языка Компилятор
Отечественные разработки Cтатьи на компьютерные темы Компьютерный юмор Прочее

Идеальный транслятор

А этот… э… диван?
— Ручной труд, - быстро сказал Роман.
— Безотказен. Конструкции Льва Бен Бецалеля. Бен Бецалель собирал и отлаживал его триста лет…
— Вот! — сказал лоснящийся Модест Матвеевич.
— Вот как надо работать! Старик, а все делал сам.

А. и Б. Стругацкие «Понедельник начинается в субботу»

            У меня есть идеальный транслятор. Только не подумайте, что я продавец очередного «идеального продукта» с рекламой в духе Голливуда. Я не торгую трансляторами, не ищу пользователей и не собираюсь доказывать, что этот транслятор наилучший. Потому, что придерживаюсь мнения: если Вы сами убеждены, что Ваше программное средство лучшее — радуйтесь втихомолку и используйте его, а не участвуйте в очередной компьютерной «религиозной войне». Ведь все равно убедить в чем-либо участников таких войн невозможно. Как выразился один из завсегдатаев компьютерного форума: «на свете нет ничего такого, что заставило бы нас отказаться от нашей системы программирования».

            Речь о другом. Когда-то в компьютерном жаргоне существовало грубоватое выражение «полировать глюкало». Это означало заниматься ерундой — продолжать улучшать и без того работающую программу. При этом программист никак не мог заставить себя прекратить это занятие, поскольку оно доставляло ему эстетическое удовольствие. Некоторые «полировали» неделями, срывая все сроки и вызывая истерику у заказчиков. А если нет срока сдачи программы, можно ли заниматься этим год? А десять лет? А двадцать пять? Ну, это вряд ли, разве что Вы какой-нибудь граф Монте-Кристо, имеющий в камере замка Иф только листинг одной программы. Да и граф, помнится, просидел всего-то 14 лет. Ну, а совершенствовать двадцать пять лет программу на ассемблере, созданную в 1982 году? Это совсем невероятно: и компьютерный мир был другим, да и какая из тогдашних программ имела бы сегодня практический смысл?

            Тем не менее, и такая программа нашлась, и такой программист (я) нашелся. Прежде всего, замечу, что 25 лет для процессоров не так уж и много. Ведь процессор 8086 выпущен еще в 1978 году, а 80386 — в 1985. Конечно, потом добавлялись команды вроде SSE2, но принципиальных изменений мало, даже 64-разрядные процессоры не сильно меняют картину. Так, что команды, написанные в 80-х, нормально выполняются и сегодня. А разбираться с командами, а не с текстом на языке высокого уровня пришлось потому, что исходный текст был недоступен. И уж конечно и в мыслях не было, что процесс совершенствования одной программы затянется на долгие годы. Это произошло постепенно, само собой. О результатах этого уникального эксперимента я и хочу рассказать и, думаю, вряд ли кому-нибудь удастся в ближайшее время повторить что-то подобное.

            В свое время мне сильно повезло: первая же серьезная программа, в которой я захотел разобраться, на примере которой учился программированию и которой в итоге занимаюсь почти 25 лет, была прекрасно написана выдающимся специалистом. Звали его Гарри Килдэлл. По логике вещей, он вполне мог бы оказаться на месте Билла Гейтса и, на мой взгляд, это было бы справедливее. Ну, уж как вышло — так вышло. Ходят слухи, что IBM в 1981 году просто ограбила Килдэлла, присвоив его операционную систему CP/M под именем MS DOS (и создав для этого подставную фирму MicroSoft). Любителям конспирологии есть, где разгуляться, тем более что сам Килдэлл погиб в 1994 году при неясных обстоятельствах. Но как бы то ни было, в силу многих и не всегда понятных причин одна из его прекрасных программ так и не нашла массового пользователя ни в 1982 году, когда она появилась, ни позже. Хотя, например, еще Петер Нортон писал положительный отзыв на эту программу для компьютерного журнала.

            В 1987 году эта программа досталась и мне вместе с компьютером IBM PC XT. Собственно в компьютере кроме MS DOS 3.0, текстового редактора SideKick и этой программы вообще больше ничего не было. А являлась эта программа транслятором с языка PL/1 подмножества «G» (подмножество общего назначения).

            Программистам старшего поколения не нужно объяснять, что такое PL/1 и чем он был в 70-80-ые годы. Жаль, что на «персоналках» все пошло кривым путем бейсиков и Си (но это я опять скатываюсь к «религиозной войне»). Одним из объяснений, почему PL/1 не прижился на персональном компьютере, было отсутствие транслятора. Дескать, язык такой сложный, что транслятор не поместится в памяти. Но, во- первых, транслятор для IBM/360 вообще «помещался» в 64 Кбайта (на самом деле он имел оверлейную структуру). А во-вторых, транслятор-то давно уже был, вот этот самый Digital Research PL/I-86 compiler!

            Сначала у меня ничего не получалось, несмотря на энтузиазм, с которым я взялся за изучение новой системы программирования (была отличная документация на английском). Сыпались непонятные ошибки, нельзя было писать по-русски даже комментарии, а системная библиотека была рассчитана на DOS 1.0. Поэтому я решил разобраться, как все устроено, исправить, что нужно и пользоваться. Но сначала получить текст транслятора как результат дисассемблирования. В конце 80-х без опыта и готовых средств это было очень не просто. Даже получить большую распечатку в виде книги в отсутствии лазерных принтеров было нелегким делом.

            Постепенно все стало налаживаться, выработалась и технология: на распечатке пишутся комментарии к понятым фрагментам, затем комментарии переписываются в файлы исходного текста. В конце концов, вся распечатка покрывалась пометками и засаливалась до такой степени, что приходилось создавать новую, разбирать которую было уже проще. Разгадывание оказалось увлекательным занятием, помню, радовался как ребенок, когда удавалось внести небольшое усовершенствование или просто найти ошибку в трансляторе. Кроме того, разбирательство с транслятором принесло огромную пользу в понимании свойств этого языка и языков вообще, их возможностей и даже замыслов их создателей. Я заметил, что количество ошибок и глупых решений в моих собственных программах сократилось. По мере накопления опыта стали возможными более существенные изменения, например, почему бы не использовать команды сопроцессора? Почему бы не вставить не реализованный оператор PUT DATA ? Каждая новая возможность транслятора немедленно применялась в программах, которые ту же переписывались под новые условия. В основном, я занимался инженерными расчетами и не чувствовал ни малейшей необходимости использовать другие системы программирования, которые наконец в начале 90-х в огромном количестве стали появляться и в нашей стране.

            Через несколько лет я с удивлением увидел, что на персональном компьютере PL/1 использую только я (и маленькая группа моих коллег), а остальные работают или на Си или на Паскале и даже не слышали о трансляторе с PL/1, а новое поколение программистов уже и не знает, что это за язык. Честно говоря, я не расстраивался по этому поводу, поскольку уже привык к сладкому вкусу независимости (считая, что программные средства будут работать так, как я сочту правильным, а не так как кто-то там уже сделал!). В это время стали возможны более сложные доработки: переход от 16 к 32 разрядам и от DOS к Win32. Нашлось и удобное время для продолжения работ с транслятором — длительная дорога на работу и обратно. Конечно, кому-нибудь это покажется ненормальным: ездить годами на работу и чуть не каждый день вертеть в руках одну и ту же распечатку. Но мои соседи по транспорту вообще постоянно решают бессмысленные «японские кроссворды» и им же не приходит в голову, что они просто теряют зря время.

            Постепенно для меня прояснилась и задача: я хочу создать «идеальный» транслятор, программу, где каждая из 29 тысяч команд проанализирована на предмет необходимости и простоты. Каждая команда (раз уж так вышло, что у меня текст только на ассемблере) должна получить правильный и внятный комментарий. Я постараюсь убрать все лишнее, а «освободившееся место» использовать для расширения возможностей транслятора. Я не буду ставить себе никакого конечного срока, т.е. никакая версия не является окончательной.

            Создание «идеального» транслятора не является обязательной работой, а скорее годится в рубрику «развлечения не без пользы». Только ошибки в программах по вине транслятора делают его анализ опять приоритетным. Внося расширения, буду стараться оставаться в рамках языка и дорожить тем огромным практическим опытом по использованию PL/1, который уже накоплен.

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

            Новый «исходный» текст, пусть и на ассемблере, дал возможность продолжить совершенствование транслятора с того места, на котором остановился Килдэлл, а иногда убирать шероховатости, оставленные разработчиками языка. Приведу несколько примеров. Как известно, «главная» программа на PL/1 начинается с заклинания PROC OPTIONS(MAIN). Смысл ключевого слова OPTIONS — в возможности задать параметры, относящиеся не к языку, а к «внешней среде». Это, например, начальный размер стека, который с точки зрения языка бесконечен. Но параметр MAIN как раз относится именно к языку, так же как, например, RECURSIVE или EXTERNAL . И они пишутся безо всякой OPTIONS . Я подправляю транслятор, чтобы MAIN можно было писать и так и так. Тексты старых программ менять не надо, зато в новых программах уже не надо вставлять надоедливую OPTIONS . Изменился ли язык? Формально да, а по сути лишь убрана маленькая «неровность» стандарта. В трансляторе это обошлось всего в несколько команд.

            Другой пример. После ключевого слова окончания процедуры или функции можно повторить ее имя. Например, F:PROCEDURE;… END F; Если имя указано — транслятор проверяет его на совпадение с именем в заголовке. Если не указано — транслятор ничего не проверяет. Теперь это правило легко расширяется и на циклы:
DO I=1 TO 100
DO J=1 TO 100;
DO WHILE(…);
…
END WHILE;
END J;
END I;
На мой взгляд, дух PL/1 сохраняется, а доработки транслятора просто ничтожны.

            Следующий пример. Разработчики PL/1 перенесли из Алгола «сложные» циклы, т.е. возможность менять в заголовке цикла сам закон изменения параметра, например, DO I=3,5,100, BY -1 TO 0; Признаком смены «формулы» цикла является запятая, а признаком конца всего заголовка — точка с запятой. Я, например, использую такие циклы вместо конструкции UNTIL , когда первую итерацию нужно выполнять всегда:
DO F2=F(X), WHILE(ABS(F1-F2)>EPS);
F1=F2;
X+=DX;
F2=F(X);
END WHILE;
            В трансляторе я решил довести до конца идею «сложных» циклов и разрешить смену не только закона изменения параметра цикла, но и самого параметра, например, вот задание прохождения по «квадратной» траектории:
Y=0;
DO X=0 TO 99, Y=0 TO 99, X=100 TO 1 BY -1, Y=100 TO 0 BY -1;
ПЕРЕМЕСТИТЬ(X,Y);
END;
            Здесь на самом деле 4 цикла с двумя параметрами и когда один параметр меняется, второй — «замораживается» и остается таким, каким был при выходе из предыдущего цикла.

            Подобных дополнений довольно много, но все они необязательны к применению да и, на мой взгляд, без чистки шероховатостей языка нельзя считать транслятор «идеальным».

            Теперь рассмотрим, чего удалось достичь с точки зрения эффективности кода, скорости трансляции и размеров «идеального» транслятора. Не думаю, что при современных средствах эти характеристики так уж важны, если, конечно, они не совсем безобразны. Но я их привожу, как пример, до чего можно «отполировать» программу за много лет.

            Начнем с наименее важной характеристики — размеров транслятора. Я все время стараюсь сделать его как можно меньше, просто потому, что это легко измерить, есть объективный показатель совершенствования. Я отдельно считаю размер команд и статических данных. Это пошло с давних пор, когда еще было необходимо втискивать команды «прохода» транслятора в 64 Кбайта. Сейчас сокращение на несколько байт не имеет смысла, но все равно приятно, когда при анализе находятся очередные лишние команды. На начало 2011 года размер команд «идеального» транслятора составляет 87091 байт, размер статических данных 182619 байт и, следовательно, весь размер транслятора 269710 байт.

            Я не пытаюсь установить мировой рекорд малости (да и транслятор Лиспа или Форта все равно будет меньше), но уверен, что немного найдется трансляторов с языка такого уровня таких же размеров. Сравните, например, хотя бы с размером файла с данной статьей. Причем, я вовсе не «зажимаюсь» с возможностями транслятора. Он может выдать и распечатку всех имен и результаты трансляции в виде ассемблера (хотя сразу генерирует готовый код объектного модуля) и даже раскрашивает сообщения об ошибках на экране. Т.е. многое можно было бы выбросить без ущерба для функциональности, но тогда какой же это будет «идеальный» транслятор, если нельзя получить, например, распечатку результата анализа в виде обратной польской записи? Для сопровождения это вовсе не роскошь, а необходимость. Несколько портит дело большой размер статических данных, но там львиную долю занимает один буфер внутренних операций (131072 байта). Когда-то он занимал лишь 256 байт, но изящно увеличить его удалось только до 65536 элементов по 2 байта каждый. Одно время я хотел все буфера выделять динамически, но затем махнул рукой. Практического смысла в экономии на данных нет, да и выполняемый модуль у меня один (он включает транслятор, редактор связей, библиотеки и т.п.) размером в полтора мегабайта. Зато для компактности большая часть других статических данных размещена как раз в этом буфере (к моменту его использования эти данные уже не нужны), а остаток места в буфере занимает довольно длинный текст описания ошибок при трансляции, выдаваемый на экран, как справочные данные.

            Обнаружилась любопытная вещь. Оказалось, что «скорость» совершенствования (в данном случае уменьшения размера команд) примерно постоянна уже много лет. Т.е. и здесь действует что-то вроде «первого закона Мура». Но значит, и здесь когда-нибудь сработает «второй закон Мура» - т.е. сокращения закончатся. Можно привести механическую аналогию — сжимание пружины. Увеличивая нагрузку можно заставлять пружину продолжать сжиматься. Но рано или поздно ее витки лягут друг на друга. Дальше можно лишь сломать пружину, но сжать ее больше не удастся.

            Немного запутывает дело тот факт, что в транслятор постоянно вносились и расширения, без них «скорость» сжатия была бы существенно выше.

            Следующей по важности (точнее, по неважности) характеристикой является скорость трансляции. Когда-то это был очень важный параметр. Помню, первая же более-менее объемная программа транслировалась на IBM PC XT минут шесть. Можно было сходить чаю попить. Конечно, я старался ускорить транслятор, но быстро возросшая скорость самих компьютеров обесценила эти усилия. К тому же мешает отсутствие объективного показателя скорости вроде размера в байтах для предыдущей характеристики. Дело не в том, что хочется засечь микро и наносекунды. Я бы предпочел иметь в процессоре специальную команду типа RDTSC, которая бы считала такты, если управление находится внутри заданного диапазона адресов, а вне этого диапазона такты не меняются. Тогда даже для небольшой конкретной процедуры можно было бы получать некий числовой показатель скорости и смотреть, как на него влияют изменения команд. А так, исправления нескольких команд, обычно никак не ощущаются на скорости работы всей программы. За неимением таких средств, для оценки скорости работы я просто делю объем транслируемой программы на время трансляции и на тактовую частоту процессора. Объем программы можно выразить в байтах или строках. Конечно, строка исходного текста, это очень субъективный показатель, зависящий от стиля программирования, но, тем не менее, почему-то часто принято оценивать объем программы именно в строках.

            На моем компьютере с обычным процессором Intel Core Solo CPU 1.33GHz все 40 модулей программы (моей основной работы) общим объемом 4479812 байт или 148423 строк транслируются за 6382 миллисекунды (время засекает сам транслятор). Это означает, что «идеальный» транслятор работает со средней скоростью 528 байт или 17 строк исходного текста в секунду на каждый мегагерц тактовой частоты процессора. Здесь, правда есть небольшой обман: это время не первой, а второй и последующих трансляций, когда файлы уже попали в кэш Windows. Небольшим обман я считаю потому, что перетрансляции у нас идут десятками с утра до вечера и то, что первая из них проходит медленней, практически незаметно. В указанный объем программы входят, естественно и заголовочные файлы, которые транслятор для каждого модуля разбирает заново, из-за чего объем текста всего проекта становится довольно большим.

            Не думаю, что такая скорость трансляции является рекордной, однако мы давно уже перестали обращать на нее внимание. И даже был анекдотичный случай трансляции небольшой программы, когда при вызове транслятора с опцией «сразу запустить полученную программу», происходила ошибка из-за того, что не успевали отпустить «Enter» и на клавишу реагировала уже оттранслированная и запущенная программа.

            Наконец рассмотрим практически единственно важную характеристику современных трансляторов - качество генерируемого ими кода. Но как раз качество кода однозначно оценить сложно. Для разных случаев могут быть разные критерии. Готов признать, что «идеальный» транслятор генерирует не идеальный, а обычный нормальный код. Без сверхсложных оптимизаций, но и без глупых команд типа LEA ESI,[ESI]. Транслятор имеет регистровую модель IA-32, пытается максимально использовать регистры и в сложных случаях распределяет их по алгоритму Биледи. Кстати, в моих прикладных программах до этого алгоритма почему-то дело никогда не доходит. Имеется и поиск часто встречающихся случаев. Поэтому и оператор X=X+1; и оператор X+=1 ; транслятор легко превращает в одну команду инкремента.

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

            Вот так выглядит исходный текст:
TEST:PROC MAIN;
DCL
(I,J,K) FIXED(31),
F ENTRY(FIXED(31),FIXED(31)),
X (100,100) FIXED(31);
DO I=1 TO 100;
DO J=1 TO 100;
F(I,J);
K+=X(I,J);
END J;
END I;
END TEST;
            Вот так выглядит часть программы в обратной польской записи:
…
IID 0 N 1 00 00 I
C4 0 N 0 00 00 #00000001
ILD 1 N 0 01 00
IAS 2 S 0 31 00
WHL 0 N 0 01 00
IID 0 N 1 00 00 I
ILD 1 N 0 31 00
C4 0 N 0 00 00 #00000064
ILD 1 N 0 07 00
ILE 2 N 0 01 00
DOW 1 N 0 01 00
LIO 0 N 1 64 00 N0008
LL4 0 N 0 07 00
FE
IID 0 N 1 00 00 J
C4 0 N 0 00 00 #00000001
ILD 1 N 0 01 00
IAS 2 S 0 31 00
WHL 0 N 0 01 00
IID 0 N 1 00 00 J
ILD 1 N 0 31 00
C4 0 N 0 00 00 #00000064
ILD 1 N 0 07 00
ILE 2 N 0 01 00
DOW 1 N 0 01 00
LIO 0 N 1 65 00 N0009
IID 0 N 1 00 00 I
NID 0 N 1 00 00 #01AEE89B
AST 2 N 0 00 00
            А вот, что получилось у транслятора в итоге:
1 000000 TEST:PROC MAIN;
2 000000 DCL
000000 TEST:
000000 B88C9B4002 mov eax,37788556
000005 E800000000 call ?START
3 00000A (I,J,K) FIXED(31),
4 00000A F ENTRY(FIXED(31),FIXED(31)),
5 00000A X (100,100) FIXED(31);
6 00000A
7 00000A DO I=1 TO 100;
00000A C7050800000001000000 mov I,1
000014 @1:
000014 833D0800000064 cmp I,100
00001B 7F4D jg @2
8 00001D DO J=1 TO 100;
00001D C7050C00000001000000 mov J,1
000027 @3:
000027 833D0C00000064 cmp J,100
00002E 7F32 jg @4
9 000030 F(I,J);
000030 BB589C0000 mov ebx,offset @00009C58h
000035 E800000000 call F
10 00003A K+=X(I,J);
00003A 693D0800000090010000 imul edi,I,400
000044 A10C000000 mov eax,J
000049 C1E002 shl eax,2
00004C 03F8 add edi,eax
00004E 8B8780FEFFFF mov eax,X+0FFFFFE6Ch[edi]
000054 010510000000 add K,eax
00005A FF050C000000 inc J
000060 EBC5 jmps @3
000062 @4:
000062 FF0508000000 inc I
000068 EBAA jmps @1
00006A @2:
11 00006A END J;
12 00006A END I;
13 00006A
14 00006A END TEST;
00006A E800000000 call ?STOPX
15 00006F
CODE 00006F
DATA 009C60
            Как видите, особых изысков нет, но и ужасным такой код назвать нельзя. Обратите внимание на способ передачи параметров I и J внутрь процедуры F через список адресов в памяти, а не через стек. Для рекурсивных процедур это замедляет работу, для не рекурсивных —… ускоряет. Здесь как раз видна противоречивость оценки качества кода. Например, для передачи параметров потребовалось 13 байт (5 байт — засылка адреса списка в EBX и 8 байт на сам список адресов в памяти). Если бы I и J передавались через стек, потребовалось бы всего 12 байт. Однако возврат из процедуры F в данном случае производится командой RET (1 байт), а в случае использования стека RET 8 (3 байта). Какие плюсы, какие минусы перевесят в каждом случае — совсем неочевидно.

            Так можно ли считать этот транслятор «идеальным»? Себе я отвечаю на этот вопрос положительно. Для доказательства и приведены характеристики, которые не получить без многолетней работы. Это буквально «вылизанное» средство, которое постепенно развивалось вместе с эволюцией компьютеров. Сразу такой транслятор создать было бы невозможно. Он уже сильно отличается от исходного: половина команд добавлена вновь, а вторая половина изменена (что ничуть не умаляет заслуг Килдэлла). Новые решения, которые теперь легко добавлять, я сам же проверяю на практике и ими вполне доволен. К тому же, всеохватность языка PL/1 позволила успешно применять его для самых разных задач. «Идеальным» оказался транслятор и для моего руководства: не требуются деньги на лицензионные средства или время на переучивание, а положительные результаты получаются.

            Не всегда транслятор оказывается «идеальным». Например, иногда к результатам его работы с подозрением относятся антивирусы, а программа, которая должна была установить защиту от копирования, вдруг выдала нелепое сообщение: «Ваша программа не предназначена для работы под Windows». Подозреваю, что их сбило с толку отсутствие в программах секции «text». Для тех, кто не знает: когда-то так «умно» назвали раздел EXE-файла, содержащий выполняемые команды. Просто здесь он называется ближе по смыслу: «PROGRM».

            Я с уважением отношусь к советским конструкторам, особенно оружейникам. Их труд и блестящие результаты являются вдохновляющим примером и настоящим, без иронии, идеалом, к которому нужно стремиться. И, на мой взгляд, есть что-то общее между трансляторами для программистов и оружием для военных. При такой аналогии мой транслятор, пожалуй, это пистолет Макарова. Это классическая схема, компактность, надежность и простота. Причем простота конструкции данного пистолета обманчива: за каждой деталью стоит огромный объем поисков и отработок. И статью я хочу закончить цитатой об этом оружии: «С современной точки зрения пистолет Макарова считается устаревшим оружием. Однако и сегодня (через 64 года после создания — прим. мое) он является единственным серийным пистолетом, проходящим [все] комплексные проверки».

Автор: Д.Ю.Караваев. 08.03.2011

Последняя правка: 2018-10-29    15:53

ОценитеОценки посетителей
   ██████████████████████████████████████████ 2 (100%)
   ▌ 0
   ▌ 0
   ▌ 0

Отзывы

     2018/09/22 10:02, Автор сайта

Если не секрет, на чём программируете сейчас, неужели по-прежнему на PL/I?

     2018/09/22 11:22, Д.Ю.Караваев

А по поводу PL/1 — да, используем и тоже, как говорится, «и в ус не дуем». Дело в том, что для инженерных задач он очень подходит. Многие вещи в нем и проще и эффективнее и, что очень важно, проверены на практике за очень долгий период.

Кроме этого, а может быть и главное в этом — это доступность транслятора для исправлений. Например, можно ввести новую систему типов: Типы в инженерных задачах, а можно захватывать максимальные ресурсы при выполнении программы: http://files.rsdn.org/122727/pl1ex22.doc

Так что, вполне себе рабочий язык для вполне себе актуальных задач. Незаслуженно и парадоксально получивший ярлык «дико сложного», притом, что нынешнее поколение программистов вообще считает предыдущее чем-то вроде дикарей с луком и стрелами. Честно скажу, за все время моей карьеры программиста никогда не возникало сложностей в части «как это выразить на языке». Все сложности всегда были по части «как найти решение этой задачи?». Поэтому программы на PL/1 постоянно и успешно работают на борту МКС.

     2018/09/22 12:00, Автор сайта

Для меня PL/1 — это такая далёкая история… Конечно, ПО — не скоропортящийся товар, но факт того, что PL/1 до сих пор работает на современной технике — это, конечно, для меня сюрприз. Про лук и стрелы — это Вы красочно живописали. А что ещё как из современного, так и из «древностей» в РКК «Энергия» используют? Просто любопытно.

Ваше письмо подтолкнуло меня к чтению Википедии насчёт PL/I :) Как правило, все языки имеют свой сайт: java.org, dlang.org, haskell.org, rust.org, golang.org. А вот про pl1.org в Википедии не пишут. Материалов про него мало.

     2018/09/22 12:42, Д.Ю.Караваев

У нас тоже была попытка создать сайт и даже имя было вполне удачное: http://pl1.su но по некоторым причинам он так и остался замороженым в начальной стадии.

Фраза про «лук и стрелы» попалась мне на одном из форумов. Вроде имелся ввиду АЛГОЛ.

РКК — большая организация, то и инструментальные средства используются самые разные. Наше подразделение чисто «прикладное», руководству всё равно, какими инструментами мы пользуемся. Не просим купить лицензионные продукты, успеваем за развитием возможностей компьютеров — ну и слава богу.В общем-то, PL/1, который для IBM/360, вместе с IBM/360 и ушел. А вот для X86 только жить начал после принятия стандарта ANSI X3.74 в 1987 году.

Ещё могу привести байку (на самом деле это правда), что вместе с первой экспедицией на МКС летел и компилятор с PL/1. Не было уверенности, что ПО связи заработает сразу как надо, да и пропускная способность была даже штатно очень слабая. Поэтому в аварийном случае рассматривался вариант: диктуем экипажу исправления в исходных текстах и перетранслируем на борту. К счастью, такая экзотика не потребовалась.

Напоследок компьютерная байка (к сожалению, забыл, у кого ее прочел). Почему PL/1 не вытеснил Фортран и Кобол.

В середине 60-х в американском компьютерном сообществе сложились две группы, условно «инженерная» и «экономическая». Одни использовали Фортран, другие — Кобол. К друг другу относились свысока, почти ненавидели (вроде фанатов ЦСКА и Спартака). При создании нового языка была мысль объединить преимущества каждого из языков в одном и, тем самым, объединить обе группы одним инструментом. Разработчики искренне верили, что программисты благосклонно воспримут новый язык, как следующую ступень развития, уж явно совершеннее и Фортрана и Кобола. В действительности получилось обратное. «Инженеры» возмутились, что в их прекрасный простой Фортран воткнули бухгалтерский ввод-вывод (в PL/1 имеется спецификация вывода дебета/кредита). А «экономисты» возмутились тем, что в их простой Кобол был вставлен целиком Фортран. В результате массового перехода на PL/1 не произошло. Фортран и Кобол продолжали оставаться основными инструментами. И только новое поколение в 70-х, уже не связанное этой «вендеттой» начали пользоваться новым инструментом. Уже искренне удивляясь, почему предыдущие поколения не признают преимущества этого языка, а видят только недостатки.

Такая вот непредсказуемая вещь — язык программирования.

     2018/09/22 14:11, Автор сайта

Интересно, какова степень Вашего авторства на данный момент? Это тот самый изначальный компилятор от главы Digital Research, который развивали и развивали и даже сделали 64-разрядную кодогенерацию? Или Вы на определённом этапе взяли и написали компилятор с нуля и это теперь на 100% Ваше детище? Думаю, ответ на этот вопрос будет интересен не только мне, но и читателям. А он вполне логичен, потому что вопрос авторства в Ваших статьях освещён не был.

     2018/09/22 15:33, Д.Ю.Караваев

Для меня вопрос непростой. Сначала формально нет, не разработчик. И такой задачи не ставилось.

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

Имея такой совершенный ассемблерный код, не вижу смысла переписывать с нуля, такого качества уже никому не достигнуть. С проблемой переносимости (с архитектуры x86 на другую) так и не сталкивался, скорее виртуальные машины появятся на всех архитектурах для всех архитектур.

     2018/09/22 16:21, Автор сайта

В целом получается, что и да и нет: и разработчик, и не разработчик.

Но если Вы хотите внести свой транслятор в перечень отечественного ПО, то вопрос об авторских правах надо как-то надо решать.

Имея такой совершенный ассемблерный код, не вижу смысла переписывать с нуля, такого качества уже никому не достигнуть.

Почему имеет смысл — хотя бы полностью очиститься в вопросе авторских прав :) Но есть другой аспект: если Вы хотите, чтобы Ваш транслятор достался потомкам на века, есть смысл написать его на более понятном языке, нежели ассемблер. Это более лёгкая поддержка — не для Вас, а для потомков. Как вариант, можно переписать транслятор PL/1 на самом PL/1 — дополнительная проверка транслятора.

С проблемой переносимости (с архитектуры x86 на другую) так и не сталкивался

Может, я и не прав, но как мне кажется, что архитектура ARM куда более практична для космоса и вообще бортового оборудования: она энергоэффективнее, на каждую единицу потреблённой электроэнергии приходится наибольшее количество выполненных команд. Архитектура MIPS тоже неплоха в этом плане. И неплохо было бы иметь кодогенератор для LLVM. Но это я сужу со своей колокольни. Вам куда виднее :)

     2018/09/22 17:36, Д.Ю.Караваев

Но раз Вы хотите внести свой транслятор в перечень отечественного ПО, то вопрос об авторских правах надо как-то надо решать.

А стоит ли беспокоиться? Исходный продукт вышел 34 года назад в виде 16-разрядного продукта для MS-DOS 1.0 (для MS-DOS 3.0 уже были нюансы). Он до сих пор доступен в сети под именем PL/I-86. Его потомок генерирует очень отличный от исходного код и совсем для другой среды. Да и международная обстановка облегчает вопросы о правах :)

Если Вы хотите, чтобы Ваш транслятор достался потомкам на века, есть смысл написать его на более понятном языке, нежели ассемблер. Это более лёгкая поддержка — не для Вас, а для потомков. Как вариант, можно переписать транслятор PL/1 на самом PL/1 — дополнительная проверка транслятора.

Будучи представителем действительно универсального языка, тем не менее, я скептически отношусь к таким вещам как «раскрутка компилятора». Вспоминается шутка 90-х: «транслятор с Паскаля нужен, чтобы писать на нем трансляторы с Паскаля». У меня нет ни физических, ни моральных сил переписывать транслятор, особенно учитывая, что сразу на порядок просядет эффективность и быстродействие. Тем более что две трети транслятора занимает генерация x86, т.е. все равно привязка к командам. Дополнительная проверка транслятора — слабая плата за переписывание. Гораздо эффективнее получаются проверки, когда мы находим нового программиста. В его исходных текстах обязательно найдется что-то неожиданное :)

А работу на века обеспечат виртуальные машины. Мне кажется, они раньше закроют все потребности, чем договорятся о едином промежуточном коде вроде LLVM.

Может, я и не прав, но как мне кажется, что архитектура ARM куда более практична для космоса и вообще бортового оборудования: она энергоэффективнее, на каждый ватт электроэнергии приходится наибольшее количество выполненных команд. Архитектура MIPS тоже неплоха в этом плане.

Будучи сторонником универсального языка, я являюсь и сторонником CISC-команд. В защиту таких команд приведу шуточную аналогию. Знаете ли Вы, что в соревнованиях по плаванию теперь есть специальный судья, который следит за тем, чтобы пловцы после стартового прыжка вынырнули ДО середины бассейна? Так как под водой, понятно, они движутся быстрее. При чем здесь CISC ? А они, набрав себе операндов, тоже «ныряют» вглубь кристалла. И пусть действуют там как можно дольше "не барахтаясь на поверхности", т.е. не обращаясь к медленной памяти. Предельный случай — квадратный корень или тригонометрия в FPU. Вы можете написать свою функцию корня, никаких особых, волшебных команд внутри FPU нет, но он все равно сработает быстрее, поскольку не надо читать команды и обращаться к памяти за данными.

RISC команды работают быстрее, но быстрее ли программы из RISC команд? Это не факт, учитывая, что кристаллы все быстрее и быстрее, а память все отстает и отстает. Архитектура, где любая команда может стать командой перехода, сложна в конвейеризации и выделении линейных участков программы.

Но это я сужу со своей колокольни. Вам куда виднее :)

Да я тоже не господь бог. Сейчас наши программы работают на МКС на обычных ноутбуках под Windows. Ну и одна на контроллере AT90S2313. Особой «космической» специфики здесь нет.

     2018/09/22 18:41, Автор сайта

А стоит ли беспокоиться? … Да и международная обстановка облегчает вопросы о правах :)

Да уж… У нас есть очень хороший рычаг — угроза пересмотра договоров об авторских правах :)

Гораздо эффективнее получаются проверки, когда мы находим нового программиста. В его исходных текстах обязательно найдется что-то неожиданное :)

Вы меня удивили! Даже не подумаешь о подобном. Надо взять себе на заметку :)

RISC команды работают быстрее, но быстрее ли программы из RISC команд? Это не факт, учитывая, что кристаллы все быстрее и быстрее, а память все отстает и отстает. Архитектура, где любая команда может стать командой перехода, сложна в конвейеризации и выделении линейных участков программы.

Да я не про скорость, а про энергоэффективность. Фигурально выражаясь, на вычисление квадратного корня х86 тратит 10 джоулей, а ARM — 1 джоуль. А в космосе (да и вообще, в бортовых системах) — каждый киловатт-час на счету.

 Сейчас наши программы работают на МКС на обычных ноутбуках под Windows.

Значит, там всё неплохо с энергоснабжением :)

Ещё мысль про «очистку» авторских прав. Транслятор PL/1, который вы долго «допиливали», был изначально написан, скорее всего, на Си или на чём-то подобном. Но не на ассемблере. А раз так, то Вы можете предъявить миру текст на ассемблере, а вот наследники Килдэлла если что-то и предъявят, так это текст на Си. И даже после трансляции тексты на 90% будут несовпадающи. Когда-то в далёкие советские времена рассказывали случаи из жизни «загнивающих»: два программиста спорили в суде насчёт авторских прав на одну и ту же программу. Выиграл суд тот, который смог показать суду лишние команды, внесённые в программу специально как тайнопись.

     2018/09/22 20:13, Д.Ю.Караваев

Значит, там всё неплохо с энергоснабжением :)

Каждый ватт экономят на спутниках. Здесь все-таки другие масштабы. Кроме этого, это т.н. «компьютеры экипажа». Поэтому взята обычная и привычная среда и техника, а не что-то специальное.

Транслятор PL/1, который вы долго «допиливали», был изначально написан, скорее всего, на Си или на чём-то подобном. Но не на ассемблере.

Транслятор Килдэлла был написан на PL/M. Это нечто среднее между ассемблером и Си.

Поскольку я не собираюсь продавать транслятор в Америке, думаю до суда не дойдет. Кстати, жена Гарри умерла в 2002, насколько помню, у него сын и дочь. А тексты после многолетней «полировки» не совпадают на 100%. Т.е. вообще ничего общего при похожей функциональности.

Написать отзыв

Написать автору можно на электронную почту mail(аt)compiler.su

Авторизация

Регистрация

Выслать пароль

Карта сайта


Каким должен быть язык программирования?

Анализ и критика

Описание языка

Компилятор

Отечественные разработки

Cтатьи на компьютерные темы

Двадцать тысяч строк кода, которые потрясут мир?

Почему владение/заимствование в Rust такое сложное?

Масштабируемые архитектуры программ

Почему Хаскелл так мало используется в отрасли?

Бесплатный софт в мышеловке

Исповедь правового нигилиста

Русской операционной системой должна стать ReactOS

Почему обречён язык Форт

Программирование без программистов — это медицина без врачей

Электроника без электронщиков

Статьи Дмитрия Караваева

●  Идеальный транслятор

●  К вопросу о совершенствовании языка программирования

●  О реализации метода оптимизации при компиляции

●  О реализации метода распределения регистров при компиляции

●  О распределении памяти при выполнении теста Кнута

●  Опыты со стеком или «чемпионат по выполнению теста Кнута»

●  Сколько проходов должно быть у транслятора?

●  Чтение лексем

●  Экстракоды при синтезе программ

●  Об исключенных командах или за что «списали» инструкцию INTO?

●  Типы в инженерных задачах

●  Непрерывное компилирование

●  Об одной реализации специализированных операторов ввода-вывода

●  О русском языке в программировании

●  Формула расчета точности для умножения

●  Права доступа к переменным

●  Скорость в попугаях

●  Крах операции «Инкогнито»

●  Предопределенный результат

Компьютерный юмор

Прочее

Последние комментарии

2018/11/12 14:18 ••• Попов Михаил
✎ Программирование без программистов — это медицина без врачей

2018/11/11 23:39 ••• Автор сайта
✎ Изменение длины объекта в стеке во время исполнения

2018/11/11 14:29 ••• Александр Коновалов aka Маздайщик
✎ Помеченные комментарии

2018/11/11 14:01 ••• Александр Коновалов aka Маздайщик
✎ Нерабочий код

2018/11/11 13:39 ••• Александр Коновалов aka Маздайщик
✎ О русском языке в программировании

2018/11/11 12:57 ••• Александр Коновалов aka Маздайщик
✎ Об одной реализации специализированных операторов ввода-вывода

2018/11/03 22:43 ••• rst256
✎ Непрерывное компилирование

2018/11/02 23:23 ••• Неслучайный читатель
✎ Сколько проходов должно быть у транслятора?

2018/11/01 19:10 ••• Автор сайта
✎ Об исключенных командах или за что «списали» инструкцию INTO?

2018/10/31 06:01 ••• kt
✎ Чтение лексем

2018/10/30 18:30 ••• Александр Коновалов aka Маздайщик
✎ Экстракоды при синтезе программ

2018/10/29 13:17 ••• Автор сайта
✎ Каким должен быть язык программирования?