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

Не поминайте всуе PL/1

Люди, которые не знают PL/1 и поминают его не к месту, очень раздражают нас — тех, кто знает PL/1.

извлечено с компьютерного форума

Да, действительно раздражает. Вот, например, упоминание в типичной и далеко не новой статье на Хабре от 3 декабря 2012, «Ликбез по типизации в языках программирования».

Преобразования в неоднозначных ситуациях и преобразования с потерей данных — это очень, очень плохо. Ничего хуже этого в программировании нет. Если вы мне не верите, изучите язык PL/1 или даже просто поищите его спецификацию. В нем есть правила преобразования между ВСЕМИ типами данных! Это просто ад!

После слова «ВСЕМИ» еще не хватает трех восклицательных знаков, и тогда на этом накале пафоса уже можно было бы жарить картошку.

Автор статьи не знает, что в PL/1 есть переменные (т.е. данные) типа метка, типа файл, типа процедура, типа указатель, наконец, и всех их нельзя преобразовать. Ах, я придираюсь, оказывается, автор имел в виду только числа и строки? Тогда зачем писать про «между всеми» и про ад? Как говорится, во-первых, не из табакерки, а, во-вторых — не лысый чёрт! На мой взгляд, к аду гораздо ближе языки, где, например, символ «плюс» означает и арифметическое действие, и склейку строк. Вот там бывают веселые преобразования.

Но это старая статья, а вот в свежей статье от 25 ноября 2020 с названием «от Фортрана до Питона» Андрей Терехов пишет:

Американцы озлобились, когда в Европе появился Алгол-60, и сделали PL/1… Кошмарный язык! Сотни автоматических преобразований типов в другие типы. Как говорили, язык-оболочка. Несколько сот операторов: на любой чих отдельный оператор — кто их все запомнит? Тем не менее, этот язык стал довольно популярным и в СССР, поскольку появились ЕС ЭВМ. Я писал на нем, но тоже кошмарики случались. Опишешь в одной процедуре глобальную переменную А bin fix (целое), а в другой переменную А bin float (с плавающей точкой). Потом будешь долго искать ошибку — транслятор ничего не скажет

Вроде знающий и уважаемый человек. Пишет странное. Язык не поворачивается сказать, что пишет ерунду. Во-первых, PL/1 появился не по злобе на Алгол-60, а как его прямое продолжение. Да, именно он прямой потомок, а не Паскаль (выкидыш Алгола-68). Достаточно сравнить семантический разбор в трансляторах Алгола и PL/1 — ровно один и тот же набор основных структур: блочная структура, присваивание, условие, вызов, цикл, ввод-вывод. И никакой злобы.

Во-вторых, непонятно, что за «сотни операторов на любой чих» имеются в виду. Встроенные функции? Ну не пользуйтесь, изобретайте свои. Можно даже с точно такими же названиями, блочная структура языка это позволяет. По мне, так лучше использовать имеющиеся в языке (и в нормальной документации), как появившиеся в результате практической работы и придуманные опытными людьми. Да и ошибок с типами операндов будет меньше, ведь встроенные функции уже предусматривают операнды разных типов. Как их все запомнить? А тысячи разных функций из библиотек как запомнить? А здесь всего-то, несколько десятков (например, 84 штуки в PL/1-KT, включая всякие гиперболические тангенсы), а вовсе не сотен.

И, в-третьих, непонятно насчёт глобальных переменных. Глобальные переменные должны описываться в файле исходного текста один раз во внешнем блоке, на то они и глобальные, видны везде, повторять описание во всех процедурах не нужно. А если совсем в другом файле другая глобальная переменная вдруг с тем же именем оказалась — так сам себе злобный Буратино. В этом случае к компилятору-то (и к языку) какие претензии? Откуда он узнает, что этот другой файл — оказывается продолжение общего проекта и он (компилятор) когда-нибудь его тоже будет транслировать. Тогда уж претензии должны быть к редактору связей. И вообще-то есть специальные утилиты типа LINT для проверок глобальных переменных и типов операндов процедур из разных модулей.

Еще одно вздорное упоминание языка — это обвинение, что «любой текст (вариант: рассыпанная и случайно перетасованная колода перфокарт) считается программой на PL/1 и компилятор начнет его разбирать, хе-хе». Любой компилятор (кроме транслятора Дракона?) читает исходный текст посимвольно и, конечно, ему нужно прочитать несколько символов, прежде чем понять, что этот текст — не программа. В этом смысле PL/1 ничем не отличается и не выделяется из других: правильный текст должен строго начинаться или со слова BEGIN с точкой с запятой или с метки с двоеточием, за которым следует слово PROCEDURE, иначе это не PL-программа. Возможно, здесь ноги растут из неудачного решения разработчиков IBM-транслятора, когда на любую ошибку сразу выдается максимум информации о программе, включая таблицу встроенных функций. Это могло вызвать оторопь у новичка, когда на неправильно введенную колоду карт, он получал несколько листов распечатки ненужных ему данных.

