<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta />
    <article-meta>
      <title-group>
        <article-title>Инструментальная поддержка эволюционного расширения программ при инкрементальной разработке</article-title>
      </title-group>
      <fpage>346</fpage>
      <lpage>359</lpage>
      <abstract>
        <p>Аннотация. В настоящее время используются разнообразные подходы к эволюционной разработке программ. Ряд их широко применяется на практике, найдя воплощение в различных техниках и парадигмах программирования. В статье рассматриваются особенности программных объектов современных языков программирования, обеспечивающих поддержку эволюционной разработки программного обеспечения. Среди множества существующих методов можно выделить те, которые ориентированы на поддержку полиморфизма, позволяющего изменять поведение процедур или функций за счет динамического связывания во время выполнения. Проводится сравнение подходов, используемых в процедурной, объектно-ориентированной, процедурно-параметрической парадигмах, а также использование интерфейсов в языке программирования Go. За исключением процедурной парадигмы все прочие подходы предлагают свои варианты реализации полиморфизма, сопоставление которых представляет определенный интерес для разработчиков перспективных языков программирования. Предлагается набор базовых ситуаций инкрементального расширения программ, на основе которого осуществляется сопоставление различных подходов: расширение обобщений специализациями; добавление новых процедур, обеспечивающих дополнительную функциональность; добавление новых полей данных в существующие типы; добавление новых процедур, предназначенных для обработки только одной из специализаций; создание нового обобщения на основе существующих специализаций; добавление в программу мультиметода; изменение мультиметодов при добавлении новых специализаций. Оцениваются возможности использования разных методов полиморфизма в языке функционально-потокового параллельного программирования.</p>
      </abstract>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>-</title>
      <p>Сибирский федеральный университет</p>
      <p>Annotation. Currently used a different approaches to the evolutionary software
development. A number of them are widely used in practice and are embodied in
various programming techniques and programming paradigms. The article discusses
the features of software objects of modern programming languages that provide
support for evolutionary software development. Among the many existing methods,
we can distinguish those that are focused on supporting polymorphism, which allows
changing the behavior of procedures or functions using a dynamic binding during
execution. We compare the approaches which used in the procedural, object-oriented,
procedural-parametric paradigms, as well as the use of interfaces in the Go
programming language. With the exception of the procedural paradigm, all other
approaches offer their own variants for the implementation of polymorphism, the
comparison of which is of particular interest to developers of promising programming
languages. We propose a set of basic situations of incremental program expansion, on
the basis of which various approaches are compared. This are the extension of
generalizations by using specializations; adding new procedures that provide
additional functionality; adding new data fields to existing data types; adding new
procedures designed to process only one of the specializations; creating a new
generalization based on existing specializations; adding a multimethod to the program;
change of multimethods when adding new specializations. The possibilities of using
different methods of polymorphism are evaluated for the functional parallel
programming language which using dataflow control.
Введение
Эволюционная разработка больших программных систем приобретает все
большую популярность. Это обусловлено различными факторами, связанными
с развитием информационных технологий. В частности:
• широко используемые гибкие методы разработки программного
обеспечения (ПО) ориентированы на инкрементальное наращивание кода;
• современные языки и системы программирования содержат
средства, обеспечивающие поддержку эволюционного проектирования;
• эволюционное расширение программных
более выгодно, чем использование методов,
постоянную модификацию уже написанного кода;
систем экономически
ориентированных на
• использование эволюционного расширения программ уменьшает
количество ошибок, вносимых в написанный и уже отлаженный код,
который постоянно приходится модифицировать при использовании
традиционных методов разработки программного обеспечения.</p>
      <p>
        В настоящее время используются разнообразные подходы к
эволюционной разработке программ. Ряд их широко применяется на практике,
найдя воплощение в различных техниках и парадигмах программирования.
Вместе с тем современные инструментальные средства, поддерживающие
эволюционную разработку, обладают определенными ограничениями и не
всегда позволяют достичь желаемого эффекта. Поэтому наряду с ними широко
применяются методы, обеспечивающие инкрементальное наращивание кода за
счет использования разнообразных алгоритмических приемов. В настоящее
время эти приемы отражены в образцах (паттернах) проектирования [
        <xref ref-type="bibr" rid="ref1">1</xref>
        ],
которые стали особенно популярны при использовании методов
объектноориентированной разработки программ.
      </p>
      <p>
        Среди множества существующих методов можно выделить те, которые
ориентированы на поддержку полиморфизма, позволяющего изменять
поведение процедур или функций за счет динамического связывания во время
выполнения. Их особенностью является ориентация на формирование
конструкций базовых программных объектов, задающих процедуры и данные, и
то, что они могут интегрироваться с любыми другими методами эволюционного
расширения программ. К данной категории относятся механизмы
виртуализации и наследования, применяемые в объектно-ориентированном
программировании (ООП) [
        <xref ref-type="bibr" rid="ref2">2</xref>
        ], процедурно-параметрические обобщения и их
