«Մասնակից:MHamlet/Սևագրություն/2»–ի խմբագրումների տարբերություն

Առանց խմբագրման ամփոփման
No edit summary
No edit summary
[[Ծրագրավորման լեզու]]ներում և [[Տիպերի տեսություն|տիպերի տեսության]] մեջ '''պոլիմորֆիզմ''' են անվանում տարբեր [[տվյալների տիպ|տիպ]] ունեցող տվյալների միանման մշակումը։
{{Տեղեկաքարտ Ծրագրավորման լեզու
| name = BCPL
| logo =
| semantics =
| paradigm = [[Գործընթացային ծրագրավորում|գործընթացային]], [[կառուցվածքային ծրագրավորում|կառուցվածքային]]
| class= [[Ինտերպրետատոր|ինտերպրետացվող]]
| year = [[1966]]թ․
| designer = Մարտին Ռիչարդս
| extension =
| latest_release_version =
| latest_release_date =
| latest_preview_version =
| latest_preview_date =
| typing = անտիպ (բոլոր տիպերն ունեն մեքենայական բառի երկարությունը)
| implementations =
| dialects =
| influenced_by = [[CPL (ծրագրավորման լեզու)|CPL]]
| influenced = [[B (ծրագրավորման լեզու)|B]], [[C (ծրագրավորման լեզու)|C]]
}}
'''BCPL''' ('''Basic Combined Programming Language'''), [[ծրագրավորման լեզու]], որն մշակվել է Մարտին Ռիչարդսի կողմից [[1966]] թվականին [[Քեմբրիջի համալսարան]]ում։ Ի սկզբանե այն նախատեսված է եղել այլ լեզուների համար [[կոմպիլյատորներ]] գրելու համար։
 
Գոյություն ունեն պոլիմորֆիզմի մի քանի սկզբունքորեն տարբեր տեսակներ, որոնցից երկուսը նկարագրված են եղել [[:en:Christopher Strachey|Քրիստոֆեր Ստրեչի]] կողմից [[1967]]թ․։
Այժմ BCPL-ը գործնականում չի օգտագործվում, բայց ժամանակին այն շատ կարևոր դեր ուներ՝ իր դյուրակիրության համար։ Լեզվի հառաոտ տարբերակը Урезанная версия языка с несколько изменённым синтаксисом стала языком программирования [[Би_(язык_программирования)|B]], который оказал сильное влияние на [[Си (язык программирования)|язык программирования Си]]. По этой причине программисты в шутку расшифровывали название BCPL как ''Before C Programming Language'' («язык программирования, появившийся до языка Си»)<ref>Питер Ван Дер Линден, «Expert C Programming: Deep C Secrets» (Prentice Hall, 1994), ISBN 978-0131774292</ref>.
 
Եթե ֆունկցիան նկարագրում է հստակ նկարագրված տիպերի և նրանց կոմբինացիաների սահմանափակ խմբերի տարբեր իրականացումներ (հնարավոր է, տարբեր պահվածքներով), դա անվանում են '''իրավիճակային պոլիմորֆիզմ''' ('''[[ad hoc]] polimorphism''')։ Իրավիճակային պոլիմորֆիզմն աջակցվում է շատ լեզուներում [[ֆունկցիաների վերբեռնում|ֆունկցիաների և մեթոդների վերբեռնման]] միջոցով։
BCPL стал ответом на сложности своего предшественника, языка [[CPL (язык программирования)|CPL]], разработанного в начале 1960-х. Ричардс создал BCPL, «удалив из полного языка те функции, которые усложняли компиляцию». Первая реализация компилятора, работавшего на [[IBM 7094]] под ОС [[CTSS]], была написана Ричардсом весной 1967, в ходе посещения им исследовательской лаборатории «Project MAC» в [[Массачусетский технологический институт|МТИ]]. Язык был впервые описан в документе, представленном на 1969 Spring Joint Computer Conference.
 