Таким образом, большая часть упоминаний PL/1 обычно идет как негативный пример неудачного языка, при этом часто безосновательно его упоминают люди или вообще не имевшие с ним дела или имевшие, но очень давно, в другую компьютерную эпоху. Например, обсуждая обработку исключений, начинают вдруг вспоминать с какой версии Си/Си++ исключения появились в языках. Казалось бы, вот тут-то и упомянуть бы PL/1 как пионера в этой области, но нет. Справедливости ради, бывают, конечно, и упоминания в положительном ключе, когда вспоминают, например, удобный отладочный оператор PUT DATA или работу с битовыми строками, не требующую применять булеву алгебру к числам.

А что, разве у PL/1 нет недостатков и их нельзя вспоминать? Конечно, есть и можно, ведь язык появился более полувека назад, когда многие очевидные теперь вещи были совсем неочевидны, да и возможности взаимодействия с компьютером по сегодняшним меркам были чрезвычайно слабы. Тогда эта слабость заставляла тратить большие силы на ерунду вроде режима трансляции программы «до конца», даже при наличии ошибок или уже упомянутой выдачи программисту огромного объема данных при единичной простейшей ошибке.

Лично мне досадно, что с появлением персональных компьютеров, общее развитие программирования вдруг просело с уровня Алгола-PL/1 до уровня Си-Бейсика-Паскаля и ему потребовалось лет 10, чтобы опять достичь уровня, с которого можно было стартовать еще с начала 80-х. Напомню, что небывалая популярность IBM PC (появились в 1981 году, когда другие ПК уже были) во многом была связана с маркой, с престижем, с трендом: «у меня на столе стоит целый IBM!». Какой бы язык выбирали новички, если бы тогда имелась возможность богатого выбора? Ну, разумеется, тоже самый престижный: «язык языков», «язык профессионалов из ИБМ», т.е. тот самый PL/1. И ведь транслятор для ПК был уже почти готов. Но некрасивая история с участием Гарри Килдэла с одной стороны, и Билла Гейтса и IBM с другой, поставила крест на массовом внедрении PL/1 на персоналках. А поскольку число мэйнфреймов и их пользователей быстро сокращалось, язык потерял актуальность и постепенно (и несправедливо) превратился в пугало, обросшее мифами и анекдотами.

Могу привести анекдот, высмеивающий большое число ключевых слов в языке: «вчера разговаривал на улице с негром, используя словарный запас языка PL/1». Ну да, число ключевых слов в языке, пожалуй, побольше, чем в словаре людоедки-Эллочки. Да и то, не астрономическое число. В том же PL/1-KT в 128 штук помещаются все, включая экзотические составные операторы типа «не больше» (^>) и «не меньше» (^<). Это раза в 4 больше, чем слов в Паскале. Но при этом значительной частью этих слов можно никогда в программах не пользоваться и даже не знать об их существовании и поэтому называть так свои переменные (как в каламбуре IF THEN=ELSE THEN ELSE=IF;)

Еще одно дежурное обвинение языка в «не ортогональности», т.е. возможности выполнить одно и то же требуемое действие разными средствами языка. Но ведь, например, и русский язык «не ортогонален», как и другие языки, он имеет большое число синонимов, а не строго соответствие одному понятию одного слова. Частично это объясняется разными оттенками смысла, но в большей степени объясняется тем, что язык использует очень большое число очень разных людей. Применительно к языку программирования, на мой взгляд, тоже должна быть некоторая свобода выбора, поскольку программисты — тоже люди очень разные. Строго «ортогональный» язык заставляет думать всех программистов исключительно «в ногу». Для простых и типовых задач это, вероятно, хорошо, но для сложных — снижает вероятность появления оригинальных и эффективных алгоритмов.

И, напоследок, о том, что даже упоминание всуе может иногда принести пользу, т.е. возвращаясь к примеру А. Терехова с глобальными переменными. Я проверил, действительно такой ляпсус был и в компиляторе PL/1-KT. Это связано с блочной структурой. При разборе описаний каждое имя проверяется на уже такое же, встретившееся в данном блоке. Тогда это ошибка типа «уже было». Но в других блоках точно такое же имя может быть у другого объекта — в этом и состоит «блочная» видимость. Вот при таких проверках и забыли про проверку на атрибут глобальности «EXTERNAL», который как раз «ломает» блочность. Такая проверка вводится легко, но я решил кроме этого еще обобщить поиск сомнительных мест: если в объемлющем блоке есть точно такое же имя с атрибутом «EXTERNAL», то сразу выдавать предупреждение, даже еще не разбирая атрибуты текущего имени. Формально ошибок здесь нет, но если это точно такой же объект, то его описание можно просто убрать — ведь этот же объект уже виден «сверху». А если это другой объект и без атрибута «EXTERNAL», то странно, что уже есть точно такое же, да еще глобальное имя. Лучше обратить внимание программиста на потенциальную опасность ошибки.

