Опять о языках, точнее, - об одном языке

18 июль, 2007 - 11:44Андрей Зубинский
Ещё точнее, - о несуществующем языке.
 
Я люблю C. Потому что это действительно хороший язык (хоть и ужасный, конечно). И очень много кто ещё любит C – иначе бы сегодня не было столько разных производителей С-компиляторов для столь разных платформ (от 8-битовых контроллеров до 256-битовых спецвычислителей). C пережил многие языки, которые некогда считались панацеей от всех болячек. C пережил легенду под названием Ada – уже и программное обеспечение пассажирских самолётов (можете представить себе степень надёжности, требуемую в этой области) мирового класса пишут на C, вот свидетельство:
C пережил Lisp, Prolog и Smalltalk – сейчас эти языки существуют, но ничего значимого на них давно уже не пишется (в сравнении с пишущимся на C).
Итак, C прожил долго, счастливо, и будет жить ещё долго. Потому что он нужен, платформенно-независимый высокоуровневый ассемблер, он очень нужен. Но если смотреть на С именно как на ассемблер обобщённой вычислительной машины традиционной архитектуры, есть некоторые претензии.
Мне лично бы хотелось, чтобы в высокоуровневом ассемблере были как минимум две конструкции, отсутствующие в C: суффикс, ключевое слово at и суффикс, ключевое слово when.
at позволяет указать физический адрес размещения объекта в памяти, например:
volatile unsigned int PORT_A at 0x0002 ;
что значит – слово (размер – unsigned int для целевой платформы), расположенное по адресу 0x0002,  является отображённым на память регистром порта ввода-вывода A. Подобных регистров в самых разных архитектурах необъятное количество.
Ключевое слово when, по сути, являющееся модификацией at и относящееся исключительно к функциям. Оно позволяет задавать обработчики прерываний без обращения к ассемблерному коду:
void Signal_From_Gyro( void ) when INT_11 ;

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

В принципе, можно обойтись и без when, только c at, но в таком случае программист будет вынужден городить ещё больше низкоуровневого машинно-зависимого кода в тех случаях, когда с этой задачей прекрасно может справиться генератор кода компилятора.

Ещё хотелось бы, чтобы серьёзно «прошерстили» последний стандарт языка, выловили все оставленные на откуп разработчикам конкретных реализаций компиляторов неоднозначности (ведь многие из них тянутся со времен Кернигана и Ричи), и постарались от них избавиться. Причем так, чтобы грамотный прежде написанный код всегда работал. Во многих случаях это возможно.

Например, жёсткое правило, что при операциях присваивания (lvalue = rvalue) сначала генерируется (и исполняется) код вычисления rvalue, затем – код вычисления lvalue, и только после этого выполняется собственно присваивание, устраняет много мелких семантических пакостей (и никак не влияет ни на эффективность генерируемого кода, ни на исполнимость написанного ранее – потому что из-за неоднозначности в нынешнем стандарте языка такой код «с нюансами» заслуженно считается неправильным).

Вообще, неплохо было бы создать гибрид семантики современного алголоподобного языка (Modula-2 или Oberon-1), самой приятной части C-синтаксиса и, непременно, - адресной арифметики, - получилось бы очень «вкусно».
По-моему, Никлас Вирт мог бы создать язык действительно взрывной популярности, если бы пошёл по этому пути. Кстати, -  совершенно необязательно делать такой язык объектно-ориентированным, хоть бы и в минимальной степени (как Oberon-2). Причина одна – для объектно-ориентированных языков крайне трудно создавать верификаторы.
Ну а насчёт функциональных языков… Системы управления реального времени, где сейчас царит C – область volatile-переменных и обработчиков прерываний. Чистым функциональным языкам эти понятия – как серпом по… А сложные абстрактные построения, которые призваны устранить это отчуждение изящной чистой математики от безобразной реальности, сами по себе настолько безобразно уродливы (как те же монады), что уж лучше возиться с императивным ассемблером. Было бы иначе – разработчики ПО Airbus предпочли бы функциональный стиль - уж они-то своё дело знают, будьте уверены.