Языковые и инструментальные средства эволюционной разработки программ на основе процедурно-параметрической парадигмы программирования тема диссертации и автореферата по ВАК РФ 00.00.00, кандидат наук Косов Павел Владимирович

  • Косов Павел Владимирович
  • кандидат науккандидат наук
  • 2026, «Национальный исследовательский университет «Высшая школа экономики»
  • Специальность ВАК РФ00.00.00
  • Количество страниц 173
Косов Павел Владимирович. Языковые и инструментальные средства эволюционной разработки программ на основе процедурно-параметрической парадигмы программирования: дис. кандидат наук: 00.00.00 - Другие cпециальности. «Национальный исследовательский университет «Высшая школа экономики». 2026. 173 с.

Оглавление диссертации кандидат наук Косов Павел Владимирович

Введение

1 Подходы к реализации динамического полиморфизма

1.1 Механизмы реализации динамического полиморфизма

1.1.1 Поддержка динамического полиморфизма в статически типизированных объектно-ориентированных языках программирования

1.1.2 Реализация динамического полиморфизма в статически типизированных процедурных языках

1.1.2.1 Механизмы динамического полиморфизма в Go

1.1.2.2 Механизмы динамического полиморфизма в Rust

1.1.3 Динамический полиморфизм в функциональных языках на примере Haskell

1.1.4 Реализация динамического полиморфизма в ППП

1.2 Инструментальная поддержка множественного полиморфизма

1.2.1 Обзор возникновения и развития множественного полиморфизма

1.2.1.1 Детали реализации поиска специализации в CLOS

1.2.1.2 Множественный полиморфизм в Julia

1.2.1.3 Множественный полиморфизм в Clojure

1.2.2 Интеграция множественного полиморфизма в ООП

1.2.2.1 Множественный полиморфизм в С++

1.2.3 Реализация множественного полиморфизма в Rust

1.3 Реализация множественного полиморфизма в ППП

1.4 Выводы по главе

2 Процедурно-параметрический С

2.1 Основные процедурно-параметрические конструкции и их отображение на язык C

2.1.1 Основа специализации

2.1.2 Специализация обобщения

2.1.3 Параметрическое обобщение

2.1.4 Экземпляры параметрических обобщений

2.1.5 Рекурсивное расширение специализаций

2.1.6 Операции над специализированными переменными

2.1.7 Обобщающие параметрические функции

2.1.8 Обработчики параметрических специализаций

2.1.9 Вызовы параметрических функций

2.2 Трансформация процедурно-параметрических конструкций в промежуточное

представление КЬУМ

2.2.1 Трансформация параметрических обобщений

2.2.2 Трансформация специализаций параметрических обобщений

2.2.3 Создание объектов параметрических специализаций

2.2.4 Трансформация обобщающих функций

2.2.5 Трансформация обработчиков специализаций

2.2.6 Особенности процесса компоновки и запуска программы

2.2.7 Динамически подгружаемые библиотеки

2.3 Реализация встроенных функций

2.3.1 Создание и инициализация специализаций

2.3.2 Сравнение признаков типов

2.3.3 Создание специализации по индексу и получение общего количества специализаций для обобщения

2.4 Выводы по главе

3 Приемы проектирования с использованием 1111 подхода

3.1 Примеры ситуаций эволюционного расширения с использованием ППП

3.1.1 Добавление новых полиморфных методов

3.1.2 Эволюционная поддержка множественного полиморфизма

3.1.3 Построение конечного автомата

3.1.4 Конструирование объектов новых специализаций

3.1.5 Рекурсивное включение обобщения как основы для специализации

3.2 Применение ППП для улучшения безопасности преобразования типов в существующих приложениях

3.2.1 Актуальность проблем, решаемых ППП в С

3.2.2 Формирование оберток вокруг библиотечных функций

3.2.3 Оценка использования ПП оберток для программ на С

3.3 Реализация паттернов проектирования с помощью ПП конструкций

3.3.1 Фабричный метод

3.3.2 Абстрактная фабрика

3.3.3 Декоратор

3.3.4 Строитель

3.3.5 Прототип

3.3.6 Стратегия

3.3.7 Посетитель

3.5 Выводы по главе

4 Сравнение методов реализации множественного полиморфизма

4.1 Выбор решений для сравнения

4.2 Методика эксперимента

4.3 Описание решений

4.3.1 Процедурно-параметрические мультиметоды

4.3.2 Эмуляция мультиметодов, основанная на операторе switch

4.3.3 Реализация поиска специализаций мультиметодов в Julia

4.3.3.1 Описание поиска в быстром кеше

4.3.3.2 Описание поиска в основном кеше

4.3.5 Реализация объектно-ориентированного паттерна Посетитель

4.3.6 Реализация паттерна Посетитель с использованием процедурного подхода

4.3.7 Реализация паттерна Посетитель с использованием ППП

4.4 Анализ результатов измерений производительности

4.4.1 Анализ результатов замеров производительности поиска специализации мультиметода с двумя параметрами

4.4.2 Анализ результатов замеров производительности поиска специализации мультиметода с тремя и более параметрами

4.4.3 Выводы по сравнению производительности

4.5 Анализ сложности исходного кода для разных вариантов

4.5.1 Методика оценки исходного кода

4.5.1.1 Обзор существующих решений

4.5.1.2 Обоснование выбора используемой методики

4.5.2 Оценка сложности исходного кода сравниваемых вариантов

4.5.2.1 Вычисление характеристик исходного кода

4.5.2.2 Расчет метрик исходного кода

4.5.3 Анализ метрик для мультиметодов с двумя параметрами

4.5.4 Анализ метрик для мультиметодов с тремя и более параметрами

4.5.5 Выводы по сравнению метрик оценки сложности исходного кода

4.6 Анализ данных профилирования рассматриваемых вариантов

4.6.1 Методика профилирования

4.6.2 Профилирование циклов процессора

4.6.3 Профилирование выполненных инструкций процессора

4.6.4 Профилирование промахов кеша процессора

4.6.5 Анализ профилирования метрик

4.7 Сравнение вариантов по размеру сгенерированного машинного кода

4.7.1 Методика измерений размера машинного кода

4.7.2 Результаты и анализ сравнения

4.8 Итоговые выводы по проведенным измерениям

Заключение

Библиографический список

Список сокращений

Приложение А Исходные коды примеров

Приложение А.1 Разрешение неоднозначности выбора специализации в Clojure

Приложение А.2 Инициализации объекта в автоматической памяти

Приложение А.3 Инициализации объекта в динамической памяти

Приложение А.4 Функция init_spec

Приложение А.5 Диспетчеризующая функция для двух аргументов

Приложение А.6 Выделение памяти для массива обработчиков

Приложение А.7 Регистрация обработчика специализации

Приложение А.8 Реализация функции init_spec

Приложение А.9 Реализация функции create_spec

Приложение А.10 Реализация функции spec_index_cmp

Приложение А.11 Реализация функции выделения памяти под массив обработчикок

Приложение А.12 Запись обработчиков в массив

Приложение А.13 Реализация функции get_spec_ptr

Приложение А.14 Реализация функции get_spec_size

Приложение А.16 Использование интерфейсов в Go

Приложение А.17 Ручная реализация виртуальных таблиц в Linux

Приложение А.18 Ручная реализация виртуальных таблиц в C

Приложение А.19 Пример использования С++ библиотеки Yomm2

Приложение А.20 Пример использования Rust библиотеки multimethods.rs

Приложение А.21 Реализация диспетчеризующей функции основанной на операторе switch

для мультиметода с тремя параметрами

Приложение Б Реализация ОО паттернов проектирования с помощью ППП

Приложение Б.1 Фабричный метод

Приложение Б.2 Абстрактная фабрика

Приложение Б.3 Декоратор

Приложение Б.4 Строитель

Приложение Б.5 Прототип

Приложение Б.6 Стратегия

Приложение Б.7 Посетитель

Рекомендованный список диссертаций по специальности «Другие cпециальности», 00.00.00 шифр ВАК

Введение диссертации (часть автореферата) на тему «Языковые и инструментальные средства эволюционной разработки программ на основе процедурно-параметрической парадигмы программирования»

Введение

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

Большой вклад в исследование возможностей эволюционной разработки программ внесли отечественные исследователи. Одной из основных работ здесь является книга Фуксмана А.Л., вышедшая в 1979 году и описавшая концепции вертикальных и горизонтальных слоев программ, представляющих собой основной алгоритм работы программы и новый, эволюционно добавляемый функционал соответственно [1]. Данные идеи были позже расширены в работах Горбунова-Посадова М.М. [2,3] и Левыкина В.М. [4]. Однако, из-за отсутствия инструментальной поддержки, данные исследования не получили развития на практике.