При этом многие компиляторы неудовлетворительно работают с предупреждениями, т.е. сообщениями, которые не меняют генерацию кода. Обычно можно только их отключить, так как при большом количестве, на них перестают обращать внимание. В PL/1-KT применен другой подход. С каждым предупреждением можно разобраться отдельно, и, если, в данном случае так и было задумано (ошибки нет), можно, так сказать, закомментировать данный фрагмент исходного текста от выдачи предупреждений с помощью указания прямо в тексте специального ключа. Тогда при изменении текста программ выдаются только новые предупреждения

А при очередном упоминании PL/1 у меня часто возникают ассоциации с упоминанием СССР в современных (да и в старых) буржуазных СМИ: обязательно с негативным оттенком, реальный или вымышленный недостаток преувеличен до искажения. И большинство людей возразить не может, поскольку о предмете личного мнения и опыта не имеет.



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

Опубликовано: 2020.12.12, последняя правка: 2020.12.12    15:24

Оцените

Отзывы

     2020/12/12 16:02, Автор сайта          # 

Когда появился PL/1? Всего лишь 20 лет после ENIAC! Это сейчас легко критиковать PL/1. А вот попробовали бы критиковать его в то время. С чем тогда его можно было сравнивать? С Фортраном, Коболом, Лиспом, APL. Алголом. Вот, пожалуй, и всё. Тогда не только языков, но и программистов было в тысячи раз меньше. В тысячи (если не в миллионы!) раз меньше было опыта и научной базы. Не даром говорят: «Не критикуйте родителей. Они выросли без Гугла и Википедии».

Да, некоторые вещи в PL/1 архаичны. Однако нельзя сказать, что «он первый начал». Если хотим критиковать «goto», то надо вспоминать Фортран, а не PL/1, потому что Фортран первый ввёл в практику «goto». Не нравится многословные операторы? Претензии надо адресовать в первую очередь к Коболу. И тогда на долю PL/1 остаётся не так уж и много критики.

     2020/12/18 16:04, Автор сайта          # 

Вспомнил некоторые не очень известные факты о PL/1:
  • PL/1 был первым языком, использующим /* */ для комментариев.
  • Это был первый язык, который использовал нотацию -> для указателей.
  • PL/1 был первым языком, который использовал термин «статический» для хранения переменных, не связанных со стеком.
  • PL/1 был первым языком высокого уровня, используемым для написания операционной системы (Multics).
  • Это был первый язык, который обрабатывал исключения на основе стековых фреймов (называемых «условиями», т.е. condition).
Так что мы в чём-то обязаны этому языку. Надо не забывать о его вкладе в жизнь программистов.

Добавить свой отзыв

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

Авторизация

Регистрация

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

Карта сайта


Содержание

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

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

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

Компилятор

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

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

●  Концепция владения в Rust на примерах

●●  Концепция владения в Rust на примерах, часть 2

●●  Концепция владения в Rust на примерах, часть 3

●  О неулучшаемой архитектуре процессоров

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

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

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

●  О создании языков

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

●  Программирование исчезнет. Будет дрессировка нейронных сетей

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

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

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

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

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

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

●  Программисты-профессионалы и программирующие инженеры

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

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

●●  В защиту PL/1

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

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

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

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

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

●●  О размещении переменных в стеке

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

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

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

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

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

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

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

●●  Особенности реализации структурной обработки исключений в Win64

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

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

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

●●  Заметки о выходе из функции без значения и зеркальности get и put

●●  Модификация исполняемого кода как способ реализации массивов с изменяемыми границами

●●  Ошибка при отсутствии выполняемых действий

●●  О PL/1 и почему в нём не зарезервированы ключевые слова

●●  Не поминайте всуе PL/1

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

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

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

●●  Поддержка профилирования кода программы на низком уровне

●  Следующие 7000 языков программирования

●●  Что нового с 1966 года?

●●  Наблюдаемая эволюция языка программирования

●●  Ряд важных языков в 2017 году

●●  Слоны в комнате

●●  Следующие 7000 языков программирования: заключение

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

Новости и прочее




Последние отзывы

2021/01/21 00:00 ••• alextretyak
Концепция владения в Rust на примерах, часть 3

2021/01/21 00:00 ••• alextretyak
Выбор кодировки для компилятора

2021/01/20 00:10 ••• Автор сайта
Признаки устаревшего языка

2021/01/17 23:15 ••• Бурановский дедушка
Изменение длины объекта в стеке во время исполнения

2021/01/16 22:47 ••• Автор сайта
Предложения и замечания

2021/01/11 17:51 ••• Автор сайта
Утилита транслитерации русского C/C++ в стандартный

2021/01/09 18:08 ••• kt
Типы в инженерных задачах

2021/01/06 15:34 ••• Автор сайта
О неулучшаемой архитектуре процессоров

2020/12/18 16:04 ••• Автор сайта
Не поминайте всуе PL/1

2020/10/30 15:33 ••• Бурановский дедушка
Указатели и ссылки в C++

2020/10/29 15:02 ••• kt
Экстракоды при синтезе программ

2020/10/08 23:00 ••• Автор сайта
Короткие комментарии

2020/10/07 17:34 ••• NuShaman
Энтузиасты-разработчики компиляторов и их проекты

2020/10/05 23:19 ••• Неслучайный читатель
Обработка ошибок