stringtranslate.com

Программирование, ориентированное на функции

В компьютерном программировании функционально -ориентированное программирование ( FOP ) или функционально-ориентированная разработка программного обеспечения ( FOSD ) — это парадигма программирования для генерации программ в линейках программных продуктов (SPL) и для поэтапной разработки программ.

История

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

FOSD возник из основанных на слоях конструкций и уровней абстракции в сетевых протоколах и расширяемых системах баз данных в конце 1980-х годов. [1] Программа представляла собой стек слоев. Каждый слой добавлял функциональность к ранее составленным слоям, а различные композиции слоев производили различные программы. Неудивительно, что возникла необходимость в компактном языке для выражения таких конструкций. Элементарная алгебра отвечала всем требованиям: каждый слой представлял собой функцию ( преобразование программы ), которая добавляла новый код к существующей программе для создания новой программы, а конструкция программы моделировалась выражением, т. е. композицией преобразований (слоев). Рисунок слева иллюстрирует наложение слоев i, j и h (где h находится внизу, а i — наверху). Для выражения этих конструкций использовались алгебраические обозначения i(j(h)), i•j•h и i+j+h.

Со временем слои были приравнены к функциям, где функция является приращением в функциональности программы. Парадигма проектирования и генерации программ была признана как результат оптимизации реляционных запросов, где программы оценки запросов были определены как выражения реляционной алгебры, а оптимизация запросов была оптимизацией выражений. [2] Линейка программных продуктов представляет собой семейство программ, где каждая программа определяется уникальным составом функций. С тех пор FOSD превратилась в изучение модульности функций, инструментов, анализов и методов проектирования для поддержки генерации программ на основе функций.

Второе поколение исследований FOSD было посвящено взаимодействиям функций, которые возникли в телекоммуникациях. Позже был придуман термин программирование, ориентированное на функции ; [3] эта работа выявила взаимодействия между слоями. Взаимодействия требуют адаптации функций при составлении с другими функциями.

Третье поколение исследований было сосредоточено на том факте, что каждая программа имеет несколько представлений (например, исходный код, make-файлы, документация и т. д.), и добавление функции в программу должно разрабатывать каждое из ее представлений так, чтобы все они были согласованными. Кроме того, некоторые представления могут быть сгенерированы (или получены) из других. В разделах ниже описывается математика трех последних поколений FOSD, а именно GenVoca, [1] AHEAD, [4] и FOMDD [5] [6] , а также предоставляются ссылки на линейки продуктов, которые были разработаны с использованием инструментов FOSD. Кроме того, четыре дополнительных результата, которые применимы ко всем поколениям FOSD, это: метамодели FOSD , кубы программ FOSD и взаимодействия функций FOSD.

GenVoca

GenVoca ( гибрид названий Genesis и Avoca) [1] — это композиционная парадигма для определения программ линеек продуктов. Базовые программы — это 0-арные функции или преобразования, называемые значениями :

 f -- базовая программа с функцией f h -- базовая программа с функцией h

а функции — это унарные функции/преобразования, которые разрабатывают (изменяют, расширяют, совершенствуют) программу:

 i + x — добавляет функцию i в программу x j + x — добавляет функцию j в программу x

где + обозначает композицию функций. Дизайн программы — это именованное выражение, например:

 p 1 = j + f — программа p 1 имеет функции j и f p 2 = j + h — программа p 2 имеет функции j и h p 3 = i + j + h — программа p 3 имеет функции i, j и h

Модель GenVoca домена или линейки программных продуктов представляет собой набор базовых программ и функций (см. MetaModels и Program Cubes ). Программы (выражения), которые могут быть созданы, определяют линейку продуктов. Оптимизация выражений — это оптимизация проектирования программ , а оценка выражений — это генерация программ .

Примечание: GenVoca основана на пошаговой разработке программ: процессе, который подчеркивает простоту и понятность дизайна, которые являются ключом к пониманию программы и автоматизированному построению программы. Рассмотрим программу p 3 выше: она начинается с базовой программы h, затем добавляется функция j (читай: функциональность функции j добавляется к кодовой базе h), и, наконец, добавляется функция i (читай: функциональность функции i добавляется к кодовой базе j•h).
Примечание: не все комбинации признаков имеют смысл. Модели признаков (которые могут быть переведены в пропозициональные формулы) являются графическими представлениями, которые определяют допустимые комбинации признаков. [7]
Примечание: более поздняя формулировка GenVoca симметрична : есть только одна базовая программа, 0 (пустая программа), и все функции являются унарными функциями. Это предполагает интерпретацию, что GenVoca составляет структуры программ путем суперпозиции , идея о том, что сложные структуры составляются путем наложения более простых структур. [8] [9] Еще одна переформулировка GenVoca — как моноид : модель GenVoca представляет собой набор функций с операцией композиции (•); композиция ассоциативна и есть элемент идентичности (а именно 1, функция идентичности). Хотя все композиции возможны, не все из них имеют смысл. Вот причина для моделей функций .