Одним из подходов, обеспечивающих эволюционную разработку программ, является динамический полиморфизм (другое название — ad-hoc полиморфизм) [5,6]. Он связан с выявлением связи между вариантами альтернативных данных и функциями, обеспечивающими их обработку во время выполнения программы, которая реализуется соответствующими техническими приемами не требующими явной проверки типов.

Традиционная реализация динамического полиморфизма в объектно-ориентированном подходе (ООП) опирается на механизмы наследования и виртуальных функций.

В процедурных языках (например, C [7]) аналогичный эффект достигается через указатели на функции, структуры с полями-указателями на операции (реализация таблиц виртуальных методов вручную) и механизмы динамической загрузки библиотек (например, dlopen для Linux [8] или LoadLibrary для Windows [9]). В этом случае полиморфное поведение формируется путём переназначения указателей на функции либо подмены целых структур дескрипторов операций во время выполнения [10].

Актуальность работы: проблематика динамического полиморфизма имеет глубокие исторические корни. Концептуальные основы была заложены в 1960-х годах в рамках языков программирования Simula [11], Lisp [12], последовательно развитые в Smalltalk [13], CLOS [14], Eiffel [15], C++ [16], Java [17] и др. Текущие реализации динамического полиморфизма в ООП во многом помогают эволюционной разработке программ, однако в то же время вносят существенные накладные расходы: а) косвенные вызовы снижают локальность кода; б) нарастающая сложность иерархий наследования и увеличение количества полиморфных функций в интерфейсах замедляет компиляцию, снижает понятность кода, и усложняет переиспользование компонентов, что приводит к снижению возможностей эволюционного расширение. Помимо этого начиная с 1975 года в научной литературе по программной инженерии активно обсуждается фундаментальная проблема, известная как «проблема выражений» (expression problem) или «проблема расширяемости» (extensibility problem) [1821], которая заключается в принципиальной трудности одновременного расширения программной системы как новыми типами данных, так и новыми операциями над этими типами без модификации существующего кода, поскольку традиционный объектно-ориентированный подход позволяет удобно добавлять новые типы через наследование, но требует изменения базовых классов и всех их наследников при введении дополнительных операций. Другой фундаментальной проблемой является следующее: несмотря на то, что ООП механизмы демонстрируют достаточно высокую эффективность в контексте одиночного полиморфизма, когда динамическое поведение определяется типом единственного объекта, у них есть ограничения при реализации множественного полиморфизма — сценариев, в которых реализация функций зависит от более чем одного полиморфного параметра. В подобных ситуациях разработчики вынуждены прибегать к архитектурным обходным путям (созданию дополнительных классов), ручной конструкции таблиц указателей на функции либо внедрению каскадных условных конструкций, это сопровождается деградацией производительности и увеличением когнитивной сложности кода [22].

С точки зрения применения динамического полиморфизма в процедурных языках программирования и, в частности, языка С, который остаётся доминирующим в сфере системного программирования, отсутствие встроенных механизмов полиморфизма влечёт необходимость ручной реализации диспетчеризации через конструкции switch-case или таблицы указателей на функции (данный способ широко используется, например, в ядре операционной системы Linux [10]). Такой подход приводит к значительному росту объёма кода и увеличению вероятности внедрения дефектов, особенно при инкрементальном добавлении новых специализаций. Данные сложности при разработке больших проектов вызвали

необходимость дополнения процедурных языков механизмами полиморфизма, например, интерфейсами в Go [23] и типажами в Rust [24], которые основаны на статической утиной типизации (duck typing).

Отдельно стоит отметить работы в области множественного полиморфизма, востребованного при разработке крупных проектов [22], c 1980-х годов ведутся исследования по его внедрению в различные языки программирования [25]. Однако предложенные решения демонстрируют избыточную сложность, препятствующую их широкому распространению в экосистеме современных языков программирования. Попытки интеграции мультиметодов в C++ (например, на основе библиотечной поддержки [26]), Java (создание нового языка программирования MultiJava [27]) и другие широко используемые языки сталкиваются с комплексом проблем, включающих вопросы производительности, синтаксической сложности и обратной совместимости с существующими механизмами диспетчеризации. Из наиболее успешных современных реализаций можно отметить Julia [28], R [29], и Clojure [30], однако и эти подходы не решают проблемы производительности [31].

Один из подходов, ориентированных на оригинальный механизм поддержки динамического полиморфизма, был предложен в процедурно-параметрической (ПП) парадигме, развивающей концепцию динамического полиморфизма в процедурном подходе на основе расширяемых вариантных типов данных и параметрических таблиц обработчиков [32]. Концептуальная основа процедурно-параметрического подхода заключается в использовании обобщений, расширяемых специализациями и обработчиках обобщений, расширяемых обработчиками специализаций. Каждая основа специализации представляет собой автономный тип данных, который может быть расширен дополнительными специализациями. Механизм диспетчеризации реализуется через обобщённые функции, которые автоматически осуществляют выбор соответствующей реализации на основе типов переданных аргументов. Ключевым преимуществом ПП подхода является обеспечение эволюционного расширения без необходимости модификации существующей кодовой базы. Новые специализации могут быть инкрементально добавлены в отдельных единицах компиляции без требования перекомпиляции предварительно полученных объектных файлов. Достигается данное свойство за счёт механизма параметрических таблиц, формируемых во время инициализации программного комплекса и автоматически интегрирующих все доступные специализации.

Данный подход показал перспективность на экспериментальных языках программирования [33] и в виде библиотечной реализации для С++ [34], однако он до сих пор не имеет необходимой инструментальной поддержки, охватывающей этапы компилирования и компоновки исполняемых программ и динамических библиотек, которая обеспечивала бы

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

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

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

Задачи работы:

1. Исследование существующих подходов к реализации динамического полиморфизма.

2. Исследование методов реализации процедурно-параметрического подхода и его интеграции с языками программирования.

3. Исследование возможностей процедурно-параметрической парадигмы и разработка методов эффективной расширяемости функциональности программ.

4. Инструментальная поддержка процедурно-параметрической парадигмы программирования. Формирование технологической цепочки от компиляции до исполнения процедурно-параметрических программ и динамических библиотек.

5. Исследование эффективности предложенной реализации процедурно-параметрического подхода. Сравнительный анализ с другими подходами реализации множественного полиморфизма.

Предмет исследований: языковые и инструментальные средства процедурно-параметрического программирования и методы эффективной трансформации процедурно-параметрических программ.

Объект исследований: методы эволюционной разработки программного обеспечения и повешения ее эффективности

Методы исследования. Поставленные задачи решались посредством элементов теории

языков программирования, теории графов, технологии трансляции и теории алгоритмов. При разработке основных положений диссертации применялись методы системного анализа вычислительных систем, процедурно-параметрического и объектно-ориентированного проектирования и программирования. Разработанное программное обеспечение реализовано на языке С++. Примеры, демонстрирующие возможности рассматриваемой парадигмы, написаны на разработанном 1111 языке программирования PPC (Procedural-Parametric C), являющимся расширением языка программирования C.

Научная новизна:

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

2. Разработаны и реализованы новые методы компоновки и инициализации процедурно-параметрических конструкций, обеспечивающие эволюционное создание объектных модулей с их последующей компоновкой и окончательной сборкой во время запуска программы.

3. Методы процедурно-параметрического программирования добавлены в компилятор clang для языка программирования С, что обеспечило более гибкую эволюционную разработку программ.

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

5. Проведено сравнительное исследование эффективности различных подходов реализации мультиметодов, демонстрирующее высокие показатели у процедурно-параметрического решения.

Положения, выносимые на защиту:

1. Новые процедурно-параметрические конструкции и вспомогательные функции, которые обеспечивают более гибкую эволюционную разработку программ по сравнению с существующими решениями.

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

3. Процедурно-параметрические расширения и дополнительные служебные функции,

которые позволяют повысить возможности языков программирования по разработке эволюционно расширяемых программ.

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

Теоретическая и практическая значимость

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

2. Проведено сравнение с текущими подходами в производительности, сложности исходного кода и размера сгенерированного кода

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

Статьи по теме диссертации:

Основные положения и результаты исследований докладывались и обсуждались на открытых семинарах ВШЭ и Института систем информатики им. А. П. Ершова, шести всероссийских и международных конференциях и семинарах, в том числе: "Параллельные вычислительные технологии (ПАВТ 2025)" (Москва, 2025); "Central & Eastern European Software Engineering Conference in Russia (CEE-SECR 2013)" (Москва, 2013); "Проблемы информатизации региона. ПИР-2013" (Красноярск, 2013).

По теме диссертации опубликовано 9 работ, из которых 6 статей в изданиях, рекомендуемых ВАК, и 2 свидетельства о государственной регистрации программ для ЭВМ.

1. Косов П.В., Легалов А.И. Сравнение объектно-ориентированного и процедурно-параметрического полиморфизма // Труды Института системного программирования РАН, том 37, вып. 6, часть 1, 2025. C. 43-58.

2. Legalov, A.I., Kosov, P.V. C Language Extension to Support Procedural-Parametric Polymorphism. Aut. Control Comp. Sci. 58, 762-778 (2024). https://doi.org/10.3103/S014641162470024X

3. Легалов А.И., Косов П.В. Эволюционное расширение программ с использованием процедурно-параметрического подхода // Вычислительные технологии. 2016. Т. 21. №3. С. 56-69.

4. Косов П.В., Легалов А.И. Сравнение производительности различных подходов реализации диспетчеризации для мультиметодов // Системы анализа и обработки

данных. - 2025. - № 4 (100). - С. 69-84. - DOI: 10.17212/2782-2001-2025-4-69-84.

5. Косов П.В., Легалов А.И., Васильев В.В. Эволюционная разработка многопоточных программ с применением процедурно-параметрической парадигмы программирования // Труды конференции "Параллельные вычислительные технологии (ПАВТ 2025)". 2025. №1. С. 151-163.

6. Легалов А.И., Косов П.В. Инструментальная поддержка эволюционного расширения программ средствами процедурно-параметрического программирования. // Решетневские чтения. 2015. Т. 2. № 19. С. 232-233.

7. Легалов А.И., Косов П.В., Легалов И.А. Использование процедур с одинаковой сигнатурой для эволюционного расширения программ./ Доклады АН ВШ РФ, № 1 (26), 2015. - С. 41-51.

8. Legalov A, Kosov P. Evolutionary software development using procedural-parametric programming. / CEE-SECR '13 Proceedings of the 9th Central & Eastern European Software Engineering Conference in Russia. ACM New York, NY, USA ©2013. ISBN: 978-1-45032641-4. Article No. 3.

9. Легалов А.И., Косов П.В. Особенности организации и использования обобщенных записей языка процедурно-параметрического программирования Alien. / Проблемы информатизации региона. ПИР-2013: Материалы XIII Всероссийской научно-практической конференции. Красноярск: ИВМ СО РАН, 2013. - С. 187-194.

Свидетельства о государственной регистрации программ

1. Легалов А.И., Косов П.В., Легалов И.А., Швец Д.А. Транслятор с процедурно-параметрического языка программирования для операционной системы Linux. / Свидетельство о государственной регистрации программы для ЭВМ №2014612264. Зарегистрировано в реестре программ 21 февраля 2014 года.

2. Легалов А.И., Косов П.В., Легалов И.А., Швец Д.А. Генератор кода LLVM с языка процедурно-параметрического программирования. / Свидетельство о государственной регистрации программы для ЭВМ № 2015612548. Зарегистрировано в реестре программ 19 февраля 2015 года.

Соответствие специальности. По своему научному содержанию диссертационная работа соответствует паспорту специальности 1.2.3 «Теоретическая информатика, кибернетика»: пункту №4 (математическая теория языков и грамматик); пункту № 29 (теоретические основы программирования, создания программных систем для новых информационных технологий).

Личный вклад автора. Основные результаты являются новыми и получены лично

автором. Вклад автора в научные работы, опубликованные в соавторстве с научным руководителем, заключается в следующем: анализе особенностей 1111 парадигмы в контексте задачи эффективной реализации множественного полиморфизма; разработке методов и алгоритмов преобразования 1111 программ в исполняемую форму; создании инструментальных средств трансформации 1111 программ и их интеграции с существующими инструментальными средствами программирования; разработке демонстрационных примеров. Все выносимые на защиту результаты принадлежат лично автору. Компилятор 1111 расширения языка программирования С на основе clang создан лично автором. На основе именно этого компилятора была выполнена вся экспериментальная часть данной работы.

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

1редставление изложенных в диссертации и выносимых на защиту результатов, полученных в совместных исследованиях, согласованно с соавторами.

Структура и объем работы. Диссертация состоит из введения, четырех разделов, заключения, списка сокращений и двух приложений. Работа содержит 140 страниц основного текста, 24 рисунка и 3 таблицы. Список использованных источников содержит 132 наименования.

Во введении приводится общая характеристика работы и дается краткий обзор содержания диссертации.

В первой главе проводится обзор существующих подходов к реализации полиморфизма. Рассматриваются процедурные, объектно-ориентированные и функциональные языки программирования. 1омимо одиночного полиморфизма рассматривается и множественный полиморфизм, начиная от его первых реализаций в CLOS до его современных реализаций в языках программирования Julia, Clojure, и др. В завершении главы приводится обзор процедурно-параметрического подхода к реализации полиморфизма.

Вторая глава посвящена формальному описанию синтаксиса и семантики процедурно-параметрического расширения языка C. 1редставлены формальные конструкции для описания обобщений и специализаций, обобщённых функций и их обработчиков. Детально рассмотрен процесс трансформации 11 конструкций в промежуточное представление LLVM и механизмы

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

Третья глава посвящена аспектам применения ППП в проектировании программных систем. Показано, как классические паттерны проектирования (Фабричный метод, Абстрактная фабрика, Декоратор, Строитель, Прототип, Стратегия и Посетитель) могут быть применены в рамках процедурно-параметрической парадигмы. Дополнительно описаны специфические приёмы программирования, такие как рекурсивное включение обобщений и использование целочисленных значений в качестве основ специализаций.

Четвертая глава содержит экспериментальное сравнение различных подходов к реализации множественного полиморфизма. Проведены систематические эксперименты по измерению производительности, метрик сложности кода и объёма генерируемого машинного кода. Результаты экспериментов демонстрируют лучшие показатели ППП по большинству измеренным метрикам.

В заключении представлены научные и практические результаты, а также возможные пути дальнейших научных исследований.

В приложении А приведены исходные коды рассматриваемых примеров.

В приложении Б приведены реализации ООП паттернов проектирования в ПП подходе.

Значимость проделанной работы заключается не столько в расширении самого языка C механизмами ПП, сколько в доказательстве концептуальной осуществимости и практической эффективности процедурно-параметрического подхода в рамках чисто процедурной, компилируемой и широко распространённой платформы. Реализованный в компиляторе clang комплекс механизмов — от синтаксического разбора до генерации промежуточного кода LLVM и поддержки динамических библиотек — служит реплицируемым образцом, который может быть адаптирован к любому другому языку программирования независимо от его парадигматической ориентации. Тем самым работа не ограничивается локальным достижением для экосистемы C, а предоставляет возможность включению процедурно-параметрического полиморфизма в языки императивного и функционального подходов, разрабатываемые для решения задач как системного, так и прикладного программирования, без необходимости значительного пересмотра их архитектуры.

1 Подходы к реализации динамического полиморфизма

1.1 Механизмы реализации динамического полиморфизма

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

1.1.1 Поддержка динамического полиморфизма в статически типизированных объектно-ориентированных языках программирования

Одним из фундаментальных механизмов, обеспечивающих гибкость эволюционного расширения, является динамический полиморфизм, позволяющий системам обеспечивать гибкость и расширяемость за счёт отложенного разрешения вызовов методов до момента исполнения программы. В отличие от статического полиморфизма, где выбор конкретной реализации функции происходит на этапе компиляции, динамический подход позволяет объектам разных типов обрабатываться через единый интерфейс, что особенно важно для построения модульных, легко расширяемых систем. Идея динамического полиморфизма оформилась в 1960-х годах в языке Simula [11], где впервые были введены понятия виртуальных методов и позднего связывания. С тех пор механизмы динамической диспетчеризации эволюционировали вместе с развитием языков программирования, приспосабливаясь к их парадигмам — будь то объектно-ориентированное, процедурное, функциональное или смешанное программирование.