обработчики в процедурно-параметрическом программировании (ППП) [
        <xref ref-type="bibr" rid="ref3 ref4">3, 4</xref>
        ]. К
последним решениям в данной области относится предложенный в языке
программирования Go механизм интерфейсов, позволивший отказаться от
наследования и вместе с тем сохранивший возможности, обеспечивающие
поддержку полиморфизма, аналогичного объектно-ориентированному (ОО) [
        <xref ref-type="bibr" rid="ref5">5</xref>
        ].
Имеющиеся при этом отличия можно охарактеризовать как Go-подход,
появление которого позволяет провести дополнительные сравнения
возможностей эволюционного расширения по сравнению с ранее проведенным
анализом [
        <xref ref-type="bibr" rid="ref6">6</xref>
        ]. Каждый из представленных подходов имеет свои особенности и
обеспечивает поддержку определенных ситуаций, возникающих при
инкрементальном развитии программ. Поэтому представляет интерес их
изучение и сопоставление. Сравнение осуществляется на основе анализа
возможностей языковых средств обеспечить безболезненное расширение
программы в одной из рассматриваемых простых (базовых) ситуаций.
Предполагается, что ситуация должна быть реализована непосредственно
конструкциями языка без написания дополнительного кода. Сравнение
возможностей эволюционного расширения программ проводится для
следующих ситуаций:
1. расширение обобщений специализациями и, как следствие,
расширение обрабатывающих их обобщающих процедур;
      </p>
      <p>2. добавление новых процедур, обеспечивающих дополнительную
функциональность;</p>
      <p>3. добавление новых полей данных в существующие типы и изменение в
соответствии с этим процедур, осуществляющих обработку измененных
программных объектов;</p>
      <p>4. добавление новых процедур, предназначенных для обработки только
одной из специализаций некоторого обобщения;
5. создание нового обобщения на основе существующих специализаций;
6. добавление в программу мультиметодов, осуществляющих обработку
двух или более обобщенных параметров;</p>
      <p>7. изменение мультиметодов при добавлении новых специализаций в
обобщения, используемые в качестве аргументов мультиметодов.
Сравнение осуществляется для следующих парадигм:
•
•
процедурного программирования;
объектно-ориентированного программирования;
• механизма интерфейсов, реализованного в языке программирования
Go (Go-подход);
• процедурно-параметрического программирования.</p>
      <p>Далее процедура и функция воспринимаются как синонимы, что вполне
соответствует их эквивалентной трактовке в различных языках
программирования.</p>
      <p>
        1. Добавление новых специализаций в обобщение
Процедурный подход. В традиционных процедурных языках для
построения обобщений обычно используются объединения (в языке C [
        <xref ref-type="bibr" rid="ref7">7</xref>
        ]) или
вариантные записи (языки Pascal [
        <xref ref-type="bibr" rid="ref8">8</xref>
        ], Modula-2 [
        <xref ref-type="bibr" rid="ref9">9</xref>
        ]), что при расширении требует
модификации уже написанного кода. Безболезненного расширения данных в
этих языках можно достичь использованием указателя на произвольный тип,
что снижает безопасность программного кода [
        <xref ref-type="bibr" rid="ref10">10</xref>
        ] из-за появляющейся
возможности некорректного использования такого указателя. Вместе с тем,
иногда допускается использование наследования на уровне данных, что
позволяет безболезненно расширять специализации в таких процедурных и
мультипарадигменных языках как Оберон [
        <xref ref-type="bibr" rid="ref11">11</xref>
        ], Оберон-2 [
        <xref ref-type="bibr" rid="ref12">12</xref>
        ], Ada [
        <xref ref-type="bibr" rid="ref13">13</xref>
        ], C++ [
        <xref ref-type="bibr" rid="ref14">14</xref>
        ]
и других.
      </p>
      <p>
        Однако в любом случае при процедурном подходе формирование новых
специализаций ведет к добавлению их обработчиков, которые обычно
реализуются как новые ветви уже существующего условного оператора или
эквивалентного ему оператора выбора (переключения), вставляемые в
имеющиеся процедуры, обрабатывающие это обобщение, что не способствует
эволюционному расширению написанного кода.
Объектно-ориентированный подход. Для добавления специализации в
языках программирования Оберон-2 и Ada применяется расширение типа. Для
добавления новых обработчиков специализаций используются процедуры,
связанные с типом. В C++, C# [
        <xref ref-type="bibr" rid="ref15">15</xref>
        ], Java [
        <xref ref-type="bibr" rid="ref16">16</xref>
        ] и других