Функции GenVoca изначально были реализованы с использованием методов препроцессора C ( #ifdef feature ... #endif). Более продвинутая техника, называемая слоями миксинов , показала связь функций с объектно-ориентированными проектами на основе совместной работы.

ПРЕДСТОЯЩИЙ

Алгебраические иерархические уравнения для проектирования приложений ( AHEAD ) [4] обобщили GenVoca двумя способами. Во-первых, они раскрыли внутреннюю структуру значений GenVoca как кортежи. Каждая программа имеет несколько представлений, таких как источник, документация, байт-код и make-файлы. Значение GenVoca — это кортеж представлений программы. Например, в линейке продуктов парсеров базовый парсер f определяется его грамматикой g f , исходным кодом Java s f и документацией d f . Парсер f моделируется кортежем f=[g f , s f , d f ]. Каждое представление программы может иметь подпредставления, и они тоже могут иметь подпредставления, рекурсивно. В общем случае значение GenVoca — это кортеж вложенных кортежей, которые определяют иерархию представлений для конкретной программы.

Иерархические отношения между программными артефактами

Пример. Предположим, что терминальные представления — это файлы. В AHEAD грамматика g f соответствует одному файлу BNF, источник s f соответствует кортежу файлов Java [c 1 …c n ], а документация d f — кортежу файлов HTML [h 1 …h k ]. Значение GenVoca (вложенные кортежи) можно изобразить в виде направленного графа: граф для парсера f показан на рисунке справа. Стрелки обозначают проекции, т. е. отображения кортежа на один из его компонентов. AHEAD реализует кортежи как файловые каталоги, поэтому f — это каталог, содержащий файл g f и подкаталоги s f и d f . Аналогично, каталог s f содержит файлы c 1 …c n , а каталог df содержит файлы h 1 …h k .

Примечание: Файлы могут быть иерархически разложены далее. Каждый класс Java может быть разложен на кортеж членов и других объявлений классов (например, блоки инициализации и т. д.). Важная идея здесь заключается в том, что математика AHEAD является рекурсивной.

Во-вторых, AHEAD выражает функции как вложенные кортежи унарных функций, называемых дельтами . Дельты могут быть уточнениями программы (преобразованиями, сохраняющими семантику), расширениями (преобразованиями, расширяющими семантику) или взаимодействиями (преобразованиями, изменяющими семантику). Мы используем нейтральный термин «дельта» для обозначения всех этих возможностей, поскольку каждая из них встречается в FOSD.

Для иллюстрации предположим, что функция j расширяет грамматику на Δg j (добавляются новые правила и токены), расширяет исходный код на Δs j (добавляются новые классы и члены, а существующие методы изменяются) и расширяет документацию на Δd j . Кортеж дельт для функции j моделируется как j=[Δg j ,Δs j ,Δd j ], который мы называем дельта-кортежем . Элементы дельта-кортежей сами могут быть дельта-кортежами. Пример: Δs j представляет изменения, которые вносятся в каждый класс в s f функцией j, т. е. Δs j =[Δc 1 …Δc n ]. Представления программы вычисляются рекурсивно путем вложенного сложения векторов. Представления для парсера p 2 (чье выражение GenVoca равно j+f) следующие:

 p 2 = j + f -- выражение GenVoca = [Δg j , Δs j , Δd j ] + [g f , s f , d f ] -- подстановка = [Δg j +g f , Δs j +s f , Δd j +d f ] — составить кортежи поэлементно

То есть грамматика p 2 является базовой грамматикой, составленной с ее расширением (Δg j +g f ), источник p 2 является базовым источником, составленным с ее расширением (Δs j +s f ), и так далее. Поскольку элементы дельта-кортежей сами могут быть дельта-кортежами, композиция рекурсивна, например, Δs j +s f = [Δc 1 …Δc n ]+[c 1 …c n ]=[Δc 1 +c 1 …Δc n +c n ]. Подводя итог, значения GenVoca являются вложенными кортежами программных артефактов, а признаки являются вложенными дельта-кортежами, где + рекурсивно составляет их путем сложения векторов. Это суть AHEAD.

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

Первоначальная реализация AHEAD — это AHEAD Tool Suite и язык Jak, которые демонстрируют как Принципы Единообразия, так и Масштабируемости. Инструменты следующего поколения включают CIDE [10] и FeatureHouse. [11]

FOMDD

Отношения вывода и уточнения между программными артефактами

Feature-Oriented Model-Driven Design ( FOMDD ) [5] [6] объединяет идеи AHEAD с Model-Driven Design ( MDD ) (также известной как Model-Driven Architecture ( MDA )). Функции AHEAD фиксируют синхронное обновление программных артефактов при добавлении в программу функции. Но существуют и другие функциональные связи между программными артефактами, которые выражают деривации. Например, связь между грамматикой g f и ее исходным парсером s f определяется инструментом компилятора-компилятора, например, javacc. Аналогично связь между исходным Java s f и его байт-кодом b f определяется компилятором javac. Диаграмма коммутации выражает эти связи. Объекты являются представлениями программы, направленные вниз стрелки являются деривациями, а горизонтальные стрелки являются дельтами. На рисунке справа показана диаграмма коммутации для программы p 3 = i+j+h = [g 3 ,s 3 ,b 3 ].

Фундаментальным свойством коммутирующей диаграммы является то, что все пути между двумя объектами эквивалентны. Например, один из способов вывести байт-код b 3 парсера p 3 (нижний правый объект на рисунке справа) из грамматики g h парсера h (верхний левый объект) — вывести байт-код b h и уточнить до b 3 , в то время как другой способ уточняет g h до g 3 , а затем вывести b 3 , где + представляет собой дельта-композицию, а () — это функция или применение инструмента:

b 3 = Δb j + Δb i + javacc ( javac ( g h ) ) = javac ( javacc ( Δg i + Δg j + g h ) )

Существуют возможные пути для получения байт-кода b 3 парсера p 3 из грамматики g h парсера h. Каждый путь представляет собой метапрограмму , выполнение которой генерирует целевой объект (b 3 ) из начального объекта (g f ). Существует потенциальная оптимизация: прохождение каждой стрелки коммутирующей диаграммы имеет стоимость. Самый дешевый (т. е. кратчайший) путь между двумя объектами в коммутирующей диаграмме — это геодезический , который представляет собой наиболее эффективную метапрограмму, которая производит целевой объект из заданного объекта.

Примечание: «Показатель стоимости» не обязательно должен быть денежным значением; стоимость может измеряться во времени производства, пиковых или общих требованиях к памяти, энергопотреблении или какой-либо неформальной метрике, такой как «простота объяснения», или комбинацией вышеперечисленного (например, многоцелевая оптимизация ). Идея геодезической является общей и должна пониматься и оцениваться в этом более общем контексте.
Примечание: на геодезической линии может быть m начальных объектов и n конечных объектов; когда m=1 и n>1, это задача направленного дерева Штейнера , которая является NP-трудной.

Диаграммы коммутации важны по крайней мере по двум причинам: (1) существует возможность оптимизации генерации артефактов (например, геодезических) и (2) они определяют различные способы построения целевого объекта из исходного объекта. [5] [12] Путь через диаграмму соответствует цепочке инструментов: для того, чтобы модель FOMDD была последовательной, должно быть доказано (или продемонстрировано посредством тестирования), что все цепочки инструментов, которые сопоставляют один объект с другим, на самом деле дают эквивалентные результаты. Если это не так, то либо в одном или нескольких инструментах есть ошибка, либо модель FOMDD неверна.

Примечание: приведенные выше идеи были вдохновлены теорией категорий . [5] [6]

Приложения

Смотрите также

Ссылки

  1. ^ abc «Проектирование и реализация иерархических программных систем с повторно используемыми компонентами» (PDF) .
  2. Выбор пути доступа в реляционных базах данных. 30 мая 1979 г. С. 23–34. doi :10.1145/582095.582099. ISBN 9780897910019. S2CID  8537523.
  3. ^ "Feature-Oriented Programming: A Fresh Look at Objects". Архивировано из оригинала 2003-08-03 . Получено 2015-12-16 .
  4. ^ ab «Масштабирование пошагового уточнения» (PDF) .
  5. ^ abcd «Разработка на основе ориентированных на функции моделей: пример портлетов» (PDF) .
  6. ^ abc Трухильо, Сальвадор; Азанса, Майдер; Диас, Оскар (октябрь 2007 г.). «Генеративное метапрограммирование». Труды 6-й международной конференции по генеративному программированию и компонентной инженерии . стр. 105–114. doi :10.1145/1289971.1289990. ISBN 9781595938558. S2CID  236715.
  7. ^ «Модели признаков, грамматики и пропозициональные формулы» (PDF) .
  8. ^ «Алгебра для признаков и композиции признаков» (PDF) .
  9. ^ «Наложение: независимый от языка подход к составлению программного обеспечения» (PDF) .
  10. ^ «Гарантирование синтаксической корректности для всех вариантов линейки продуктов: независимый от языка подход» (PDF) .
  11. ^ «FeatureHouse: Независимая от языка автоматизированная разработка программного обеспечения» (PDF) .
  12. ^ «Тестирование линеек программных продуктов с использованием инкрементальной генерации тестов» (PDF) .