Исторически реализация динамического полиморфизма тесно связана с объектно-ориентированной парадигмой (ООП). В динамически типизированных языках, таких как Smalltalk [13] и Python [35], используется концепция «утиной типизации», где совместимость объектов определяется наличием методов с идентичной сигнатурой. В статически типизированных ОО-языках (C++ [36], Java [17], C# [37]) базовым решением стало сочетание наследования и виртуализации: первое гарантирует однородность интерфейсов, второе — подмену реализаций в производных классах.

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

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

В языке программирования С++ динамический полиморфизм реализован с использованием общей фундаментальной идеи: выбор реализации метода во время выполнения на основе динамического типа объекта с использованием таблицы виртуальных методов, указатель на которую хранится в каждом объекте полиморфного типа. Для иллюстрации механизма на рисунке 1 приведена схему ОО реализации наследования в статически типизированных языках программирования.

Рисунок 1. Реализация объектно-ориентированного полиморфизма Объектно-ориентированный полиморфизм формируется путем сочетания наследования и виртуализации. Виртуализация при этом обычно реализуется за счет таблиц виртуальных методов (VT). Таблица базового класса Base, выступающего в роли обобщения, содержит указатели на один или несколько методов (F), которые обычно переопределяются в виртуальных таблицах производных классов, являющихся специализациями обобщения (Childi — Childn). При этом каждый производный класс, расширяя базовый класс, имеет собственный тип, что выражается в уникальном имени класса (Childi). Производные классы формируются независимо друг от друга. Это позволяет эволюционно расширять альтернативные

Похожие диссертационные работы по специальности «Другие cпециальности», 00.00.00 шифр ВАК

Список литературы диссертационного исследования кандидат наук Косов Павел Владимирович, 2026 год

Библиографический список

1. Фуксман, А.Л. Технологические аспекты создания программных систем - М.: Статистика, 1979 - 184 с.

2. Горбунов-Посадов, М.М.. Расширяемые программы - М.: Полиптих, 1999 - 336 с.

3. Горбунов-Посадов, М.М. Эволюция программы: структура транзакции // Открытые системы. - 2000. - №10 - C.43-47.

4. Левыкин, В. М. Принципы эволюционного создания функционального программного обеспечения распределенных информационных систем / В. М. Левыкин, С. Ф. Чалый, Д. Н. Боровской, // Радиоэлектроника и информатика. - 2001. - Т.15. - №2 — C. 152-154.

5. Cardelli, L. On understanding types, data abstraction, and polymorphism / L. Cardelli, P. Wegner // ACM Computing Surveys (CSUR). - 1985. - Т.17. - №5 - P. 471-523.

6. Strachey, C. Fundamental Concepts in Programming Languages // Higher-Order and Symbolic Computation. - 2000. - Т.13. - №1 - P.11-49.

7. Kernighan, B. W. C Programming Language / B. W. Kernighan, D. M. Ritchie -Pearson, 1986 - 272 p.

8. Kerrisk, M. The Linux Programming Interface: A Linux and UNIX System Programming Handbook / M. Kerrisk - No Starch Press, 2010 - 1552 p.

9. Yosifovich, P. Windows Internals: System architecture, processes, threads, memory management / P. Yosifovich, M. E. Russinovich, D. A. Solomon, A. Ionescu - Microsoft Press, 2017 -800 p.

10. Love. R. Linux Kernel Development / R. Love - Addison-Wesley Professional, 2010 -

480 p.

11. Pooley, R. J. Introduction to Programming With Simula / R. J. Pooley - Alfred Waller Ltd, 1987 - 344 p.

12. Steele, G. Common LISP. The Language / G. Steele - Digital Press, 1990 - 1056 p.

13. Shafer, D. Practical Smalltalk. Using Smalltalk / D. Shafer, D. A. Ritz. - Springer, 1991 - 233 p.

14. Demichiel, L. G. Overview: The common lisp object system / L. G. Demichiel // Lisp and Symbolic Computation. - 1989. - №1 - P.227-244.

15. Meyer, B. Eiffel: The Language / B. Meyer - Prentice Hall, 1991 - 300 p.

16. Stroustrup, B. C++ Programming Language / B. Stroustrup - Addison-Wesley Professional, 2013 - 1376 p.

17. Sciore, E. Java Program Design / E. Sciore - Apress Media, 2019 - 473 p.

18. Reynolds, J. User-defined Types and Procedural Data Structures as complementary approaches to Data Abstraction / J. Reynolds // IFIP Working Group 2.1 on Algol. - 1975. - P.157-168.

19. Cook, W. R. Object-Oriented Programming Versus Abstract Data Types / W. R. Cook // Proceedings of the REX School/Workshop on Foundations of Object-Oriented Languages. - 1990. — P.151-178.

20. The Expression Problem, [online, revised 28/08/2025] : https://homepages.inf.ed.ac.uk/wadler/papers/expression/expression.txt

21. Torgersen, M. The Expression Problem Revisited / M. Torgersen // European Conference on Object-oriented Programming. - 2004. - P.123-143.

22. Muschevici, R. Multiple dispatch in practice / R. Muschevici, A. Potanin, E. Tempero, J. Noble // Proceedings of the 23rd ACM SIGPLAN conference on Object-oriented programming systems languages and application. - 2008. - P.563-582.

23. Freeman, A. Pro Go: The Complete Guide to Programming Reliable and Efficient Software Using Golang / A. Freeman - Apress Media, 2022 - 1076 p.

24. Blandy, J. Programming Rust / J. Blandy, J. Orendorff, L. Tindall. - O'Reilly Media, 2021 - 1470 p.

25. Moon, D. New Flavors / D. Moon, S. Keene // OOPSLA '86: Conference proceedings on Object-oriented programming systems, languages and applications. - 1986. - P.15-16.

26. Pirkelbauer, P. Open Multi-Methods for C++ / P. Pirkelbauer, Y. Solodkyy, B. Stroustrup // GPCE '07: Proceedings of the 6th international conference on Generative programming and component engineering. - 2007 - P. 123-134.

27. Clifton, C. MultiJava: Design rationale, compiler implementation, and applications / C. Clifton, T. Millstein, G. T. Leavens, C. Chambers // ACM Transactions on Programming Languages and Systems (TOPLAS). - 2006. - Т.28. - №3 - P. 517-575.

28. Julia Documentation, [online, revised 28/08/2025] : https://docs.julialang.org/en/v1/

29. R programming language manual, [online, revised 28/08/2025] : https://stat.ethz.ch/R-manual/R-devel/library/base/html/UseMethod.html

30. Clojure. Multimethods and Hierarchies, [online, revised 28/08/2025] : https://clojure.org/reference/multimethods

31. Julia Documentation. The dangers of abusing multiple dispatch, [online, revised 28/08/2025] : https://docs.julialang.org/en/v1/manual/performance-tips/#The-dangers-of-abusing-multiple-dispatch-(aka,-more-on-types-with-values-as-parameters

32. Легалов, А.И. Процедурно-параметрическая парадигма программирования. Возможна ли альтернатива объектно-ориентированному стилю? / А.И. Легалов // Деп. рук. № 622-В00 Деп. в ВИНИТИ 13.03.2000. - Красноярск: 2000. - 43 с.

33. Легалов, А.И. Процедурный язык с поддержкой эволюционного проектирования / А. И. Легалов, Д. А. Швец // Научный вестник НГТУ, № 2 (15), 2003. С. 25-38.

34. PPLib. C++ Library for Procedural-Parametric Polymorphism, [online, revised 28/08/2025] : https://github.com/kpdev/pplib

35. Hunt, J. Advanced Guide to Python 3 Programming / J. Hunt - Springer, 2019 - 497 p.

36. Gregoire, M. Professional C++ / M. Gregoire - John Wiley & Sons, 2018 - 1122 p.

37. Albahari, J. C# 6.0 Pocket Reference / J. Albahari, B. Albahari - O'Reilly Media, 2016 - 224 p.

38. Fortran High-performance parallel programming language, [online, revised 28/08/2025] : https://fortran-lang.org/

39. Barnes, J. Programming in Ada 2012 / J. Barnes - Cambridge University Press, 2014 -

967 p.

40 ГОСТ 27831-88. Язык программирования Ада (утвержден и введен в действие постановлением гос комитета СССР по стандартам от 22.09.88 N 3217), 1988 - 133 c.

41. Hudak, P. Report on the programming language Haskell: a non-strict, purely functional language version 1.2 / P. Hudak // ACM SIGPLAN Notices. - 1992 - Т.27. - №5 - 164 p.

42. Jones, S. P. Type classes: Exploring the design space / S. P. Jones, M. Jones, E. Meijer // Proceedings of the Haskell Workshop. - 1997. - 16 p.

43. The Glasgow Haskell Compiler, [online, revised 28/08/2025] : https://www.haskell.org/ghc/

44. Milner, R. A theory of type polymorphism in programming / R, Milner // Journal of Computer and System Sciences. - 1978. - Т.17. - №3 - P.348-375.

45. Легалов, А.И. Особенности организации и использования обобщенных записей языка процедурно-параметрического программирования Alien. / А.И. Легалов, П.В. Косов // Проблемы информатизации региона. ПИР-2013: Материалы XIII Всероссийской научно-практической конференции. Красноярск: ИВМ СО РАН, 2013. - С. 187-194.

46. Procedural-parametric meta compiler for C, [online, revised 28/08/2025] : https://github.com/kpdev/ppmc

47. Gamma, E. Design Patterns. Elements of Reusable Object-Oriented Software / E. Gamma, R. Helm, R. Johnson, J. Vlissides - Addison-Wesley Professional, 1994 - 416 p.

48. Alexandrescu, A. Modern C++ Design. Generic Programming and Design Patterns Applied / A. Alexandrescu - Addison-Wesley Professional, 2001 - 360 p.

49. Meyers, S. More effective C++. 35 New Ways to Improve Your Programs and Designs / S. Meyers - Addison-Wesley Professional, 1996 - 318 p.

50. Legalov, A. I. OOP, Multimethods and Pyramidal Evolution / A. I. Legalov // Open Systems. - 2002. - №3 - P.41-45.

51. Stroustrup, B. The design and evolution of C++ / B. Stroustrup - ACM Press/Addison-Wesley Publishing Co., New York, NY, USA,1994 - 427 p.

52. Rust library for Multimethods support, [online, revised 28/08/2025] : https://github.com/fcard/multimethods.rs

53. Hendler, J. Enhancement for multiple-inheritance / J. Hendler // OOPWORK '86: Proceedings of the 1986 SIGPLAN workshop on Object-oriented programming. - 1986. - P. 98-106.

54. Bobrow, D. G. CommonLoops: merging Lisp and object-oriented programming / D. G. Bobrow, K. Kahn, G. Kiczales, L. Masinter, M. Stefik, F. Zdybel // OOPSLA '86: Conference proceedings on Object-oriented programming systems, languages and applications. - 1986. - P.17-29.

55. The Cecil Language. Specification and Rationale. Version 3.2, [online, revised 28/08/2025] : https://projectsweb.cs.washington.edu/research/projects/cecil/www/Release/doc-cecil-lang/cecil-spec.pdf

56. Diesel, [online, revised 28/08/2025] : https://wasp.cs.washington.edu/wasp_diesel.html

57. Shalit, A. The Dylan Reference Manual: The Definitive Guide to the New Object-Oriented Dynamic Language / A. Shalit - Addison-Wesley,1996 - 469 p.

58. Ungar, D. Self: The power of simplicity / D. Ungar, R. B. Smith // Conference

proceedings on Object-oriented programming systems, languages and applications. - 1987. - P.227-242.

59. Freeman-Benson, B. N. A Proposal for Multi-Methods in SELF / B. N. Freeman-Benson // Unpublished manuscript. - 1989.

60. Chambers, C. Object-Oriented Multi-Methods in Cecil / C. Chambers // ECOOP '92: Proceedings of the European Conference on Object-Oriented Programming. - 1992. - P. 33-56.

61. Chambers, C. Efficient multiple and predicated dispatching / C. Chambers, W. Chen // ACM SIGPLAN Notices. - 1999. - T.34. - №10 - P. 238-255.

62. Mugridge, W. B. Multi-Methods in a Statically-Typed Programming Language / W. B. Mugridge, J. Hamer, J. G. Hosking // ECOOP '91: Proceedings of the European Conference on Object-Oriented Programming. - 1991. - P. 307-324.

63. Leavens, G. T. Verifying Object-Oriented Programs that use Subtypes / G. T. Leavens // PhD Thesis, MIT - 1989. - 212 p.

64. Steele, G. L. Parallel programming and code selection in Fortress / G. L. Steele // Proceedings of the eleventh ACM SIGPLAN symposium on Principles and practice of parallel programming. - 2006. — P. 1-15.

65. Park, G. Polymorphic symmetric multiple dispatch with variance / G. Park, J. Hong, G. L. Steele, S. Ryu // Proceedings of the ACM on Programming Languages, Volume 3, Issue POPL. -2019. - T.3. - № - P. 1-28.

66. R programming language, [online, revised 28/08/2025] : https://www.r-project.org/about.html

67. The Metaobject Protocol of the Common Lisp Object System, [online, revised 28/08/2025] : http://metamodular.com/CLOS-MOP/compute-discriminating-function.html

68. GNU CLISP - an ANSI Common Lisp Implementation, [online, revised 28/08/2025] : https://www.gnu.org/software/clisp/

69. Julia Compiler Source Code. Generic Functions, [online, revised 28/08/2025] : https://github.com/JuliaLang/julia/blob/vL11.3/src/gf.c

70. Bezanson, J. Array Operators Using Multiple Dispatch: A design methodology for array implementations in dynamic languages / J. Bezanson, J. Chen, S. Karpinski, V. Shah, A. Edelman // ARRAY'14: Proceedings of ACM SIGPLAN International Workshop on Libraries, Languages, and Compilers for Array Programming. - 2014. - P. 56-61.

71. The Unreasonable Effectiveness of Multiple Dispatch, [online, revised 28/08/2025] : https://www.juliaopt.org/meetings/santiago2019/slides/stefan karpinski.pdf

72. Gowda, S. High-performance symbolic-numerics via multiple dispatch / S. Gowda, Y Ma, A. Cheli, M. Gwozzdz, V. B. Shah, A. Edelman, C. Rackauckas // ACM Communications in Computer Algebra. - 2022. - T.55. - №3 - P. 92-96.

73. Allen, E. Type checking modular multiple dispatch with parametric polymorphism and multiple inheritance / E. Allen, J. Hilburn, S. Kilpatrick, V. Luchangco, S. Ryu, D. Chase, G. Steele // ACM SIGPLAN Notices, Volume 46, Issue 10. - 2011. - T.46. - №10 - P. 973-992.

74. Belyakova, J. Decidable Subtyping of Existential Types for Julia / J. Belyakova, B. Chung, R. Tate, J. Vitek // Proceedings of the ACM on Programming Languages. - 2024. - T.8. - №191

- P. 1091-1114.

75. Pelenitsyn, A. Type Stability in Julia: Avoiding Performance Pathologies in JIT Compilation / A. Pelenitsyn, J. Belyakova, B. Chung, R. Tate, J. Vitek // Proceedings of the ACM on Programming Languages. - 2021. - T.5. - №150 - P. 1-26.

76. Francesco, Z. N. Julia subtyping: a rational reconstruction / F. Z. Nardelli, J. Belyakova, A. Pelenitsyn, B. Chung, J. Bezanson, J. Vitek // Proceedings of the ACM on Programming Languages. - 2018. - T.2. - №113 - P. 1-27.

77. Hickey, R. A history of Clojure / R. Hickey // Proceedings of the ACM on Programming Languages. - 2020. - T.4. - P. 1-46.

78. Clojure compiler source code, [online, revised 28/08/2025] : https://github.com/cloiure/cloiure/tree/cloiure-1.12.0

79. Milner, R. The Definition of Standard ML / R. Milner - 1997 - 132 p.

80. The Nice programming language, [online, revised 28/08/2025] : https://nice.sourceforge.net/

81. Eclipse IDE, [online, revised 28/08/2025] : https://eclipseide.org/

82. Amiel, E. Optimizing multi-method dispatch using compressed dispatch tables / E. Amiel, O. Gruber, E. Simon // ACM SIGPLAN Notices. - 1994. - T.29. - №10 - P. 244-258.

83. Dixon, R. A fast method dispatcher for compiled languages with multiple inheritance / R. Dixon, T. McKee, M. Vaughan, P. Schweizer // ACM SIGPLAN Notices. - 1989. - T.24. - №10 - P. 211-214.

84. Ingalls, D. A simple technique for handling multiple polymorphism / D. Ingalls // ACM SIGPLAN Notices. - 1986. - T.21. - №11 - P. 347-349.

85. Boyland, J. Parasitic methods: an implementation of multi-methods for Java / J. Boyland, G. Castagna // OOPSLA '97: Proceedings of the 12th ACM SIGPLAN conference on Object-oriented programming, systems, languages, and applications. - 1997. - P. 66-76.

86. Coady, Y. Using aspectC to improve the modularity of path-specific customization in operating system code / Y. Coady, G. Kiczales, M. Feeley, G. Smolyn // ESEC/FSE-9: Proceedings of the 8th European software engineering conference held jointly with 9th ACM SIGSOFT international symposium on Foundations of software engineering. - 2001. - T.. - № - P. 88-98.

87. Leavens, G. T. Multiple dispatch as dispatch on Tuples / G. T. Leavens, T. D. Millstein // OOPSLA '98: Proceedings of the 13 th ACM SIGPLAN conference on Object-oriented programming, systems, languages, and applications. - 1998. - P. 374-387.

88. Foote, B. Efficient Multimethods in a Single Dispatch Language / B. Foote, R. E. Johnson, J. Noble // ECOOP'05: Proceedings of the 19th European conference on Object-Oriented Programming. - 2005. - P. 337-361.

89. Stroustrup, B. Thriving in a crowded and changing world: C++ 2006-2020 / B. Stroustrup // Proceedings of the ACM on Programming Languages. - 2020. - T.4. - №17 - 168 p.

90. Wonnacott, D. Using accessory functions to generalize dynamic dispatch in singledispatch object-oriented languages / D. Wonnacott // Proceedings of the 6th conference on USENIX Conference on Object-Oriented Technologies and Systems. - №6 - 7 p.

91. Cmm (C++ with MultiMethods) user documentation, [online, revised 28/08/2025] :

http://www.op59.net/cmm/

92. Multimethods, [online, revised 28/08/2025] : https://accu.org/journals/overload/9/42/smith 456/

93. Julian, S. Proposal for adding MultiMethods to C++ / S. Julian - 2003. - 16 p.

94. Bettini, L. Double dispatch in C++ / L. Bettini, S. Capecchi, B. Venneri // Software— Practice & Experience. - 2006. - Т.36. - №6 - P. 581-613.

95. Edison Design Group. The C++ Front End, [online, revised 28/08/2025] : https://www.edg.com/c

96. Pirkelbauer, P. Design and evaluation of C++ open multi-methods / P. Pirkelbauer, Y. Solodkyy, B. Stroustrup // Science of Computer Programming. - 2010. - Т.75. - №7 - 30 p.

97. Mach7 C++ Library for Open Pattern Matching, [online, revised 28/08/2025] : https://github.com/solodon4/Mach7

98. Solodkyy, Y. Open and efficient type switch for C++ / Y. Solodkyy, G. D. Reis, B. Stroustrup // Proceedings of the ACM international conference on Object oriented programming systems languages and applications. - 2012. - P. 963-982

99. YOMM2 C++ Library, [online, revised 28/08/2025] : https://github.com/jll63/yomm2

100. YOMM2: Fast, Orthogonal Open (Multi) Methods, [online, revised 28/08/2025] : https://github.com/jll63/yomm2/blob/master/docs/slides/YOMM2-corecpp.pdf

101. Boost C++ Libraries, [online, revised 28/08/2025] : https://www.boost.org/

102. Boost.OpenMethod, [online, revised 28/08/2025] : https://jll63.github.io/Boost.OpenMethod/

103. C++ Library Technical Report, [online, revised 28/08/2025] : https://www.open-std.org/jtc1/sc22/wg21/docs/library_technical_report.html

104. Легалов, А. И. Расширение языка C для поддержки процедурно-параметрического полиморфизма / А. И. Легалов, П. В. Косов // Моделирование и анализ информационных систем, 2023 - С.40-62.

105. Легалов, И.А. Применение обобщенных записей в процедурно-параметрическом языке программирования / Легалов И.А. // Науч. вест. НГТУ 2007. № 3(28). С. 25-37.

106. Linux x86 Program Start Up, [online, revised 28/08/2025] : http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html

107. Elf Format — Linux manual page, [online, revised 28/08/2025] : https://man7.org/linux/man-pages/man5/elf5.html

108. dlopen — Linux manual page, [online, revised 28/08/2025] : https://man7.org/linux/man-pages/man3/dlopen.3.html

109. Win32 API. LoadLibrary, [online, revised 28/08/2025] : https://learn.microsoft.com/ru-ru/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibrarya

110. Procedure Parametric Clang Compiler Project based on Clang, [online, revised 28/08/2025] : https://github.com/kpdev/llvm-project/tree/pp-extension-v2

111. Butenhof, D. R. Programming with POSIX Threads / D. R. Butenhof - Addison-Wesley Professional,1997 - 400 p.

112. Williams, A. C++ Concurrency in Action / A. Williams - Manning,2019 - 592 p.

113. Kiczales, G. Aspect-oriented programming / G. Kiczales, J. Lamping, A. Mendhekar, C. Maeda, C. Lopes, J. Loingtier, J. Irwin - 1997 - P.220-242.

114. The LLVM Compiler Infrastructure, [online, revised 28/08/2025] : https://github.com/llvm/llvm-project/

115. Benchmarks for multiple dispatch mechanisms, [online, revised 28/08/2025] : https://github.com/kpdev/julia lookup/

116. Примеры программ, демонстрирующие возможности процедурно-параметрического программирования, [online, revised 28/08/2025] : https://github.com/kreofil/evo-situations

117. O'Neil, D. National Software Quality Experiment Results / D. O'Neil // Proceedings of the Eighth Annual Software Technology Conference. - 1996. - P.21-26.

118. McCabe, T. J. A complexity measure / T. J. McCabe // ICSE '76: Proceedings of the 2nd international conference on Software engineering. - 1976. - Т.2. - №4 - P. 308-320.

119. Halstead, M. H. Elements of software science / M. H. Halstead - Operating and programming systems series - 1977 - 142 p.

120. Akiyama, F. An Example of Software System Debugging / F. Akiyama // IFIP Congress. - 1971. - Т.71. - №1 - P.353-359.

121. Bhatt, K. Analysis Of Source Lines Of Code (SLOC) Metric / K. Bhatt, V. Tarey, P. Patel // International Journal of Emerging Technology and Advanced Engineering. - 2012. - Т.2. - №5 - P.150-154.

122. Chidamber, S. R. A Metrics Suite for Object Oriented Design / S. R. Chidamber, C. F. Kemerer // IEEE Transactions on Software Engineering. - 1994. - Т.20. - №6 - P.476-493.

123. Brito, A. F. Object-oriented software engineering: Measuring and controlling the development process / A. F. Brito, R. Carapu9a // Proceedings of the 4th International Conference on Software Quality. - 1994. - Т.186. - 8 p.

124. Metrics Thresholds in McCabe IQ, [online, revised 28/08/2025] : http://www.mccabe.com/pdf/McCabe%20IQ%20Metrics.pdf

125. Software Size Measurement: A Framework for Counting Source Statements (CMU/SEI92-TR-020), [online, revised 28/08/2025] : https://insights.sei.cmu.edu/documents/1058/1992 005 001 16082.pdf

126. Chou, C. Metrics in Evaluating Software Defects / C. Chou // International Journal of Computer Applications. - 2013. - Т.63. - №3 - P.23-29.

127. Measure Code Complexity Using Cyclomatic Complexity, [online, revised 28/08/2025] : https://la.mathworks.com/help/matlab/matlab_prog/measure-code-complexity-using-cyclomatic-complexity.html

128. Yourdon, E. Structured Design: Fundamentals of a Discipline of Computer Program and Systems Design / E. Yourdon, L. L. Constantine. - Prentice-Hall,1979 - 473 p.

129. CAST Enforce Object Oriented Metrics - Chidamber and Kemerer Metrics Suite, [online, revised 28/08/2025] : https://doc.castsoftware.com/export/TG/CMS+Assessment+Model+-+Information+-+CAST+Enforce+Object+Oriented+Metrics+-

+Chidamber+and+Kemerer+Metrics+Suite

130. Abreu, F. B. Evaluating the Impact of Object-Oriented Design on Software Quality / F. B. Abreu, W. Melo, W. Melo // Proceedings of the 3rd International Symposium on Software Metrics: From Measurement to Empirical Results. - 1996 - 90 p.

131. Harrison, R. An Evaluation of the MOOD Set of Object-Oriented Software Metrics / R. Harrison, S. J. Counsell, R. V. Nithi // IEEE Transactions on Software Engineering. - 1998. - T.24. -№6 - P.491-496.

132. Gregg, B. Systems Performance / B. Gregg - Addison-Wesley Professional,2020 - 928

p.

Список сокращений

ООП — объектно-ориентированное программирование;

ППП — процедурно-параметрическое программирование;

ПППП — процедурно-параметрическая парадигма программирования;

АСД — абстрактное синтаксическое дерево;

LLVM IR - Промежуточное представление (англ.: intermediate representation) LLVM;

SSA - форма статического единственного присваивания (англ.: single static assignment);

MMU - Блок управления памятью (англ. memory management unit)

BPF - Berkeley Packet Filter

EDG - Edison Design Group

GHC - Glasgow Haskell Compiler

PPMC - Parametric Procedural Meta Compiler

JIT-компиляция - компиляция «точно в срок», или «точно в указанное время» (англ.: just in time). Технология компиляции байт-кода непосредственно во время работы программы JVM - Java Virtual Machine

CLR - Общеязыковая исполняющая среда (англ.: Common Language Runtime)

Приложение А Исходные коды примеров

Приложение А.1 Разрешение неоднозначности выбора специализации в Clojure

;; Создание типа rect, наследуемого от типа shape (derive ::rect ::shape)

;; Определение диспетчеризующей функции (мультиметода) (defmulti bar (fn [x y] [x y]))

;; Определение специализаций

(defmethod bar [::rect ::shape] [x y] :rect-shape) (defmethod bar [::shape ::rect] [x y] :shape-rect) ;; Вызов мультиметода с явно определенной специализацией (bar ::shape ::rect) -> :shape-rect

;; Вызов мультиметода с неоднозначной специализацией ;; (т.е. подходят обе специализации) ;; приводит к ошибке (bar ::rect ::rect)

-> Execution error (IllegalArgumentException) at user/eval152 (REPL:1). Multiple methods in multimethod 'bar' match dispatch value: [:user/rect :user/rect] -> [:user/shape :user/rect] and [:user/rect :user/shape], and neither is preferred

;; Устанавливаем приоритет одной специализации над другой (prefer-method bar [::rect ::shape] [::shape ::rect])

;; Теперь вызов мультиметода с такими же параметрами, как описано выше ;; не приводит к ошибке, выполняется специализация с большим приоритетом (bar ::rect ::rect) -> :rect-shape

Приложение А.2 Инициализации объекта в автоматической памяти

define void @foo() {

; Выделение памяти под структуру %fc = alloca %struct.Figure_circ

; Начало блока инициализация признаками

%0 = load i32, ptr @tag_Figure_circ

%head = getelementptr inbounds %struct.Figure_circ,

ptr %fc, i32 0, i32 0 %spec_tag = getelementptr inbounds %struct.Figure,

ptr %head, i32 0, i32 0

store i32 %0, ptr %spec_tag ; Конец блока инициализации признаками

ret void

}

Приложение А.3 Инициализации объекта в динамической памяти

define ptr @create_spec_Figure_rect() { %Size = alloca i64 store i64 8, ptr %Size %0 = load i64, ptr %Size

%malloc_res = call ptr @malloc(i64 noundef %0)

call void @init_spec_Figure_rect(ptr noundef %malloc_res) ret ptr %malloc_res

}

Приложение А.4 Функция init_spec

define void @init_spec_Figure_rect(ptr noundef %0) { %pp_head = getelementptr inbounds

%struct.Figure_rect, ptr %0, i32 0, i32 0 %pp_spec_type = getelementptr inbounds

%struct.Figure, ptr %pp_head, i32 0, i32 0 %global_spec_tag = load i32, ptr @tag_Figure_rect store i32 %global_spec_tag, ptr %pp_spec_type ret void

}

Приложение А.5 Диспетчеризующая функция для двух аргументов

define void @pp_mm_PrintFigure(ptr %f1, ptr %f2) { entry:

%0 = alloca ptr, align 8 store ptr %f1, ptr %0, align 8

%1 = getelementptr inbounds %struct.Figure, ptr %f1, i32 0, i32 0 %2 = load i32, ptr %1 %3 = sub nsw i32 %2, 1 %4 = sext i32 %3 to i64

%5 = load ptr, ptr @mminitarr_pp_mm_PrintFigure

%6 = getelementptr inbounds ptr, ptr %5, i64 %4

%7 = load ptr, ptr %6

call void %7(ptr noundef %f1)

ret void

}

Приложение А.6 Выделение памяти для массива обработчиков

define void @alloc_pp_mm_PrintFigure() { entry:

%0 = load i32, ptr @tags_Figure %1 = sext i32 %0 to i64 %2 = mul i64 8, %1

%call_malloc = call ptr @malloc(i64 noundef %2) #2 store ptr %call_malloc, ptr @initarr_pp_mm_PrintFigure %3 = load i64, ptr @initarr_pp_mm_PrintFigure %Size = alloca i64 %Iter = alloca i64 %4 = udiv i64 %2, 8

%5 = load i64, ptr @initarr_pp_mm_PrintFigure store i64 %4, ptr %Size store i64 0, ptr %Iter br label %for.cond

for.cond:

%6 = load i64, ptr %Iter %7 = load i64, ptr %Size %8 = icmp ult i64 %6, %7 br i1 %8, label %for.body, label %for.end

for.body:

%9 = load i64, ptr %Iter

%10 = load ptr, ptr @initarr_pp_mm_PrintFigure

%11 = getelementptr inbounds ptr, ptr %10, i64 %9 %12 = load i64, ptr %11

store ptr @default_pp_mm_PrintFigure, ptr %11 %13 = load i64, ptr %11 br label %for.inc

for.inc:

%14 = load i64, ptr %Iter %15 = add i64 %14, 1 store i64 %15, ptr %Iter br label %for.cond

for.end:

%16 = load i64, ptr @initarr_pp_mm_PrintFigure ret void

}

Приложение А.7 Регистрация обработчика специализации

define void @record_pp_mm_PrintFigure_Figure_rect() { entry:

%0 = load i32, ptr @tag_Figure_rect %1 = sub nsw i32 %0, 1 %2 = sext i32 %1 to i64

%3 = load ptr, ptr @initarr_pp_mm_PrintFigure %4 = getelementptr inbounds ptr, ptr %3, i64 %2 store ptr @pp_mm_PrintFigure_Figure_rect, ptr %4 ret void

}

Приложение А.8 Реализация функции init_spec

define linkonce_odr void @init_spec_Figure_Triangle(ptr noundef %0) #2 {

entry:

%pp_head = getelementptr inbounds %struct._pp_struct_Figure_Triangle, ptr %0, i32 0,

i32 0

%pp_spec_type = getelementptr inbounds %struct.Figure, ptr %pp_head, i32 0, i32 1

%global_spec_tag = load i32, ptr @tag_Figure_Triangle, align 4

store i32 %global_spec_tag, ptr %pp_spec_type, align 4 ret void

}