объектноориентированных языках в качестве специализации создается производный
класс, а обработчики специализации реализуются посредством виртуальных
методов, расширяющих обобщающий виртуальный метод базового класса.
Таким образом, ООП поддерживает безболезненное расширение в данной
ситуации.
      </p>
      <p>Go-подход. Обобщение формируется как интерфейс, задающий набор
функций, связанных с любыми типами структур, реализующих их. То есть в
нем отсутствует какая-либо привязка к типам данных, что обеспечивает
безболезненное добавление новых структур-специализаций и создание функций,
связанных с их типом и входящих в этот интерфейс.</p>
      <p>
        Процедурно-параметрический подход. Обеспечивает добавление новых
специализаций через их подключение к обобщению за счет существующей в
языке внешней операции добавления [
        <xref ref-type="bibr" rid="ref3 ref4">3, 4</xref>
        ]. Необходимые обработчики
специализаций также легко расширяют уже существующие обобщающие
процедуры за счет дописывания новых реализаций.
      </p>
      <p>2. Добавление процедур с дополнительной функциональностью
Процедурный и процедурно-параметрический подходы.
Использование внешних процедур обеспечивает простое решение данной
задачи. Не возникает никаких проблем с их безболезненным добавлением в
новых единицах компиляции. Подобный подход успешно применим
практически во всех языках процедурного программирования.</p>
      <p>Объектно-ориентированный подход. ОО парадигма напрямую не
поддерживает эволюционного добавления новых методов, расширяющих
функциональность класса. Метод, реализующий дополнительную
функциональность, приходится вставлять внутрь класса, что ведет к изменению
интерфейса последнего. Если изменяемый класс является базовым, даже при
изменении только интерфейса произойдет перекомпиляция всех модулей,
которые зависят как от этого класса, так и его производных классов. В языке
программирования C# новый метод можно вынести в другой файл. Однако его
сборка с основным классом все равно осуществляется за счет перекомпиляции.</p>
      <p>Go-подход. Так как специализации между собой не связаны, добавление
новых функций для каждой структуры данных протекает безболезненно и
осуществляется за счет использования функций, связанных с типом. Изменение
могут коснуться интерфейса, если необходима интеграция новой функции с уже
существующими. Однако в большинстве случаев возможно использование
нового интерфейса, обобщающего только добавляемую функцию, что и
обеспечивает в общем случае безболезненность добавления процедуры.
3. Добавление новых полей в существующие типы
Прямое добавление новых полей в запись или класс ведет к его
изменению независимо от избранного стиля программирования. Поэтому, при
необходимости модификации типа с сохранением возможности безболезненно
расширять программу, используются обходные пути, опирающиеся на
косвенное связывание. В этом случае осуществляется связывание через
указатель на базовый тип, к которому подключается объект производного типа,
содержащий дополнительные поля. При обработке такого объекта необходимо
использовать явное приведение типа или дополнительные функции. Если
подобные действия приходится применять в ранее написанных модулях, то
эволюционное расширение программы невозможно. Однако часто программа,
использующая модифицированный тип, может быть расширена таким образом,
что его обработка осуществляется только в добавленных единицах компиляции.</p>
      <p>Процедурный подход. Для добавления полей косвенным связыванием в
языке программирования Оберон удобно пользоваться расширением типов. В
этом случае новый тип расширяет предшественника, и через указатель на
базовый тип может использоваться по целевому назначению. Встроенный в
язык механизм проверки типа во время выполнения позволяет перейти от
базового типа к производному. Поэтому можно считать, что поздние
процедурные языки поддерживают добавление новых полей. Следует, однако,
отметить, что традиционные процедурные языки (C, Pascal) не обеспечивают
реализацию подобного приема из-за отсутствия механизма проверки типа во
время выполнения. Поэтому их использование в таком режиме невозможно без
написания дополнительного кода.</p>
      <p>Объектно-ориентированный подход. Добавление новых полей, как и
при расширении типов, осуществляется в производном классе. При
использовании языков, поддерживающих динамическую идентификацию типа
во время выполнения, использование классов аналогично применению
расширений типов, описанному для процедурных языков. В этом случае наряду
с данными можно включать и новые методы, осуществляющие их обработку.
Вместе с тем, следует отметить, что использование явной проверки типа во
время выполнения в большей степени является процедурным, чем
объектноориентированным приемом, так как объектно-ориентированный полиморфизм
базируется на сочетании наследования и виртуализации.</p>
      <p>При отсутствии динамической проверки типа или отключения этого
режима (например, в C++) использование косвенного добавления полей в класс
становится невозможным. Для его реализации необходимы дополнительные
алгоритмические приемы, например, включение в базовый класс виртуального
метода, переопределяемого в производных классах, за счет чего обеспечивается
требуемая идентификация. Таким образом, использование
объектноориентированного полиморфизма в данной ситуации невозможно без
дополнительной алгоритмической поддержки.</p>
      <p>Go-подход. Отсутствие механизмов прямого расширения структур данных