Եթե կոդը գրված է կոնկրետ տվյալների տիպերից [[աբստրակցիա|անկախ]] և, ինչի հետևանքով, կարող է ազատ օգտագործվել ցանկացած նոր տիպերի հետ, անվանում են '''պարամետրական պոլիմորֆիզմ'''։ [[:en:John C. Reynolds|Ջոն Ս․ Ռեյնոլդս]]ը և, նրանից անկախ, [[:en:Jean-Yves Girard|Ժան-Իվ Ժիրար]]ը, նկարագրեցին այդ նշանակումը որպես [[լամբդա-հաշիվ|լամբդա-հաշվման]] զագացում (որն անվանում են [[F համակարգ|պոլիմորֆ լամբդա-հաշիվ կամ F համակարգ]])։ Պարամետրական պոլիմորֆիզմն լայնորեն կիրառվում է [[ստատիկ տիպավորում|ստատիկ տիպավորմամբ]] [[ֆունկցիոնալ ծրագրավորման լեզու|ֆունկցիոնալ ծրագրավորման լեզուներում]]։ Օբյեկտային կողմնորոշված համայնքներում պարամետրիկ պոլիմորֆիզմի կիրառմամբ ծրագրավորումն անվանում են [[ընդհանրացված ծրագրավորում]]։
== Пример ==
Печать факториала:
<pre>
GET "libhdr"
 
Պոլիմորֆիզմը համարվում է [[տիպերի համակարգ]]ի հիմնարար հատկություն։ Հաճախ տարբերում են ստատիկ ոչ պոլիմորֆ տիպավորում ([[Angol]]-ի և [[BCPL]]-ի հետնորդները), դինամիկ տիպավորում ([[Lisp]]-ի, [[Smalltalk]]-ի, [[APL (ծրագրավորման լեզու)|APL]]-ի հետնորդները) և ստատիկ պոլիմորֆ տիպավորումը ([[ML]]-ի հետնորդները)։ В наибольшей степени применение ad hoc полиморфизма присуще при неполиморфной типизации, параметрического — при полиморфной. Параметрический полиморфизм и динамическая типизация намного существеннее, чем ситуативный полиморфизм, повышают коэффициент [[повторное использование кода|повторного использования кода]], поскольку определенная единственный раз функция реализует без дублирования заданное поведение для бесконечного множества вновь определяемых типов, удовлетворяющих требуемым в функции условиям.
LET start() = VALOF
 