Приложение А.9 Реализация функции create_spec

define ptr @create_spec_Figure_Triangle() {

entry:

%Size = alloca i64, align 8 store i64 24, ptr %Size, align 8 %0 = load i64, ptr %Size, align 8 %call_malloc = call ptr @malloc(i64 noundef %0)

%pp_head = getelementptr inbounds %struct.Figure_Triangle, ptr %call_malloc, i32 0,

i32 0

%pp_spec_type = getelementptr inbounds %struct.Figure, ptr %pp_head, i32 0, i32 1

%global_spec_tag = load i32, ptr @tag_Figure_Triangle, align 4

store i32 %global_spec_tag, ptr %pp_spec_type, align 4 ret ptr %call_malloc

Приложение А.10 Реализация функции spec_index_cmp

define i32 @spec_index_cmp_Figure(ptr %0, ptr %1) { entry:

%retval = alloca i32, align 4

%pp_spec_type = getelementptr inbounds %struct.Figure, ptr %0, i32 0, i32 1 %pp_spec_type1 = getelementptr inbounds %struct.Figure, ptr %1, i32 0, i32 1 %2 = load i32, ptr %pp_spec_type, align 4 %3 = load i32, ptr %pp_spec_type1, align 4 %4 = icmp eq i32 %2, %3 br i1 %4, label %if.then, label %if.end if.then:

store i32 %2, ptr %retval, align 4 br label %return if.end:

store i32 -1, ptr %retval, align 4 br label %return return:

%5 = load i32, ptr %retval, align 4 ret i32 %5

}

Приложение А.11 Реализация функции выделения памяти под массив обработчикок

define weak void @pp_init_cs_arr_Figure() { entry:

%0 = load i32, ptr @tags_Figure, align 4 %1 = add nsw i32 %0, 1 %2 = sext i32 %1 to i64 %3 = mul i64 8, %2

%call_malloc = call ptr @malloc(i64 noundef %3) #1 store ptr %call_malloc, ptr @pp_cs_arr_Figure, align 8 ret void

}

Приложение А.12 Запись обработчиков в массив

define weak void @record_cs_Figure_Circle() {

entry:

%0 = load i32, ptr @tag_Figure_Circle, align 4

%1 = sext i32 %0 to i64

%2 = load ptr, ptr @pp_cs_arr_Figure, align 8 %3 = getelementptr inbounds ptr, ptr %2, i64 %1

store ptr @create_spec_Figure_Circle, ptr %3, align 8

ret void

}

Приложение А.13 Реализация функции get_spec_ptr

define ptr @get_spec_ptrFigure(i32 noundef %0) #2 { entry:

%1 = sext i32 %0 to i64

%2 = load ptr, ptr @pp_cs_arr_Figure, align 8 %3 = getelementptr inbounds ptr, ptr %2, i64 %1 %4 = load ptr, ptr %3, align 8 %call_res = call ptr %4() ret ptr %call_res

Приложение А.14 Реализация функции get_spec_size

define i32 @get_spec_sizeFigure() #2 { entry:

%tags = load i32, ptr @pp_tags_Figure, align 4 %0 = add nsw i32 %tags, 1 ret i32 %0

}