не позволяет безболезненно добавить новые поля.</p>
      <p>Процедурно-параметрический подход. Использование косвенного
добавления полей допускается при использовании обобщенных записей. В этом
случае расширение заключается в добавлении специализации. Доступ к
специализации поддерживается механизмом проверки признака специализации,
по которому можно установить ее тип.</p>
      <p>4. Добавление новых процедур для обработки конкретных</p>
      <p>специализаций внутри существующих обобщений
Данная ситуация возникает, когда необходимо использовать только одну
из специализаций, например, при обработке элементов контейнера,
ссылающегося на обобщенный тип, через который нужно обеспечить доступ
только к одному из специализированных типов.</p>
      <p>
        Процедурный подход. В случае расширений типа используются
процедуры, в которых осуществляется явная проверка производного типа по
указателю на базовый тип [
        <xref ref-type="bibr" rid="ref10">10</xref>
        ]. Метод легко добавляется в новом модуле. Не
вызывает проблем использование этого же приема в процедурных языках, не
имеющих поддержки полиморфизма типа (например, в C). В этом случае
обобщение обычно строится таким образом, что имеет признак, который и
используется при идентификации специализации.
      </p>
      <p>
        Объектно-ориентированный подход. Применение
объектноориентированных методов опирается на использование виртуальных функций,
осуществляющих обработку специализированного объекта требуемого типа [
        <xref ref-type="bibr" rid="ref10">10</xref>
        ].
Однако такая функция, для использования виртуализации, должна добавляться
в базовый класс, что не способствует эволюционному расширению программы.
Помимо этого, базовый класс перегружается дополнительной информацией о
производном классе, что не способствует инкапсуляции. Поэтому для обработки
специализаций при объектно-ориентированном подходе чаще всего
применяется процедурный прием, основанный на явной проверке типа.
      </p>
      <p>Go-подход. Одним из вариантов безболезненного добавления процедуры
является использование пустого интерфейса для доступа к уже
сформированному обобщению с последующей явной проверкой через него типа
специализации. Если проверяемый тип соответствует типу искомой
специализации, то вызывается добавленная процедура. То есть, интерфейсы Go
позволяют сформировать эволюционное решение, аналогичное процедурному
подходу.</p>
      <p>
        Процедурно-параметрический подход. Простейшим вариантом является
использование процедурного подхода, примененного к обобщенному типу [
        <xref ref-type="bibr" rid="ref3">3</xref>
        ].
Отличие заключается в проверке признака специализации вместо проверки
производного типа подключенного объекта. Поэтому при
процедурнопараметрическом подходе не возникает проблем в решении данной задачи.
Однако помимо этого, возможно использование процедурно-параметрического
полиморфизма, при котором отсутствует необходимость явной манипуляции
типом объекта. В этом случае вначале пишется обобщающая процедура с
пустым телом (как и при объектно-ориентированном подходе). Для выполнения
требуемых манипуляций с заданной специализацией пишется ее обработчик,
который и вызывается при вызове обобщающей процедурой. В отличие от ОО
подхода все добавления осуществляются в новых модулях, что обеспечивает
эволюционное расширение программы. Таким образом,
процедурнопараметрическая парадигма предоставляет разнообразные способы для
расширения в данной ситуации.
      </p>
      <p>5. Создание обобщения из существующих специализаций
Процедурный подход. Зачастую в программе требуется сформировать
новое обобщение при уже существующих специализациях. Процедурный
подход в этом случае обеспечивает прямое решение на основе объединения
(язык C) или вариантной записи (языки Pascal, Modula-2). Данный тип может
формироваться в модулях, добавляемых в программу, что не вызывает проблем
с эволюционным расширением. Вместе с тем, следует отметить, что языки,
использующие для построения обобщений только расширение типа (Oberon,
Oberon-2), не обеспечивают прямого решения этой проблемы. Необходимы
дополнительные построения, чтобы достичь искомого решения.</p>
      <p>Объектно-ориентированный подход. Использование наследования
обладает теми же недостатками, что и расширение типа. Поэтому построение
обобщения обычно ведется на основе создание нового базового класса и
порождения от него производных классов, включающих в себя необходимые
существующие специализации. Решение достаточно простое, но не является
прямым.</p>
      <p>Go-подход. В качестве одного из достоинств, отмечаемого при сравнении
интерфейсов Go с механизмом наследования ОО языков, выделяется
возможность создания любого числа обобщений для одних и тех же структур
данных на основе интерфейсов, что и обеспечивает безболезненное расширение
кода для рассматриваемой ситуации.</p>
      <p>Процедурно-параметрический подход. Обобщения и обобщенные
