На Хабре регулярно проскакивают статьи с идеями совершенствования процесса программирования. Но все они нацелены на улучшение языка программирования, чтобы он наиболее точно отражал особенности предметной области, то есть развитие состоит в надстройке более высокоуровневых абстракций. Другое направление - графическое представление ЯП или другие способы сделать ЯП нативным.
Все направления сконцентрированы на исходном коде, который (когда уже готов) ясный, понятный, выполнимый, строгий, однозначный.
Я же обратил внимание, что не все на исходном коде помешалось. Были сложные трудновоспроизводимые умозаключения, мысленные эксперименты, переборы и в итоге вырисовалось следующее: программист не работает с исходным кодом целиком, он постоянно абстрагируется, на экране отображается не исходный код, а его часть. Фредерик Брукс со своей несуществующей серебряной пулей ошибался: программисту не страшна сложность, так как он постоянно и успешно декомпозирует задачу. Декомпозиция - это частный случай абстракции, если угодно, кросс-абстракция - когда задача бьётся на подзадачи и потом подзадачи решаются по отдельности, от остальных подзадач абстрагируются.
Абстракция, абстракция, абстракция... Я понял, что нам не хватает абстракции в языках программирования. Это и есть серебряная пуля. Нужно научиться правильно абстрагироваться, то есть отбрасывать ненужное и оставлять нужное. Тут на форуме правильно отметили: все зависит от задачи разработчика, которую он пытается решить с кодом (написание кода, добавление новой функциональности, рефакторинг, локализация ошибки, изучение кода/алгоритма).
На данном этапе я наивно предполагаю, что все задачи разработчика сводятся к системному подходу, когда необходимо определить границу системы, то есть ее входы и выходы. Выглядит логичным.
Я обратил внимание, что границы систем уходят за пределы кода. Тут я ввел понятие "окружение кода". Это внешние библиотеки, компилятор, операционная система, железо.
Теоретически границы проектируемой системы могут выходить очень далеко за пределы компьютера и могут включать в себя социальные системы, экономические, политические... Это все системология... Граничные элементы рассматриваемой системы я называю терминалами (конечными остановками). Имеется очень важный набор
стандартных терминалов, которых достаточно большинству разработчиков.
- Экран (дисплей)
- Аудиоколонка
- Принтер
- Сканер
- Клавиатура
- Мышь (короче, стандартная периферия)
- USB-порт
- Ethernet-порт
- Базы данных
- Файловая система
- Операционная система
Разработчик работает лишь с переменными и функциями (данным и кодом), а взаимодействие с терминалами происходит опосредованно через функции системной библиотеки, API операционной системы, через события.
Часто несоответствия и требования идут из дальнего окружения (окружение за пределами терминалов). "Неправильно выводится сумма счета". "Выскакивает сообщение об ошибке обращения к памяти". И так далее.
В существующих IDE разработчик на основании своего опыта определяет связи между кодом и терминалами. Например, он знает, что на изображение на экране влияют системные функции printf(), cout, объекты семейства системных классов GraphicObject и др. Ему не стоит труда (точно без труда?) найти ошибку в программе, зная формулировку ошибки в терминах терминала.
Однако эти связи можно описать кратко на абстрактном языке и избавить голову разработчика, а во многих случаях обеспечить поддержку отслеживания связи в автоматическом режиме.
Разработчик указывает терминал "экран" в качестве Y-границы, X-граница автоматически указывает на функции printf(), cout, объекты GraphicObject, используемые в коде. Правее границу X двигать нет смысла, так как код программы полностью выпадет из рассмотрения, но влево ее сдвигать можно. Этот XY-навигатор просто получится чудесным!
И вот тут стоит кропотливая задача описания на абстрактном языке всех систем, которые лежат между стандартными терминалами и кодом. Туда попадают операционные системы, компиляторы, системные библиотеки, протоколы, железо. Описание должно быть максимально сжатым, эта задача в общем-то вынесена в заголовок темы.
Абстрактное описание связи между выводом printf() и терминалом "экран" будет безумно простым (ниже приведено абстрактное описание stdio.h):
Код:
... printf(...);
terminal display = abstract(printf().parameters);
Абстрактное описание гласит: "мол, есть такая функция printf() в stdio.h, которая влияет на отображение на экране.". Такое описание позволит успешно работать XY-навигатору с терминалом "экран".
Я пока не придумал, как иначе обратиться к параметрам функции, по всей видимости, для некоторых языков придется вводить подобные абстракции, ничего в этом запретного нет.
Я фактически предлагаю computer aided abstraction (поддержку IDE в абстрагировании). Сейчас этого нет в IDE, так как не хватает ключевых винтиков, чтобы научить компьютер абстрагироваться вместе с программистом - абстрактного языка и абстрактных описаний.
-- 27.03.2021, 10:35 --Можно так:
Код:
... printf(printf_parameters);
terminal class display = abstract(printf_parameters, display, ...);
Функция printf() не просто обновляет изображение на дисплее, а вносит в него изменения.
Класс display можно разбить на два подкласса Console и Graphic. И так далее.
Можно делать описания любой степени подробности вплоть до точного описания (если, конечно, граница системы не выходит за пределы языка программирования).