Приложение А.15 Иерархия вызовов функций внутри функции jl_lookup_generic

1) Вызов функции 1оокир_а^_уре_ир1е

• jl_lookup_arg_tuple_type

• lookup_typevalue

• typekeyvalue_hash

• typekey_hash

• type_hash

• bitmix

• int64hash

• lookup_type_setvalue

• typekeyvalue_eq

• jl_types_equal

• lookup_type_idx_linearvalue

2) Вызов функции lookup_leafcache

• jl_eqtable_get

• jl_table_peek_bp

• hash_size

• max_probe

• keyhash

• к2Мех

3) Вызов функции jl_typemap_assoc_exact

• jl_typemap_entry_assoc_exact

• sig_match_leaf

• sig_match_simple

• jl_subtype

• jl_subtype_env

• init_stenv

• memset

• fix_inferred_var_bound

• forall_exists_subtype

• _forall_exists_subtype

• save_env

• alloc_env * (иерархия развернута ниже)

• exists_subtype

• re_save_env

• free_env

• next_union_state

• jl_typemap_level_assoc_exact

• arg_type_tuple

* alloc_env

• malloc_s

• jl_alloc_svec

• memset

• jl_alloc_svec_uninit

• jl_gc_alloc

• _bшltint_constant_p

• jl_gc_alloc_