записи при своем создании допускают непосредственное включение в них
специализаций, что обеспечивает их прямое построение. Помимо этого,
расширение за счет уже существующих специализаций возможно и при уже
существующем обобщении. Это обеспечивает высокую гибкость и
эволюционный рост для рассматриваемой ситуации.</p>
      <p>
        6. Добавление мультиметодов
Процедурный подход. Так как мультиметод является обычной
процедурой, его эволюционное добавление не вызывает никаких проблем.
Объектно-ориентированный подход. Реализация мультиметода в
объектно-ориентированном подходе опирается на множественную
диспетчеризацию [
        <xref ref-type="bibr" rid="ref17">17</xref>
        ], при которой между классами, играющими роль
обобщенных аргументов мультиметода, возникают тесные взаимодействия,
задаваемые через методы. Поэтому добавление мультиметода ведет к тому, что
изменяется описание класса, что не способствует эволюционному расширению.
В связи с тем, что использование диспетчеризации ведет к большим
изменениям во взаимодействующих классах, обычно при реализации
мультиметодов применяются подходы, базирующиеся на явной проверке типов
или смешанном варианте, когда тип первого аргумента выявляется полиморфно,
а тип второго определяется явной проверкой [
        <xref ref-type="bibr" rid="ref17 ref18">17, 18</xref>
        ]. Однако подобные
решения все равно не обеспечивают поддержку эволюционного расширения,
так как приходится изменять содержимое класса.
      </p>
      <p>Go-подход. Использование интерфейсов позволяет построить решение,
базирующееся на диспетчеризации, как и в случае ОО подхода. Вместе с тем,
для вновь вводимого мультиметода можно создать отдельное обобщение на
основе интерфейса, что позволяет эволюционно добавить его в программу как
обычную процедуру. Однако такое решение требует изменения трактовки
исходных обобщений, что может оказаться не всегда целесообразным.</p>
      <p>Процедурно-параметрический подход. Для гибкой реализации
мультиметодов используются обобщающие параметрические процедуры.
Являясь по сути внешними процедурами, они обеспечивают безболезненное
добавление мультиметодов в программу.</p>
      <p>
        7. Изменение мультиметодов при добавлении специализаций
Процедурный подход. Выбор обработчика комбинации специализаций
мультиметода осуществляется на основе явной проверки типов обобщенных
аргументов внутри условных операторов или операторов выбора. Поэтому
добавление новой специализации к любому обобщенному аргументу
мультиметода изменяет один или несколько условных операторов, не
обеспечивая эволюционного расширения программы в данной ситуации [
        <xref ref-type="bibr" rid="ref10">10</xref>
        ].
      </p>
      <p>Объектно-ориентированный подход. Добавление новой специализации
связано с созданием нового производного класса. Включение этого класса в
общую группу, содержащую мультиметод, ведет, для обеспечения
диспетчеризации, к добавлению дополнительных методов во все классы группы.
Поэтому прямое добавление новых специализаций в мультиметод не
поддерживается.</p>
      <p>Go-подход. Использование диспетчеризации, как и в случае ОО подхода,
не обеспечивает поддержку эволюционного расширения. Необходимо в
интерфейсы сопоставляемых структур дописывать новые отношения.</p>
      <p>
        Процедурно-параметрический подход. Данная парадигма изначально
разрабатывалась для поддержки безболезненного расширения мультиметодов
при добавлении новых специализаций. Это обеспечивается за счет описания
всех комбинаций аргументов в обработчиках специализаций, размещаемых
независимо от обобщающей процедуры. Поэтому каждая новая специализация
ведет лишь к написанию соответствующих обработчиков в новых единицах
компиляции. Метод основан на достаточно простом механизме построения
параметрических отношений, одна из возможных реализаций которого в виде
библиотеки макроопределений приведена в [
        <xref ref-type="bibr" rid="ref19 ref20">19</xref>
        ].
      </p>
      <p>8. Сопоставление рассмотренных подходов
В таблице собраны сведения, показывающие возможности каждой из
рассмотренных парадигм по прямой поддержке эволюционного расширения.
Можно увидеть, что ОО подход обеспечивает прямое эволюционное
расширение программы в наименьшем числе из рассмотренных ситуаций.
Однако в сочетании с разнообразными методами дополнительного кодирования,
позволяющими обойти возникающие проблемы, данный подход остается
наиболее популярным.</p>
      <p>Процедурный
ОО
ПП
Ситуация
1 Добавление нет
специализации и ее
обработчиков
2 Добавление процедур есть
с дополнительной
функциональностью
3 Добавление новых косвенное, для
полей в существующий расширяемых
тип типов
4 Добавление есть
обработчика
специализации,
включенной в
обобщение
5 Создание обобщения есть
на основе
существующих
специализаций
6 Добавление в есть
программу
мультиметода
7 Изменение нет
мультиметода при
Подходы
есть
нет
косвенное, при
наличии
динамической
проверки типов
во время
выполнения
нет
нет
нет</p>
      <p>Goпоход
