Մասնակից:Karinaa111/Ավազարկղ
Ընդհանրացված ծրագրավորումը (անգլ.՝ generic programming) ծրագրավորման պարադիգմ է, որը բաղկացած է տվյալների և ալգորիթմների նկարագրությունից, որոնք կարող են կիրառվել տարբեր տեսակի տվյալների վրա՝ առանց այդ նկարագրությունը փոխելու։ Այն այս կամ այն ձևով աջակցվում է տարբեր ծրագրավորման լեզուներով: Ընդհանրացված ծրագրավորման հնարավորությունները առաջին անգամ հայտնվեցին ջեներիկների(ընդհանրացված ֆունկցիաների) տեսքով 1970-ականներին Clu-ում և Ada-ում, այնուհետև պարամետրային պոլիմորֆիզմի տեսքով ML-ում և նրա հետնորդներում, այնուհետև շատ օբյեկտ կողմնորոշված լեզուներում, ինչպիսիք են C++, Python[1], Java, Object Pascal[2], D, Eiffel, լեզուներ .NET պլատֆորմի համար և այլն:
Մեթոդաբանություն[խմբագրել | խմբագրել կոդը]
Ընդհանրացված ծրագրավորումը դիտարկվում է որպես ծրագրավորման մեթոդաբանություն, որը հիմնված է տվյալների կառուցվածքների և ալգորիթմների տարանջատման վրա՝ պահանջների աբստրակտ նկարագրությունների կիրառմամբ[3]: Աբստրակտ պահանջների նկարագրությունները աբստրակտ տվյալների տիպի հասկացության ընդլայնումն են: Մեկ տեսակ նկարագրելու փոխարեն ընդհանրացված ծրագրավորման մեջ օգտագործվում է տիպերի ընտանիքի նկարագրությունը, որոնք ունեն ընդհանուր ինտերֆեյս և իմաստային վարքագիծ (անգլ.՝ semantic behavior)։ Պահանջների ամբողջությունը, որոնք նկարագրում են ինտերֆեյսը և իմաստային վարքագիծը, կոչվում է կոնցեպցիա (concept): Այսպիսով, ընդհանրացված ոճով գրված ալգորիթմը կարող է օգտագործվել ցանկացած տիպի համար։ Այդպիսի հատկանիշը կոչվում է պոլիմորֆիզմ։
Ասում են, որ տիպը մոդելավորում է կոնցեպցիան (կոնցեպցիայի մոդել է), եթե այն բավարարում է դրա պահանջներին: Կոնցեպցիանը մեկ այլ կոնցեպցիայի հստակեցումն է, եթե այն լրացնում է վերջինս: Կոնցեպցիայի պահանջները պարունակում են հետևյալ տեղեկությունները
- Թույլատրելի արտահայտությունները (անգլ.՝ valid expressions) ծրագրավորման լեզուների արտահայտություններ են, որոնք պետք է հաջողությամբ կոմպիլյացվեն կոնցեպցիան մոդելավորող տիպերի համար:
- Ասոցիացված տիպեր (associated types) օժանդակ տիպեր են, որոնք որոշակի կապ ունեն կոնցեպցիան մոդելավորող տիպի հետ:
- Ինվարիանտները(invariants) տիպերի բնութագրիչներ են, որոնք միշտ պետք է ճշմարիտ լինեն կատարման ժամանակ: Սովորաբար արտահայտվում է նախապայմանների և հետպայմանների տեսքով։ Նախապայմանին չբավարարելը հանգեցնում է համապատասխան գործողության անկանխատեսելիության և կարող է հանգեցնել սխալների:
- Բարդության երաշխիքներ(complexity guarantees) թույլատրելի արտահայտության առավելագույն կատարման ժամանակն է
C++ լեզվում օբյեկտ կողմնորոշված ծրագրավորումը (ՕԿԾ) իրականացվում է վիրտուալ ֆունկցիաների և ժառանգման միջոցով, մինչդեռ ընդհանրացված ծրագրավորումը իրականացվում է դասի շաբլոնների և ֆունկցիաների միջոցով: Այնուամենայնիվ, երկու մեթոդաբանությունների էությունը միայն անուղղակիորեն է կապված կոնկրետ իրականացման տեխնոլոգիաների հետ: ՕԿԾ-ն հիմնված է ենթատիպային պոլիմորֆիզմի վրա, մինչդեռ ընդհանրացված ծրագրավորումը հիմնված է պարամետրային պոլիմորֆիզմի վրա:Այլ լեզուներում երկուսն էլ կարող են այլ կերպ իրականացվել:Օրինակ, CLOS-ում մուլտիմեթոդներն ունեն պարամետրային պոլիմորֆիզմի նման իմաստ ։
Մասերը և Ստեպանովը առանձնացնում են ընդհանրացված ծրագրավորման մեթոդաբանության խնդրի լուծման հետևյալ փուլերը:
- Գտնել օգտակար և արդյունավետ ալգորիթմ:
- Սահմանել ընդհանրացված ներկայացում (պարամետրացնել ալգորիթմը ՝ նվազագույնի հասցնելով մշակվող տվյալների պահանջները):
- Նկարագրել մի շարք (նվազագույն) պահանջներ, որոնք բավարարելով, դուք դեռ կարող եք ստանալ արդյունավետ ալգորիթմներ:
- Ստեղծեք շրջանակ ՝ հիմնված դասակարգված պահանջների վրա:
Նվազագույնի հասցնելը և շրջանակի ստեղծումը նպատակ ունեն ստեղծել այնպիսի կառուցվածք, որում ալգորիթմները կախված չեն տվյալների հատուկ տիպերից:Այս մոտեցումը արտացոլված է STL գրադարանի կառուցվածքում։
Ընդհանրացված ծրագրավորման սահմանման այլընտրանքային մոտեցում է՝ տվյալների տիպի ընդհանրացված ծրագրավորումը (անգլ. datatype generic programming), որն առաջարկվել է Ռիչարդ Բիրդի և Լամբերտ Մերտենսի կողմից։ Դրանում տվյալների տիպի կառուցվածքները ընդհանրացված ծրագրերի պարամետրեր են: Դրա համար ծրագրավորման լեզվում ներդրվում է աբստրակցիայի նոր մակարդակ, այն է՝ պարամետրացում՝ կապված փոփոխականի գրելաձևով հանրահաշվական դասերի հետ։ Թեև երկու մոտեցումների տեսությունները կախված չեն ծրագրավորման լեզվից, Մասեր-Ստեպանովի մոտեցումը, որը շեշտը դնում է կոնցեպցիայի վերլուծության վրա, C++ ծրագրավորման լեզուն դարձրել է իր հիմնական հարթակը, մինչդեռ ընդհանրացված տվյալների տիպի ծրագրավորումն օգտագործում է գրեթե բացառապես Haskell-ը և դրա տարբերակները։
Общий механизм[խմբագրել | խմբագրել կոդը]
Средства обобщённого программирования реализуются в языках программирования в виде тех или иных синтаксических средств, дающих возможность описывать данные (типы данных) и алгоритмы (процедуры, функции, методы), параметризуемые типами данных. У функции или типа данных явно описываются формальные параметры-типы. Это описание является обобщённым и в исходном виде непосредственно использовано быть не может.
Ընդհանրացված ծրագրավորման գործիքներն իրականացվում են ծրագրավորման լեզուներում որոշակի շարահյուսական միջոցների տեսքով, որոնք հնարավորություն են տալիս նկարագրել տվյալները(տվյալների տեսակները) և ալգորիթմները (կոնցեպցիաներ, ֆունկցիաներ, մեթոդներ), որոնք պարամետրացվում են տվյալների տիպերի կողմից: Ֆունկցիան կամ տվյալների տիպը հստակ նկարագրում են ֆորմալ պարամետրերը՝ տիպերը: Այս նկարագրությունը ընդհանրացված է և չի կարող ուղղակիորեն օգտագործվել իր սկզբնական տեսքով:
Ծրագրի այն վայրերում, որտեղ օգտագործվում է ընդհանրացված տիպը կամ ֆունկցիան, ծրագրավորողը պետք է հստակ նշի իրական պարամետրը՝ նկարագրությունը բնութագրող տիպը: Օրինակ, երկու արժեքների վերադասավորման ընդհանրացված ֆունկցիան կարող է ունենալ պարամետր-տիպ, որը սահմանում է այն արժեքների տիպը, որը այն փոխում է: Երբ ծրագրավորողը պետք է փոխի երկու ամբողջ արժեք, նա կանչում է «ամբողջ թիվ» տիպի պարամետրով և երկու պարամետրով՝ ամբողջ թվեր, երբ երկու տող' "string" տիպի պարամետրով և երկու պարամետրով 'տողերով: Այս ընթացակարգը կոչվում է "ամբողջ թիվ": ընթացակարգ ' "ամբողջ Թիվ" տիպի պարամետրով և երկու պարամետրով 'ամբողջ թվեր, երբ երկու տող' "լարային" տիպի պարամետրով և երկու պարամետրով 'տողերով: Այս ընթացակարգը կոչվում է "ամբողջ թիվ":
В тех местах программы, где обобщённый тип или функция используется, программист должен явно указать фактический параметр-тип, конкретизирующий описание. Например, обобщённая процедура перестановки местами двух значений может иметь параметр-тип, определяющий тип значений, которые она меняет местами. Когда программисту нужно поменять местами два целых значения, он вызывает процедуру с параметром-типом «целое число» и двумя параметрами — целыми числами, когда две строки — с параметром-типом «строка» и двумя параметрами — строками. В случае с данными программист может, например, описать обобщённый тип «список» с параметром-типом, определяющим тип хранимых в списке значений. Тогда при описании реальных списков программист должен указать обобщённый тип и параметр-тип, получая, таким образом, любой желаемый список с помощью одного и того же описания.
Компилятор, встречая обращение к обобщённому типу или функции, выполняет необходимые процедуры статического контроля типов, оценивает возможность заданной конкретизации и при положительной оценке генерирует код, подставляя фактический параметр-тип на место формального параметра-типа в обобщённом описании. Естественно, что для успешного использования обобщённых описаний фактические типы-параметры должны удовлетворять определённым условиям. Если обобщённая функция сравнивает значения типа-параметра, любой конкретный тип, использованный в ней, должен поддерживать операции сравнения, если присваивает значения типа-параметра переменным — конкретный тип должен обеспечивать корректное присваивание.
Ընդհանրացված ծրագրավորումը լեզուներում[խմբագրել | խմբագրել կոդը]
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 году[4]. В 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». Արխիվացված է օրիգինալից 2021-02-09-ին. Վերցված է 2020-05-28-ին.
{{cite web}}
: Unknown parameter|deadlink=
ignored (|url-status=
suggested) (օգնություն) - ↑ В Delphi и PascalABC.NET
- ↑ Сик, Ли, Ламсдэйн, 2006, էջ 47—48
- ↑ «Freepascal.Generics». Արխիվացված է օրիգինալից 2010-12-15-ին. Վերցված է 2011-02-01-ին.
{{cite web}}
: Unknown parameter|deadlink=
ignored (|url-status=
suggested) (օգնություն)
Հղումներ[խմբագրել | խմբագրել կոդը]
- 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