• jl_gc_szclass

• jl_gc_pool_alloc_noinline

• jl_gc_pool_alloc_inner

• maybe_collect

• jl_gc_collect

• gc_page_data

• page_metadata_unsafe

• gc_add_page

• msan_allocated_memory

• jl_throw

• jl_gc_big_alloc_noinline

• maybe_record_alloc_to_profile

Приложение А.16 Использование интерфейсов в Go

type Writer interface {

Write([]byte) (int, error)

}

type File struct{ /* ... */ }

func (f File) Write(data []byte) (int, error) { /* ... */ } type NetworkSocket struct{ /* ... */ }

func (n NetworkSocket) Write(data []byte) (int, error) { /* ... */ }

func main() { var w Writer

w = File{} // Динамическое присвоение

w.Write([]byte{}) // Вызов File.Write()

w = NetworkSocket{} // Динамическое присвоение

w.Write([]byte{}) // Вызов NetworkSocket.Write()

}

Приложение А.17 Ручная реализация виртуальных таблиц в Linux

static const struct seq_operations proc_pid_maps_op = { .start= m_start, .next = m_next, .stop = m_stop, .show = show_map

};

static const struct seq_operations bpffs_map_seq_ops = { .start = map_seq_start, .next = map_seq_next, .show = map_seq_show, .stop = map_seq_stop,

Приложение А.18 Ручная реализация виртуальной таблицы на С

typedef struct {

void (*draw)(void *self); void (*move)(void *self, int dx, int dy); } ShapeVTable;

typedef struct {

ShapeVTable *vtbl; int x, y; } Shape;

Приложение А.19 Пример использования библиотеки Yomm2

// Стандартные структуры С++ struct Figure { ... }; struct Rectangle : Figure { ... }; struct Triangle : Figure { . }; struct Circle : Figure { ... };

// Регистрация иерархии структур

register_classes(Figure, Rectangle, Triangle, Circle); // Описание открытого метода

declare_method(void, PrintFigure, (virtual_<const Figure&>)); // Описание специализаций открытого метода

define_method(void, PrintFigure, (const Rectangle& expr)) { ... } define_method(void, PrintFigure, (const Triangle& expr)) { ... } define_method(void, PrintFigure, (const Circle& expr)) { ... }

int main() {

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

yomm2::update();

Rectangle r;

// Вызов открытого метода PrintFigure(r);

}

Вызов открытого метода с одним параметром происходит следующим образом (упрощенный псевдокод):

mtbls[ H(&typeid(Rectangle)) ] // mtable для типа Rectangle

// mtbls - статическая хэш-таблица методов // для всех типов

[ method<PrintFigure>::slots_strides[0] ] // получаем указатель на нужный метод (bill) // вызов метода

При вызове мультиметода с двумя параметрами аналогичный доступ к mtbls происходит дважды:

// Описание открытого метода вписывающего одну фигуру в другую

declare_method(void, Inscribe, (virtual_<const Figure&>, virtual_<const Figure&>)); // Описание специализации

declare_method(void, Inscribe, (const Circle& c, const Rectangle& r)) { ... }

std::uintptr_t* slots_strides = method<Inscribe>::slots_strides; // В таком случае (в отличии от предыдущего примера) // slots_strides содержит массив из 3 значений: // 1 - индекс для первого типа // 2 - количество элементов в строке таблицы // 3 - индекс для второго типа

// Данные значения используются для вычисления специализированного обработчика в таблице mtbls[ H(&typeid(Circle)) ] // таблица методов для Circle

[ slots_strides[0] ] // индекс для первого типа

[ mtbls [ H(&typeid(Rectangle)) ] // таблица методов для Rectangle

[ slots_strides[2] ] // индекс для второго типа

* slots_strides[1] // кол-во элементов в строке

] // указатель на функцию

(c, r) // вызов специализированного обработчика

Также стоит отметить возможность в данной библиотеке вызывать предыдущую наиболее подходящую специализацию по иерархии наследования с помощью функции next(). Пример:

declare_method(void, Inscribe, (const Circle& c, const Rectangle& r)) { next(c, r); // Вызов предыдущего обработчика специализации // Реализация данного обработчика

}

Приложение А.20 Использование Rust библиотеки multimethods.rs

use multimethods::multifunction;

multifunction! {

pub fn HELLO() {

println!("Hello, World!");

}

pub fn HELLO(x: &'static str) { println!("Hello, {}!", x);

}

pub fn HELLO(x: String) {

println!("Hello, Stringified {}!", x);

}

}

fn main() {

HELLO(); // Outputs: Hello, World!

HELLo("John"); // Outputs: Hello, John!

HELLo("John".to_string()); // Outputs: Hello, Stringified John!

}

Приложение А.21 Реализация диспечеризующей функции, основанной на операторе switch для мультиметода с тремя параметрами

void Inscribe3D(Shape *s1, Shape *s2, Shape *s3) { switch(s1->type) {

case CIRCLE: {

Circle *c1 = (Circle *)s1; switch(s2->type) { case CIRCLE:

Circle *c2 = (Circle *)s2; switch(s3->type) { case CIRCLE:

Circle *c3 = (Circle *)s3; invoke_spec_circ_circ_circ(c1, c2, c3); break; case RECTANGLE:

Обратите внимание, представленные выше научные тексты размещены для ознакомления и получены посредством распознавания оригинальных текстов диссертаций (OCR). В связи с чем, в них могут содержаться ошибки, связанные с несовершенством алгоритмов распознавания. В PDF файлах диссертаций и авторефератов, которые мы доставляем, подобных ошибок нет.