{ FOR i = 1 TO 5 DO writef("fact(%n) = %i4*n", i, fact(i))
Некоторые языки совмещают различные формы полиморфизма, порой сложным образом, что формирует самобытную идеологию в них и влияет на применяемые методологии декомпозиции задач. Например, в [[Smalltalk]] любой класс способен принять сообщения любого типа, и либо обработать его самостоятельно (в том числе посредством [[Отражение (программирование)|интроспекции]]), либо ретранслировать другому классу — таким образом, несмотря на широкое использование перегрузки функций, формально любая операция является неограниченно полиморфной и может применяться к данным любого типа.
RESULTIS 0
 
В [[объектно-ориентированное программирование|объектно-ориентированном программировании]] '''полиморфизм подтипов''' (или '''полиморфизм включения''') представляет собой концепцию в [[теория типов|теории типов]], предполагающую использование единого имени (идентификатора) при обращении к объектам нескольких разных классов, при условии, что все они являются '''подклассами''' одного общего '''надкласса''' (суперкласса). Полиморфизм подтипов состоит в том, что несколько типов формируют подмножество другого типа (их базового класса) и потому могут использоваться через общий интерфейс.
 
== История ==
Термин «полиморфизм» происходит от ''др.-греч.'' πολύς («много») и μορφή («форма, облик, устройство»). Термин впервые упоминается в конспекте лекций [[:en:Christopher Strachey|Кристофера Стрэчи]] под названием «[[:en:Fundamental Concepts in Programming Languages|Фундаментальные основы языков программирования]]». Впервые полиморфизм реализован в языке [[ML]], наряду с понятиями [[наследование (программирование)|наследования]] и [[инкапсуляция (программирование)|инкапсуляции]]. Спустя несколько лет подмножество [[Common Lisp Object System]] языка [[Common Lisp]] было стандартизировано, став первым стандартом объектно-ориентированного программирования.
 
== Виды полиморфизма ==
 
=== Параметрический полиморфизм ===
{{см. также|:en:Parametric polymorphism}}
Параметрический полиморфизм позволяет определять функцию или тип данных обобщённо, чтобы значения могли обрабатываться идентично вне зависимости от их типа. Параметрический полиморфизм делает язык более выразительным, сохраняя полную статическую [[:en:type safety|типобезопасность]].
 
Параметрический полиморфизм повсеместно используется в [[функциональное программирование|функциональном программировании]], где он обычно обозначается просто как «полиморфизм». Следующий пример демонстрирует параметризованный тип «[[список (программирование)|список]]» и две опредёленные на нём параметрически полиморфные функции:
<source lang=haskell>
data List a = Nil | Cons a (List a)
 
length :: List a -> Integer
length Nil = 0
length (Cons x xs) = 1 + length xs
 
map :: (a -> b) -> List a -> List b
map f Nil = Nil
map f (Cons x xs) = Cons (f x) (map f xs)
</source>
Параметрический полиморфизм связывается с [[:en:Subtyping|подтипизацией]] понятиями [[:en:bounded quantification|связанной квантификации]] и [[Ковариантность и контравариантность (программирование)|ковариантности/контравариантности]] (или полярности) [[:en:type constructor|конструкторов типов]].
 
Концепция параметрического полиморфизма применима как к данным, так и к функциям. Функция, принимающая на входе или порождающая значения разных типов, называется '''полиморфной функцией'''. Тип данных, используемый как обобщённый (например, [[список (программирование)|список]] элементов произвольного типа), называется '''полиморфным типом данных'''.
 
Параметрический полиморфизм также доступен в некоторых [[императивный язык программирования|императивных]] (в частности, [[объектно-ориентированный язык программирования|объектно-ориентированных]]) языках программирования, где для его обозначения обычно используется термин «[[обобщённое программирование]]»:
<!-- Код не отлаживался, замеченную синтаксическую ошибку можно исправить -->
<source lang=c>
struct segment { int start; int end; };
 
int seg_cmpr( struct segment *a, struct segment *b )
{ return abs( a->end - a->start ) - abs( b->end - b->start ); }
 
int str_cmpr( char **a, char **b )
{ return strcmp( *a, *b ); }
 
struct segment segs[] = { {2,5}, {4,3}, {9,3}, {6,8} };
char* strs[] = { "three", "one", "two", "five", "four" };
 
main()
{
qsort( strs, sizeof(strs)/sizeof(char*), sizeof(char*),
(int (*)(void*,void*))str_cmpr );
 
qsort( segs, sizeof(segs)/sizeof(struct segment), sizeof(struct segment),
(int (*)(void*,void*))seg_cmpr );
...
}
</source>
<br />
<source lang="cpp">
template <typename T> T max(T x, T y)
{
if (x < y)
return y;
else
return x;
}
 
int main()
AND fact(n) = n=0 -> 1, n*fact(n-1)
{
</pre>
int a = max(10,15);
double f = max(123.11, 123.12);
...
}
</source>
В первом случае одна функция обрабатывает массивы элементов любого типа, для которого определена функция сравнения. Во втором случае определение функции на уровне исходного кода по-прежнему единственно, но в результате компиляции порождается такое количество перегруженных мономорфных функций, с каким количеством типов данных функция вызывается в программе (параметрический полиморфизм на уровне исходного кода транслируется в ad hoc полиморфизм на уровне целевой платформы).
 
Параметрически полиморфная функция использует аргументы на основе поведения, а не значения, апеллируя лишь к необходимым ей свойствам аргументов, что делает её применимой в любом контексте, где тип объекта удовлетворяет заданным требованиям поведения. Таким образом, реализуется концепция [[:en:parametricity|параметричности]].
 
=== Ситуативный (ad hoc) полиморфизм ===
{{см. также|:en:Ad hoc polymorphism}}
 
[[:en:Christopher Strachey|Кристофер Стрэчи]] избрал термин «ситуативный полиморфизм» для описания полиморфных функций, вызываемых для аргументов разных типов, но реализующих различное поведение в зависимости от типа аргумента (называемых также [[перегрузка функций|перегруженными функциями]] и [[перегрузка операторов|перегруженными операторами]]). Термин «[[ad hoc]]» (лат. ''спонтанный, сделанный под текущую задачу'') в этом смысле не несёт уничижительного подтекста — он означает лишь, что этот вид полиморфизма не является фундаментальным свойством [[:en:Type system|системы типов]] языка. В следующем примере функции <code>Add</code> выглядят как реализующие один и тот же функционал над разными типами, но компилятор определяет их как две совершенно разные функции.
<source lang=pascal>
program Adhoc;
 
function Add( x, y : Integer ) : Integer;
begin
Add := x + y
end;
 
function Add( s, t : String ) : String;
begin
Add := Concat( s, t )
end;
 
begin
Writeln(Add(1, 2));
Writeln(Add('Hello, ', 'World!'));
end.
</source>
 
В [[динамическая типизация|динамически типизируемых языках]] ситуация может быть более сложной, так как выбор требуемой функции для вызова может быть осуществлён только во время исполнения программы.
 
Ситуативный полиморфизм иногда используется совместно с параметрическим. В языке [[Haskell]] стремление предоставить одновременно полиморфизм и перегрузку привело к необходимости введения принципиально нового понятия — [[:en:Type class|классов типов]] (которые, вопреки распространённому заблуждению, не являются подмножеством [[объектно-ориентированное программирование|объектно-ориентированной парадигмы программирования]]). С одной стороны, это позволяет существенно повысить выразительность программ, с другой чрезмерное их использование может приводить к сбоям механизма [[вывод типов|выведения типов]], что вынуждает программистов отказываться от его использования, явно декларируя типы функций.
 
=== Полиморфизм подтипов (или полиморфизм включения) ===
{{см. также|:en:Subtype polymorphism}}
 
Некоторые языки представляют идею '''[[:en:Subtyping|подтипизации]]''' для ограничения спектра типов, применимых в определённом частном случае параметрического полиморфизма. В этих языках полиморфизм подтипов (обычно называемый также динамическим полиморфизмом) позволяет функции, определённой на типе <code>T</code>, также корректно исполняться для аргументов, принадлежащих типу <code>S</code>, являющемуся '''подтипом''' <code>T</code> (в соответствии с [[Принцип подстановки Барбары Лисков|принципом подстановки Барбары Лисков]]). Такое отношение типов обычно записывается как <code>S&nbsp;&lt;:&nbsp;T</code>. При этом тип <code>T</code> называется '''надтипом''' (или супертипом) для <code>S</code>, что обозначается как <code>T&nbsp;:&gt;&nbsp;S</code>.
 
Например, если имеются типы <code>Number</code>, <code>Rational</code> и <code>Integer</code>, связанные отношениями
<code>Number :> Rational</code> и <code>Number :> Integer</code>, то функция, определённая на типе <code>Number</code>, также сможет принять на вход аргументы типов <code>Integer</code> или <code>Rational</code>, и её поведение будет идентичным. Действительный тип объекта может быть скрыт как «чёрный ящик», и предоставляться лишь по запросу идентификации объекта. На самом деле, если тип <code>Number</code> является абстрактным, то конкретного объекта этого типа даже не может существовать (см. [[абстрактный тип данных]], [[абстрактный класс]]). Данная иерархия типов известна — особенно в контексте языка [[Scheme (язык программирования)|Scheme]] — как [[:en:Numerical tower|числовая башня]], и обычно содержит большее количество типов.
 
Объектно-ориентированные языки программирования реализуют полиморфизм подтипов посредством [[наследование (программирование)|наследования]], то есть определения подклассов. В большинстве реализаций каждый класс содержит т. н. виртуальную таблицу — таблицу функций, реализующих полиморфную часть интерфейса класса — и каждый объект (экземпляр класса) содержит указатель на виртуальную таблицу своего класса, по согласованию с которой производится вызов полиморфного метода. Такой механизм используется в случаях:
* '''[[:en:late binding|позднего связывания]]''', где виртуальные функции не связаны до момента вызова;
* '''[[:en:single dispatch|одиночной диспетчеризации]]''' (то есть одноаргументного полиморфизма), где виртуальные функции связываются посредством простого просмотра виртуальной таблицы по первому аргументу (данному экземпляру класса), так что динамические типы остальных аргументов не учитываются.
То же применимо и к большинству остальных популярных объектных моделей. Некоторые, однако, такие как [[CLOS]], предоставляют [[множественная диспетчеризация|множественную диспетчеризацию]], в которой метод полиморфен по всем аргументам.
 
В следующем примере коты и псы являются подтипами животных. Процедура определена для животных, но также будет работать корректно, получив на входе один из подтипов:
<!-- Атрибут «lang=java» используется лишь для подсветки синтаксиса — это не корректный код на Java -->
<source lang=java>
abstract class Animal {
abstract String talk();
}
class Cat extends Animal {
String talk() { return "Meow!"; }
}
class Dog extends Animal {
String talk() { return "Woof!"; }
}
 
public class MyClass {
public static void write(Animal a) {
System.out.println(a.talk());
}
public static void main(String args[]) {
write(new Cat());
write(new Dog());
}
}
 
</source>
 
== См. также ==
* [[:en:Polymorphism in object-oriented programming|Polymorphism in object-oriented programming]]
* [[Утиная типизация]]
* [[Полиморфизм компьютерных вирусов]]
* [[Система F]] для [[лямбда-исчисление|лямбда-исчисления]] с параметрическим полиморфизмом
* [[Виртуальное наследование]]
* [[:en:Type class|Класс типов]]
 
== Примечания ==
 
== Ссылки ==
* [[:en:Robert Harper (computer scientist)|Харпер Р.]] — [http://bookre.org/reader?file=532778&pg=37 Введение в Стандартный ML, с.32, «Полиморфизм и перегрузка»]
* http://msdn.microsoft.com/ru-ru/library/ms173152(v=vs.90).aspx
 
== Литература ==
* Martin Richards, ''[http://cm.bell-labs.com/cm/cs/who/dmr/bcpl.html The BCPL Reference Manual]'' (Memorandum M-352, [[Project MAC]], Cambridge, MA, USA, July, 1967) <!-- temporary copy: http://www.fh-jena.de/~kleine/history/languages/Richards-BCPL-ReferenceManual.pdf -->
* {{книга
* [http://www.cl.cam.ac.uk/users/mr/BCPL.html Martin Richards' BCPL distribution]
|автор = Тимоти Бадд.
 
|заглавие = Объектно-ориентированное программирование в действии
{{rq|sources}}
|оригинал = An Introduction to Object-Oriented Programming
{{compu-lang-stub}}
|ответственный =
{{Языки программирования}}
|издание =
|место = СПб.
|издательство = «Питер»
|год = 1997
|страницы =
|страниц = 464
|серия = В действии
|isbn = 5-88782-270-8
|тираж = 6000
}}
* {{книга
|автор = John C. Mitchell
|часть = 6.4. Polymorphism and overloading
|заглавие = Concepts in Programming Languages
|издательство = Cambridge University Press
|год = 2002
|страницы = 145-151
|страниц = 540
|isbn = 978-0-521-78098-8
}}
 
[[Կատեգորիա:Օբյեկտային կողմնորոշված ծրագրավորում]]
[[Категория:Языки программирования]]
3107

edits