Մասնակից: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-ում մուլտիմեթոդներն ունեն պարամետրային պոլիմորֆիզմի նման իմաստ ։

Մասերը և Ստեպանովը առանձնացնում են ընդհանրացված ծրագրավորման մեթոդաբանության խնդրի լուծման հետևյալ փուլերը:

  1. Գտնել օգտակար և արդյունավետ ալգորիթմ:
  2. Սահմանել ընդհանրացված ներկայացում (պարամետրացնել ալգորիթմը ՝ նվազագույնի հասցնելով մշակվող տվյալների պահանջները):
  3. Նկարագրել մի շարք (նվազագույն) պահանջներ, որոնք բավարարելով, դուք դեռ կարող եք ստանալ արդյունավետ ալգորիթմներ:
  4. Ստեղծեք շրջանակ ՝ հիմնված դասակարգված պահանջների վրա:

Նվազագույնի հասցնելը և շրջանակի ստեղծումը նպատակ ունեն ստեղծել այնպիսի կառուցվածք, որում ալգորիթմները կախված չեն տվյալների հատուկ տիպերից:Այս մոտեցումը արտացոլված է STL գրադարանի կառուցվածքում։

Ընդհանրացված ծրագրավորման սահմանման այլընտրանքային մոտեցում է՝ տվյալների տիպի ընդհանրացված ծրագրավորումը (անգլ. datatype generic programming), որն առաջարկվել է Ռիչարդ Բիրդի և Լամբերտ Մերտենսի կողմից։ Դրանում տվյալների տիպի կառուցվածքները ընդհանրացված ծրագրերի պարամետրեր են: Դրա համար ծրագրավորման լեզվում ներդրվում է աբստրակցիայի նոր մակարդակ, այն է՝ պարամետրացում՝ կապված փոփոխականի գրելաձևով հանրահաշվական դասերի հետ։ Թեև երկու մոտեցումների տեսությունները կախված չեն ծրագրավորման լեզվից, Մասեր-Ստեպանովի մոտեցումը, որը շեշտը դնում է կոնցեպցիայի վերլուծության վրա, C++ ծրագրավորման լեզուն դարձրել է իր հիմնական հարթակը, մինչդեռ ընդհանրացված տվյալների տիպի ծրագրավորումն օգտագործում է գրեթե բացառապես Haskell-ը և դրա տարբերակները։

Общий механизм

խմբագրել

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

Ընդհանրացված ծրագրավորման գործիքներն իրականացվում են ծրագրավորման լեզուներում որոշակի շարահյուսական միջոցների տեսքով, որոնք հնարավորություն են տալիս նկարագրել տվյալները(տվյալների տեսակները) և ալգորիթմները (կոնցեպցիաներ, ֆունկցիաներ, մեթոդներ), որոնք պարամետրացվում են տվյալների տիպերի կողմից: Ֆունկցիան կամ տվյալների տիպը հստակ նկարագրում են ֆորմալ պարամետրերը՝ տիպերը: Այս նկարագրությունը ընդհանրացված է և չի կարող ուղղակիորեն օգտագործվել իր սկզբնական տեսքով:

Ծրագրի այն վայրերում, որտեղ օգտագործվում է ընդհանրացված տիպը կամ ֆունկցիան, ծրագրավորողը պետք է հստակ նշի իրական պարամետրը՝ նկարագրությունը բնութագրող տիպը: Օրինակ, երկու արժեքների վերադասավորման ընդհանրացված ֆունկցիան կարող է ունենալ պարամետր-տիպ, որը սահմանում է այն արժեքների տիպը, որը այն փոխում է: Երբ ծրագրավորողը պետք է փոխի երկու ամբողջ արժեք, նա կանչում է «ամբողջ թիվ» տիպի պարամետրով և երկու պարամետրով՝ ամբողջ թվեր, երբ երկու տող' "string" տիպի պարամետրով և երկու պարամետրով 'տողերով: Այս ընթացակարգը կոչվում է "ամբողջ թիվ": ընթացակարգ ' "ամբողջ Թիվ" տիպի պարամետրով և երկու պարամետրով 'ամբողջ թվեր, երբ երկու տող' "լարային" տիպի պարամետրով և երկու պարամետրով 'տողերով: Այս ընթացակարգը կոչվում է "ամբողջ թիվ":

В тех местах программы, где обобщённый тип или функция используется, программист должен явно указать фактический параметр-тип, конкретизирующий описание. Например, обобщённая процедура перестановки местами двух значений может иметь параметр-тип, определяющий тип значений, которые она меняет местами. Когда программисту нужно поменять местами два целых значения, он вызывает процедуру с параметром-типом «целое число» и двумя параметрами — целыми числами, когда две строки — с параметром-типом «строка» и двумя параметрами — строками. В случае с данными программист может, например, описать обобщённый тип «список» с параметром-типом, определяющим тип хранимых в списке значений. Тогда при описании реальных списков программист должен указать обобщённый тип и параметр-тип, получая, таким образом, любой желаемый список с помощью одного и того же описания.

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

Ընդհանրացված ծրագրավորումը լեզուներում

խմբագրել

В языке 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 լեզուն ապահովում է տվյալների տիպերի ընդհանրացված ծրագրավորում: Հետևյալ օրինակում 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-ն տրամադրում է ընդհանրացված ծրագրավորման գործիքներ, որոնք շարահյուսորեն հիմնված են C++ լեզվի վրա՝սկսած J2SE 5.0 տարբերակից։ Այս լեզվում կան generics կամ «T տիպի կոնտեյներներ»՝ ընդհանրացված ծրագրավորման ենթաբազմություն ։

. 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>();
     }
 }
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:

// 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.

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

Ծանոթագրություններ

խմբագրել
  1. «Python Generic». Արխիվացված է օրիգինալից 2021-02-09-ին. Վերցված է 2020-05-28-ին. {{cite web}}: Unknown parameter |deadlink= ignored (|url-status= suggested) (օգնություն)
  2. В Delphi и PascalABC.NET
  3. Сик, Ли, Ламсдэйн, 2006, էջ 47—48
  4. «Freepascal.Generics». Արխիվացված է օրիգինալից 2010-12-15-ին. Վերցված է 2011-02-01-ին. {{cite web}}: Unknown parameter |deadlink= ignored (|url-status= suggested) (օգնություն)

Հղումներ

խմբագրել

Գրականություն

խմբագրել
  • Джереми Сик, Лай-Кван Ли, Эндрю Ламсдэйн. C++ Boost Graph Library. — Питер, 2006. — 304 с. — ISBN 5-469-00352-3
  • Степанов Александр А., Роуз Дэниэл Э. От математики к обобщённому программированию. — ДМК Пресс, 2016. — 264 с. — ISBN 978-5-97060-379-6