Обобщённое программирование
Обобщённое программирование (англ. generic programming) — парадигма программирования, заключающаяся в таком описании данных и алгоритмов, которое можно применять к различным типам данных, не меняя само это описание. В том или ином виде поддерживается разными языками программирования. Возможности обобщённого программирования впервые появились в виде дженериков (обобщённых функций) в 1970-х годах в языках Клу и Ада, затем — в виде параметрического полиморфизма в ML и его потомках, а затем — во многих объектно-ориентированных языках, таких как C++, Python, Java, Object Pascal, D, Eiffel, языках для платформы .NET и других.
Методология
Обобщённое программирование рассматривается как методология программирования, основанная на разделении структур данных и алгоритмов через использование абстрактных описаний требований. Абстрактные описания требований являются расширением понятия абстрактного типа данных. Вместо описания отдельного типа в обобщённом программировании применяется описание семейства типов, имеющих общий интерфейс и семантическое поведение (англ. semantic behavior). Набор требований, описывающий интерфейс и семантическое поведение, называется концепцией (concept). Таким образом, написанный в обобщённом стиле алгоритм может применяться для любых типов, удовлетворяющих его своими концепциями. Такая возможность называется полиморфизмом.
Говорят, что тип моделирует концепцию (является моделью концепции), если он удовлетворяет её требованиям. Концепция является уточнением другой концепции, если она дополняет последнюю. Требования к концепциям содержат следующую информацию:
- Допустимые выражения (англ. valid expressions) — выражения языка программирования, которые должны успешно компилироваться для типов, моделирующих концепцию.
- Ассоциированные типы (associated types) — вспомогательные типы, имеющие некоторое отношение к моделирующему концепцию типу.
- Инварианты (invariants) — такие характеристики типов, которые должны быть постоянно верны во время исполнения. Обычно выражаются в виде предусловий и постусловий. Невыполнение предусловия влечёт непредсказуемость соответствующей операции и может привести к ошибкам.
- Гарантии сложности (complexity guarantees) — максимальное время выполнения допустимого выражения или максимальные требования к различным ресурсам в ходе выполнения этого выражения.
В C++ объектно-ориентированное программирование (ООП) реализуется посредством виртуальных функций и наследования, а обобщённое программирование (ОП) — с помощью шаблонов классов и функций. Тем не менее, суть обеих методологий связана с конкретными технологиями реализации лишь косвенно. Говоря более формально, ООП основано на полиморфизме подтипов, а ОП — на параметрическом полиморфизме. В других языках то и другое может быть реализовано иначе. Например, мультиметоды в CLOS имеют сходную с параметрическим полиморфизмом семантику.
Массер и Степанов выделяют следующие этапы в решении задачи по методологии ОП:
- Найти полезный и эффективный алгоритм.
- Определить обобщённое представление (параметризовать алгоритм, минимизировав требования к обрабатываемым данным).
- Описать набор (минимальных) требований, удовлетворяя которые всё ещё можно получить эффективные алгоритмы.
- Создать каркас на основе классифицированных требований.
Минимизация и создание каркаса ставят целью создание такой структуры, при которой алгоритмы не зависят от конкретных типов данных. Этот подход отражён в структуре библиотеки STL.
Альтернативный подход к определению обобщённого программирования, который можно назвать обобщённым программированием типов данных (англ. datatype generic programming), был предложен Ричардом Бёрдом и Ламбертом Меертенсом. В нём структуры типов данных являются параметрами обобщённых программ. Для этого в язык программирования вводится новый уровень абстракции, а именно параметризация по отношению к классам алгебр с переменной сигнатурой. Хотя теории обоих подходов не зависят от языка программирования, подход Массера — Степанова, делающий упор на анализ концепций, сделал C++ своей основной платформой, тогда как обобщённое программирование типов данных используют почти исключительно Haskell и его варианты.
Общий механизм
Средства обобщённого программирования реализуются в языках программирования в виде тех или иных синтаксических средств, дающих возможность описывать данные (типы данных) и алгоритмы (процедуры, функции, методы), параметризуемые типами данных. У функции или типа данных явно описываются формальные параметры-типы. Это описание является обобщённым и в исходном виде непосредственно использовано быть не может.
В тех местах программы, где обобщённый тип или функция используется, программист должен явно указать фактический параметр-тип, конкретизирующий описание. Например, обобщённая процедура перестановки местами двух значений может иметь параметр-тип, определяющий тип значений, которые она меняет местами. Когда программисту нужно поменять местами два целых значения, он вызывает процедуру с параметром-типом «целое число» и двумя параметрами — целыми числами, когда две строки — с параметром-типом «строка» и двумя параметрами — строками. В случае с данными программист может, например, описать обобщённый тип «список» с параметром-типом, определяющим тип хранимых в списке значений. Тогда при описании реальных списков программист должен указать обобщённый тип и параметр-тип, получая, таким образом, любой желаемый список с помощью одного и того же описания.
Компилятор, встречая обращение к обобщённому типу или функции, выполняет необходимые процедуры статического контроля типов, оценивает возможность заданной конкретизации и при положительной оценке генерирует код, подставляя фактический параметр-тип на место формального параметра-типа в обобщённом описании. Естественно, что для успешного использования обобщённых описаний фактические типы-параметры должны удовлетворять определённым условиям. Если обобщённая функция сравнивает значения типа-параметра, любой конкретный тип, использованный в ней, должен поддерживать операции сравнения, если присваивает значения типа-параметра переменным — конкретный тип должен обеспечивать корректное присваивание.
Обобщённое программирование в языках
C++
В языке C++ обобщённое программирование основывается на понятии «шаблон», обозначаемом ключевым словом template. Широко применяется в стандартной библиотеке C++ (см. STL), а также в сторонних библиотеках boost, Loki. Большой вклад в появление развитых средств обобщённого программирования в C++ внёс Александр Степанов.
В качестве примера приведём шаблон (обобщение) функции, возвращающей большее значение из двух.
// Описание шаблона функции template <typename T> T max(T x, T y) { if (x < y) return y; else return x; } ... // Применение функции, заданной шаблоном int a = max(10,15); ... double f = max(123.11, 123.12); ... или шаблон (обобщение) класса связного списка:
template <class T> class List { /* ... */ public: void Add( const T& Element ); bool Find( const T& Element ); /* ... */ }; Haskell
Язык Haskell предоставляет обобщённое программирование типов данных. В следующем примере a — параметрическая переменная типа.
data List a = Nil | Cons a (List a) length :: List a -> Int length Nil = 0 length (Cons _ tl) = 1 + length tl Пример вычислений:
length (Cons 1 (Cons 2 Nil)) == 2 Java
Java предоставляет средства обобщённого программирования, синтаксически основанные на C++, начиная с версии J2SE 5.0. В этом языке имеются generics или «контейнеры типа T» — подмножество обобщённого программирования.
.NET
На платформе .NET средства обобщённого программирования появились в версии 2.0.
// Объявление обобщенного класса. public class GenericList<T> { void Add(T input) { } } class TestGenericList { private class ExampleClass { } static void Main() { GenericList<int> list1 = new GenericList<int>(); GenericList<string> list2 = new GenericList<string>(); GenericList<ExampleClass> list3 = new GenericList<ExampleClass>(); } } Пример на C#
interface IPerson { string GetFirstName(); string GetLastName(); } class Speaker { public void SpeakTo<T>(T person) where T : IPerson { string name = person.GetFirstName(); this.say("Hello, " + name); } } D
Пример рекурсивной генерации на основе шаблонов D:
// http://digitalmars.com/d/2.0/template.html template Foo(T, R...) // T - тип, R - набор типов { void Foo(T t, R r) { writeln(t); static if (r.length)// if more arguments Foo(r);// do the rest of the arguments } } void main() { Foo(1, 'a', 6.8); } /+++++++++++++++ prints: 1 a 6.8 +++++++++++++++/ Object Pascal
Поддержка обобщённого программирования компилятором Free Pascal появилась начиная с версии 2.2 в 2007 году. В Delphi — с октября 2008 года. Основа поддержки обобщённых классов сначала появилась в Delphi 2007 .NET в 2006 году, но она затрагивала только .NET Framework. Более полная поддержка обобщённого программирования была добавлена в Delphi 2009. Обобщённые классы также поддерживаются в Object Pascal в системе PascalABC.NET.
Nim
import typetraits proc getType[T](x: T): string = return x.type.name echo getType(21) # напечатает int echo getType(21.12) # напечатает float64 echo getType("string") # напечатает string Примечания
- Python Generic. Дата обращения: 28 мая 2020. Архивировано 9 февраля 2021 года.
- В Delphi и PascalABC.NET
- Сик, Ли, Ламсдэйн, 2006, p. 39.
- Сик, Ли, Ламсдэйн, 2006, p. 47—48.
- Сик, Ли, Ламсдэйн, 2006, p. 40—45.
- Gabriel Dos Reis, Jaakko Järvi. What is Generic Programming?
- Freepascal.Generics. Дата обращения: 1 февраля 2011. Архивировано 15 декабря 2010 года.
Ссылки
- generic-programming.org (англ.)
- Gabriel Dos Reis and Jaakko Järvi, What is Generic Programming?
- Обобщённое программирование в Delphi (рус.)
Литература
- Джереми Сик, Лай-Кван Ли, Эндрю Ламсдэйн. C++ Boost Graph Library. — Питер, 2006. — 304 с. — ISBN 5-469-00352-3.
- Степанов Александр А., Роуз Дэниэл Э. От математики к обобщённому программированию. — ДМК Пресс, 2016. — 264 с. — ISBN 978-5-97060-379-6.
Википедия, чтение, книга, библиотека, поиск, нажмите, истории, книги, статьи, wikipedia, учить, информация, история, скачать, скачать бесплатно, mp3, видео, mp4, 3gp, jpg, jpeg, gif, png, картинка, музыка, песня, фильм, игра, игры, мобильный, телефон, Android, iOS, apple, мобильный телефон, Samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, ПК, web, Сеть, компьютер, Информация о Обобщённое программирование, Что такое Обобщённое программирование? Что означает Обобщённое программирование?
Obobshyonnoe programmirovanie angl generic programming paradigma programmirovaniya zaklyuchayushayasya v takom opisanii dannyh i algoritmov kotoroe mozhno primenyat k razlichnym tipam dannyh ne menyaya samo eto opisanie V tom ili inom vide podderzhivaetsya raznymi yazykami programmirovaniya Vozmozhnosti obobshyonnogo programmirovaniya vpervye poyavilis v vide dzhenerikov obobshyonnyh funkcij v 1970 h godah v yazykah Klu i Ada zatem v vide parametricheskogo polimorfizma v ML i ego potomkah a zatem vo mnogih obektno orientirovannyh yazykah takih kak C Python Java Object Pascal D Eiffel yazykah dlya platformy NET i drugih MetodologiyaObobshyonnoe programmirovanie rassmatrivaetsya kak metodologiya programmirovaniya osnovannaya na razdelenii struktur dannyh i algoritmov cherez ispolzovanie abstraktnyh opisanij trebovanij Abstraktnye opisaniya trebovanij yavlyayutsya rasshireniem ponyatiya abstraktnogo tipa dannyh Vmesto opisaniya otdelnogo tipa v obobshyonnom programmirovanii primenyaetsya opisanie semejstva tipov imeyushih obshij interfejs i semanticheskoe povedenie angl semantic behavior Nabor trebovanij opisyvayushij interfejs i semanticheskoe povedenie nazyvaetsya koncepciej concept Takim obrazom napisannyj v obobshyonnom stile algoritm mozhet primenyatsya dlya lyubyh tipov udovletvoryayushih ego svoimi koncepciyami Takaya vozmozhnost nazyvaetsya polimorfizmom Govoryat chto tip modeliruet koncepciyu yavlyaetsya modelyu koncepcii esli on udovletvoryaet eyo trebovaniyam Koncepciya yavlyaetsya utochneniem drugoj koncepcii esli ona dopolnyaet poslednyuyu Trebovaniya k koncepciyam soderzhat sleduyushuyu informaciyu Dopustimye vyrazheniya angl valid expressions vyrazheniya yazyka programmirovaniya kotorye dolzhny uspeshno kompilirovatsya dlya tipov modeliruyushih koncepciyu Associirovannye tipy associated types vspomogatelnye tipy imeyushie nekotoroe otnoshenie k modeliruyushemu koncepciyu tipu Invarianty invariants takie harakteristiki tipov kotorye dolzhny byt postoyanno verny vo vremya ispolneniya Obychno vyrazhayutsya v vide preduslovij i postuslovij Nevypolnenie predusloviya vlechyot nepredskazuemost sootvetstvuyushej operacii i mozhet privesti k oshibkam Garantii slozhnosti complexity guarantees maksimalnoe vremya vypolneniya dopustimogo vyrazheniya ili maksimalnye trebovaniya k razlichnym resursam v hode vypolneniya etogo vyrazheniya V C obektno orientirovannoe programmirovanie OOP realizuetsya posredstvom virtualnyh funkcij i nasledovaniya a obobshyonnoe programmirovanie OP s pomoshyu shablonov klassov i funkcij Tem ne menee sut obeih metodologij svyazana s konkretnymi tehnologiyami realizacii lish kosvenno Govorya bolee formalno OOP osnovano na polimorfizme podtipov a OP na parametricheskom polimorfizme V drugih yazykah to i drugoe mozhet byt realizovano inache Naprimer multimetody v CLOS imeyut shodnuyu s parametricheskim polimorfizmom semantiku Masser i Stepanov vydelyayut sleduyushie etapy v reshenii zadachi po metodologii OP Najti poleznyj i effektivnyj algoritm Opredelit obobshyonnoe predstavlenie parametrizovat algoritm minimizirovav trebovaniya k obrabatyvaemym dannym Opisat nabor minimalnyh trebovanij udovletvoryaya kotorye vsyo eshyo mozhno poluchit effektivnye algoritmy Sozdat karkas na osnove klassificirovannyh trebovanij Minimizaciya i sozdanie karkasa stavyat celyu sozdanie takoj struktury pri kotoroj algoritmy ne zavisyat ot konkretnyh tipov dannyh Etot podhod otrazhyon v strukture biblioteki STL Alternativnyj podhod k opredeleniyu obobshyonnogo programmirovaniya kotoryj mozhno nazvat obobshyonnym programmirovaniem tipov dannyh angl datatype generic programming byl predlozhen Richardom Byordom i Lambertom Meertensom V nyom struktury tipov dannyh yavlyayutsya parametrami obobshyonnyh programm Dlya etogo v yazyk programmirovaniya vvoditsya novyj uroven abstrakcii a imenno parametrizaciya po otnosheniyu k klassam algebr s peremennoj signaturoj Hotya teorii oboih podhodov ne zavisyat ot yazyka programmirovaniya podhod Massera Stepanova delayushij upor na analiz koncepcij sdelal C svoej osnovnoj platformoj togda kak obobshyonnoe programmirovanie tipov dannyh ispolzuyut pochti isklyuchitelno Haskell i ego varianty Obshij mehanizmSredstva obobshyonnogo programmirovaniya realizuyutsya v yazykah programmirovaniya v vide teh ili inyh sintaksicheskih sredstv dayushih vozmozhnost opisyvat dannye tipy dannyh i algoritmy procedury funkcii metody parametrizuemye tipami dannyh U funkcii ili tipa dannyh yavno opisyvayutsya formalnye parametry tipy Eto opisanie yavlyaetsya obobshyonnym i v ishodnom vide neposredstvenno ispolzovano byt ne mozhet V teh mestah programmy gde obobshyonnyj tip ili funkciya ispolzuetsya programmist dolzhen yavno ukazat fakticheskij parametr tip konkretiziruyushij opisanie Naprimer obobshyonnaya procedura perestanovki mestami dvuh znachenij mozhet imet parametr tip opredelyayushij tip znachenij kotorye ona menyaet mestami Kogda programmistu nuzhno pomenyat mestami dva celyh znacheniya on vyzyvaet proceduru s parametrom tipom celoe chislo i dvumya parametrami celymi chislami kogda dve stroki s parametrom tipom stroka i dvumya parametrami strokami V sluchae s dannymi programmist mozhet naprimer opisat obobshyonnyj tip spisok s parametrom tipom opredelyayushim tip hranimyh v spiske znachenij Togda pri opisanii realnyh spiskov programmist dolzhen ukazat obobshyonnyj tip i parametr tip poluchaya takim obrazom lyuboj zhelaemyj spisok s pomoshyu odnogo i togo zhe opisaniya Kompilyator vstrechaya obrashenie k obobshyonnomu tipu ili funkcii vypolnyaet neobhodimye procedury staticheskogo kontrolya tipov ocenivaet vozmozhnost zadannoj konkretizacii i pri polozhitelnoj ocenke generiruet kod podstavlyaya fakticheskij parametr tip na mesto formalnogo parametra tipa v obobshyonnom opisanii Estestvenno chto dlya uspeshnogo ispolzovaniya obobshyonnyh opisanij fakticheskie tipy parametry dolzhny udovletvoryat opredelyonnym usloviyam Esli obobshyonnaya funkciya sravnivaet znacheniya tipa parametra lyuboj konkretnyj tip ispolzovannyj v nej dolzhen podderzhivat operacii sravneniya esli prisvaivaet znacheniya tipa parametra peremennym konkretnyj tip dolzhen obespechivat korrektnoe prisvaivanie Obobshyonnoe programmirovanie v yazykahC Osnovnaya statya Shablony C V yazyke C obobshyonnoe programmirovanie osnovyvaetsya na ponyatii shablon oboznachaemom klyuchevym slovom template Shiroko primenyaetsya v standartnoj biblioteke C sm STL a takzhe v storonnih bibliotekah boost Loki Bolshoj vklad v poyavlenie razvityh sredstv obobshyonnogo programmirovaniya v C vnyos Aleksandr Stepanov V kachestve primera privedyom shablon obobshenie funkcii vozvrashayushej bolshee znachenie iz dvuh Opisanie shablona funkcii template lt typename T gt T max T x T y if x lt y return y else return x Primenenie funkcii zadannoj shablonom int a max 10 15 double f max 123 11 123 12 ili shablon obobshenie klassa svyaznogo spiska template lt class T gt class List public void Add const T amp Element bool Find const T amp Element Haskell Yazyk Haskell predostavlyaet obobshyonnoe programmirovanie tipov dannyh V sleduyushem primere a parametricheskaya peremennaya tipa data List a Nil Cons a List a length List a gt Int length Nil 0 length Cons tl 1 length tl Primer vychislenij length Cons 1 Cons 2 Nil 2 Java Java predostavlyaet sredstva obobshyonnogo programmirovaniya sintaksicheski osnovannye na C nachinaya s versii J2SE 5 0 V etom yazyke imeyutsya generics ili kontejnery tipa T podmnozhestvo obobshyonnogo programmirovaniya NET Na platforme NET sredstva obobshyonnogo programmirovaniya poyavilis v versii 2 0 Obyavlenie obobshennogo klassa public class GenericList lt T gt void Add T input class TestGenericList private class ExampleClass static void Main GenericList lt int gt list1 new GenericList lt int gt GenericList lt string gt list2 new GenericList lt string gt GenericList lt ExampleClass gt list3 new GenericList lt ExampleClass gt Primer na C interface IPerson string GetFirstName string GetLastName class Speaker public void SpeakTo lt T gt T person where T IPerson string name person GetFirstName this say Hello name D Primer rekursivnoj generacii na osnove shablonov D http digitalmars com d 2 0 template html template Foo T R T tip R nabor tipov void Foo T t R r writeln t static if r length if more arguments Foo r do the rest of the arguments void main Foo 1 a 6 8 prints 1 a 6 8 Object Pascal Podderzhka obobshyonnogo programmirovaniya kompilyatorom Free Pascal poyavilas nachinaya s versii 2 2 v 2007 godu V Delphi s oktyabrya 2008 goda Osnova podderzhki obobshyonnyh klassov snachala poyavilas v Delphi 2007 NET v 2006 godu no ona zatragivala tolko NET Framework Bolee polnaya podderzhka obobshyonnogo programmirovaniya byla dobavlena v Delphi 2009 Obobshyonnye klassy takzhe podderzhivayutsya v Object Pascal v sisteme PascalABC NET Nim import typetraits proc getType T x T string return x type name echo getType 21 napechataet int echo getType 21 12 napechataet float64 echo getType string napechataet stringPrimechaniyaPython Generic neopr Data obrasheniya 28 maya 2020 Arhivirovano 9 fevralya 2021 goda V Delphi i PascalABC NET Sik Li Lamsdejn 2006 p 39 Sik Li Lamsdejn 2006 p 47 48 Sik Li Lamsdejn 2006 p 40 45 Gabriel Dos Reis Jaakko Jarvi What is Generic Programming Freepascal Generics neopr Data obrasheniya 1 fevralya 2011 Arhivirovano 15 dekabrya 2010 goda Ssylkigeneric programming org angl Gabriel Dos Reis and Jaakko Jarvi What is Generic Programming Obobshyonnoe programmirovanie v Delphi rus LiteraturaDzheremi Sik Laj Kvan Li Endryu Lamsdejn C Boost Graph Library Piter 2006 304 s ISBN 5 469 00352 3 Stepanov Aleksandr A Rouz Deniel E Ot matematiki k obobshyonnomu programmirovaniyu DMK Press 2016 264 s ISBN 978 5 97060 379 6