есть
есть
нет
есть
есть
нет
есть
есть
есть
есть
косвенное, при
использовании
обобщенной
записи
есть процедурный
и
параметрический
косвенное
есть
есть</p>
      <p>Процедурно-параметрическое программирование обеспечивает
эволюционное расширение программы практически во всех ситуациях, что
обуславливется раздельным эволюционным расширением как данных, так и
обобщающих процедур. В ряде случаев можно использовать альтернативные
решения, опирающиеся на чистый процедурный подход или на
процедурнопараметрический полиморфизм. Последнее может повысить безопасность
разработки программ за счет применения полиморфизма вместо явной проверки
типов. Анализ простых ситуаций показывает, что ППП обладает гибкостью,
перекрывающей процедурный и ОО подходы. Представляет интерес
использование возможностей ППП и в более сложных случаях, образуемых
комбинациями простых ситуаций.</p>
      <p>9. Возможность использования полиморфизма в случае</p>
      <p>
        функционально-потокового параллельного программирования
Функционально-потоковая парадигма параллельного программирования
базируется на функционально-потоковой модели параллельных вычислений,
которая ориентирована на описание процесса управления параллельными
вычислениями на основе готовности данных [
        <xref ref-type="bibr" rid="ref21">20</xref>
        ]. Разработанный на ее основе
язык функционально-потокового параллельного программирования Пифагор
использует динамическую типизацию, что не позволяет обеспечить
эффективную трансформацию программ во время компиляции в программы для
современных вычислительных систем. Однако не существует принципиальных
препятствий для реализации на базе этой модели языка программирования,
использующего статическую систему типов и поддерживающего одну из
разновидностей полиморфизма.
      </p>
      <p>Основной проблемой в данном случае является формирование синтаксиса
языка, что связано с тем, что в модели вычислений присутствует лишь функция
интерпретации, принимающая на вход только один аргумент. При наличии
полиморфизма в соответствующих языках программирования прямо или
косвенно присутствует дополнительный аргумент, который определяет
динамические зависимости. При объектно-ориентированном подходе этим
аргументов является экземпляр класса. В языке программирования Go в его
роли выступает интерфейс. Процедурно-параметрический подход допускает
наличие не одного, а нескольких подобных аргументов в случае
множественного полиморфизма, что вносит дополнительные трудности в их
представление на уровне синтаксиса языка функционально-потокового
параллельного программирования. Вместе с тем следует отметить, что
реализация семантики для всех вариантов реализации полиморфизма
практически аналогична реализациям в уже существующих языках
программирования.
Заключение
Методы конструирования программных объектов, обеспечивающие
поддержку полиморфизма, широко используются в настоящее время
практически во всех современных языках программирования. Они реализованы
не только в императивном, но и в функциональном подходе. Каждый из
представленных в работе подходов является самодостаточным для построения
универсальных программ. Однако не каждый из них обеспечивает поддержку
безболезненного расширения уже написанного кода в случае тех или иных
ситуаций. Зачастую это ведет к совместному использованию приемов,
определяющих мультипарадигменный стиль.</p>
      <p>Функционально-потоковая парадигма программирования также может
быть расширена за счет использования статической типизации и реализации
обобщений с применением одного из подходов, поддерживающего тот или иной
вид полиморфизма. Вместе с тем следует отметить, что ее специфика требует
дальнейшего изучения представленных вариантов для принятия окончательно
решения по выбору одного из них или использованию сочетаний,
взаимодополняющих друг друга.</p>
      <p>Исследование выполнено при финансовой поддержке РФФИ в рамках
научного проекта № 17-07-00288.</p>
      <p>Литература
1. Гамма Э. Приемы объектно-ориентированного проектирования. Паттерны
проектирования. СПб.: «Питер», 2001. 368 с.
2. Буч Г. Объектно-ориентированный анализ и проектирование с примерами
приложений на C++, 2-е изд. М.: "Издательство Бином", СПб: "Невский
диалект", 1998 г. 560 с.
3. Легалов А.И. Процедурно-параметрическая парадигма программирования.
Возможна ли альтернатива объектно-ориентированному стилю? –
Красноярск, 2000. Деп. рук. № 622-В00 Деп. в ВИНИТИ 13.03.2000. 43 с.
4. Легалов И.А. Применение обобщенных записей в
процедурнопараметрическом языке программирования // Научный вестник НГТУ, 2007.
№ 3 (28). С. 25-38.
5. Саммерфильд М. Программирование на Go. Разработка приложений XXI
века. М.: ДМК Пресс, 2013. 580 с.
6. Легалов А.И., Солоха А.Ф. Особенности языка
процедурнопараметрического программирования // Вестник новосибирского
государственного университета. Серия: Информационные технологии. Том 9,
№ 3, 2011. С. 15-22.
7. Керниган Б.У., Ритчи Д.М. Язык программирования C. 2-е изд. М.:
Издательский дом «Вильямс», 2009. 304 с.
8. Павловская Т.А. Паскаль. Программирование на языке высокого уровня:
Учебник для вузов. СПб.: «Питер», 2007. 393 с.</p>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          1.
          <string-name>
            <surname>Erich</surname>
            <given-names>Gamma</given-names>
          </string-name>
          , Richard Helm, Ralph Johnson, John Vissides Design Patterns:
          <article-title>Elements of Reusable Object-Oriented Software</article-title>
          .
          <string-name>
            <surname>Addison-Wesley Professional</surname>
          </string-name>
          ;
          <year>1994</year>
          :
          <fpage>353</fpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          2.
          <string-name>
            <surname>Booch</surname>
            <given-names>G.</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Maksimchuk</surname>
            <given-names>R.A.</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Engle</surname>
            <given-names>M.W.</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Young</surname>
            <given-names>B.J.</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Conallen</surname>
            <given-names>J.</given-names>
          </string-name>
          , Houston K.A.
          <string-name>
            <surname>Object-Oriented Analysis</surname>
          </string-name>
          and
          <article-title>Design with Applications</article-title>
          .
          <source>Third Edition. / AddisonWesley</source>
          .
          <year>2007</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          3.
          <string-name>
            <surname>Legalov</surname>
            <given-names>A.I.</given-names>
          </string-name>
          <article-title>Protsedurno-parametricheskaya paradigma programmirovaniya. Vozmozhna li alternativa obyektno-oriyentirovannomu stilyu? -</article-title>
          <source>Krasnoyarsk</source>
          .
          <year>2000</year>
          . Dep. ruk. №
          <fpage>622</fpage>
          -
          <lpage>V00</lpage>
          Dep. v VINITI
          <volume>13</volume>
          .
          <year>03</year>
          .
          <year>2000</year>
          .
          <volume>43</volume>
          s.
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          4.
          <string-name>
            <surname>Legalov</surname>
            <given-names>I.A.</given-names>
          </string-name>
          <article-title>Primeneniye obobshchennykh zapisey v protsedurnoparametricheskom yazyke programmirovaniya // Nauchnyy vestnik NGTU</article-title>
          .
          <year>2007</year>
          . №
          <volume>3</volume>
          (
          <issue>28</issue>
          ). S.
          <volume>25</volume>
          -
          <fpage>38</fpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          5.
          <string-name>
            <surname>Summerfield</surname>
            <given-names>M.</given-names>
          </string-name>
          <article-title>Programming in Go. Creating Applications for the 21st Century</article-title>
          . Addison-Wesley -
          <year>2013</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          6.
          <string-name>
            <surname>Legalov</surname>
            <given-names>A.I.. Solokha A.F.</given-names>
          </string-name>
          <article-title>Osobennosti yazyka protsedurno-parametricheskogo programmirovaniya // Vestnik novosibirskogo gosudarstvennogo universiteta</article-title>
          .
          <source>Seriya: Informatsionnyye tekhnologii. Tom 9. № 3</source>
          .
          <year>2011</year>
          . S.
          <volume>15</volume>
          -
          <fpage>22</fpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>
          7.
          <string-name>
            <surname>Kernigan</surname>
            <given-names>B.W.</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Ritchie D.M. The C Programming</surname>
          </string-name>
          <article-title>Language</article-title>
          . / AT &amp; T
          <string-name>
            <surname>Bell</surname>
          </string-name>
          Laboratories -
          <year>1988</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref8">
        <mixed-citation>
          8.
          <string-name>
            <surname>Pavlovskaya</surname>
            <given-names>T.A.</given-names>
          </string-name>
          <string-name>
            <surname>Paskal</surname>
          </string-name>
          .
          <article-title>Programmirovaniye na yazyke vysokogo urovnya: Uchebnik dlya vuzov</article-title>
          .
          <source>SPb</source>
          .: «Piter».
          <year>2007</year>
          .
          <volume>393</volume>
          s.
        </mixed-citation>
      </ref>
      <ref id="ref9">
        <mixed-citation>
          9.
          <string-name>
            <surname>Virt</surname>
            <given-names>N.</given-names>
          </string-name>
          <article-title>Programmirovaniye na yazyke Modula-2</article-title>
          . M.:
          <string-name>
            <surname>Mir</surname>
          </string-name>
          ,
          <year>1987</year>
          .
          <volume>224</volume>
          с.
        </mixed-citation>
      </ref>
      <ref id="ref10">
        <mixed-citation>
          10.
          <string-name>
            <surname>Legalov</surname>
            <given-names>A.I. Raznorukoye</given-names>
          </string-name>
          programmirovaniye // URL: http://www.softcraft.ru/paradigm/dhp/.
        </mixed-citation>
      </ref>
      <ref id="ref11">
        <mixed-citation>
          11.
          <string-name>
            <surname>Wirth</surname>
            <given-names>N.</given-names>
          </string-name>
          <article-title>The Programming Language Oberon</article-title>
          .
          <source>Revision</source>
          <volume>1</volume>
          .
          <fpage>10</fpage>
          .
          <year>2013</year>
          / 3.5.
          <year>2016</year>
          // URL: https://www.inf.ethz.ch/personal/wirth/Oberon/Oberon07.Report.pdf
        </mixed-citation>
      </ref>
      <ref id="ref12">
        <mixed-citation>
          12.
          <string-name>
            <surname>Moessenboeck H. The Programming Language</surname>
            Oberon-2. Institut fur Computersysteme,
            <given-names>ETH Zurich</given-names>
          </string-name>
          <string-name>
            <surname>July</surname>
          </string-name>
          .
          <article-title>- 1996.</article-title>
        </mixed-citation>
      </ref>
      <ref id="ref13">
        <mixed-citation>
          13.
          <string-name>
            <surname>Barnes</surname>
            <given-names>J</given-names>
          </string-name>
          .
          <source>Programming in Ada 95, 2nd Edition</source>
          . Addison-Wesley,
          <year>1998</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref14">
        <mixed-citation>
          14.
          <string-name>
            <surname>Stroustrup B. The</surname>
            <given-names>C</given-names>
          </string-name>
          +
          <article-title>+ Programming Language</article-title>
          .
          <source>Fourth Edition</source>
          . / AddisonWesley - 2013.
        </mixed-citation>
      </ref>
      <ref id="ref15">
        <mixed-citation>
          15.
          <string-name>
            <surname>Troelsen</surname>
            <given-names>A</given-names>
          </string-name>
          .
          <string-name>
            <surname>Pro</surname>
            <given-names>C</given-names>
          </string-name>
          #
          <article-title>2010 and The .Net 4 Platform. Fifth Edition</article-title>
          . APress, Inc. -
          <year>2010</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref16">
        <mixed-citation>
          16.
          <string-name>
            <surname>Eckel</surname>
            <given-names>B.</given-names>
          </string-name>
          <article-title>Thinking in Java (4th Edition)</article-title>
          .
          <source>Prentice Hall Ptr - 2006</source>
          . ISBN-
          <volume>13</volume>
          :
          <fpage>978</fpage>
          -
          <lpage>0131872486</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref17">
        <mixed-citation>
          17.
          <string-name>
            <surname>Alger</surname>
          </string-name>
          , J. C+
          <article-title>+ for Real Programmers</article-title>
          .
          <source>AP Professional</source>
          ,
          <year>1998</year>
          . 388 p.
        </mixed-citation>
      </ref>
      <ref id="ref18">
        <mixed-citation>
          18.
          <string-name>
            <surname>Legalov</surname>
            <given-names>A. I. OOP.</given-names>
          </string-name>
          <article-title>multimetody i piramidalnaya evolyutsiya // Otkrytyye sistemy</article-title>
          .
          <source>№ 3</source>
          .
          <year>2002</year>
          . S.
          <volume>41</volume>
          -
          <fpage>45</fpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref19">
        <mixed-citation>
          19.
          <string-name>
            <surname>Legalov</surname>
            <given-names>A.I. Kosov P.V.</given-names>
          </string-name>
          <article-title>Evolyutsionnoye rasshireniye programm s ispolzovaniyem protsedurno-parametricheskogo podkhoda // Vychislitelnyye tekhnologii</article-title>
          .
          <year>2016</year>
          . T.
          <volume>21</volume>
          . № 3. S.
          <volume>56</volume>
          -
          <fpage>69</fpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref20">
        <mixed-citation>
          19.
          <string-name>
            <surname>Alexandrescu</surname>
            ,
            <given-names>A</given-names>
          </string-name>
          . Modern C+
          <article-title>+ Design: Generic Programming and Design Patterns Applied</article-title>
          .
          <string-name>
            <surname>Addison-Wesley Professional</surname>
          </string-name>
          ;
          <year>2001</year>
          :
          <fpage>352</fpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref21">
        <mixed-citation>
          20.
          <string-name>
            <surname>Legalov</surname>
            <given-names>A.I.</given-names>
          </string-name>
          <article-title>Funktsionalnyy yazyk dlya sozdaniya arkhitekturno-nezavisimykh parallelnykh programm // Vychislitelnyye tekhnologii</article-title>
          . №
          <volume>1</volume>
          (
          <issue>10</issue>
          ).
          <year>2005</year>
          . S.
          <volume>71</volume>
          -
          <fpage>89</fpage>
          .
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>