Әртүрлі типтегі аргументтерге полиморфты функцияларды қолдану
Ad hoc polymorphism
Әртүрлі типтерге қолданылатын полиморфтық функциялар – бағдарламалаудағы маңызды ұғым. Функция жүктемесі, түрлер жүйесі, Strachey жіктемесі туралы біліңіз.
Ағылшыншамен салыстырыңыз: абзацты басыңыз — түпнұсқа терезеде ашылады. Абзац астындағы EN түймесі оны мәтін ішінде көрсетеді.
Мазмұны
Кіріспе
Полиморфтық функцияларды әртүрлі типтегі аргументтерге қолдану
Applying polymorphic functions to arguments of different types
Бағдарламалау тілдерінде, ad hoc полиморфизмі – полиморфтық функцияларды әртүрлі типтегі аргументтерге қолдануға мүмкіндік беретін полиморфизмнің бір түрі. Себебі полиморфтық функция, оған қолданылған аргумент(тер) түріне байланысты, бірнеше ерекше және мүмкін гетерогендік іске асыруларды білдіре алады. Объектіге бағытталған немесе процедуралық ұғымдарға қатысты қарастырылғанда, бұл функцияны немесе операторды жүктеу деп те аталады. Бұл контексте ad hoc термині жағымсыз мағынада қолданылмайды; ол жай ғана осы полиморфизм түрі типтік жүйенің негізгі ерекшелігі емес екенін көрсетеді. Бұл параметрлік полиморфизмге қарсы, онда полиморфтық функциялар нақты типті көрсетпей жазылады, соның салдарынан бір абстрактілі іске асыруды кез келген типке ашық түрде қолдануға болады. Бұл жіктеме 1967 жылы Кристофер Стречимен енгізілген.
In programming languages, ad hoc polymorphism is a kind of polymorphism in which polymorphic functions can be applied to arguments of different types, because a polymorphic function can denote a number of distinct and potentially heterogeneous implementations depending on the type of argument(s) to which it is applied. When applied to object oriented or procedural concepts, it is also known as function overloading or operator overloading. The term ad hoc in this context is not intended to be pejorative; it refers simply to the fact that this type of polymorphism is not a fundamental feature of the type system. This is in contrast to parametric polymorphism, in which polymorphic functions are written without mention of any specific type, and can thus apply a single abstract implementation to any number of types in a transparent way. This classification was introduced by Christopher Strachey in 1967.
Ертеде міндетті түрде
Ad hoc полиморфизм – бұл жөнелту механизмі: бір атаулы функция арқылы басқару бірнеше функцияға жіберіледі, осы функциялардың қайсысы шақырылатынын нақты көрсетудің қажеті жоқ. Ашығу (overloading) әртүрлі типтегі бірнеше функцияны бірдей атаумен анықтауға мүмкіндік береді; компилятор немесе интерпретатор дұрыс функцияның шақырылуын автоматты түрде қамтамасыз етеді. Осылайша, бүтін сандар тізімдерін, жолдар тізімдерін, нақты сандар тізімдерін және т.б. қосатын функцияларды жазуға болады, және олардың барлығы append деп аталады – ал қосылатын тізімдердің типіне байланысты дұрыс append функциясы шақырылады. Бұл параметрлік полиморфизмнен өзгеше, онда функция кез келген тізіммен жұмыс істеу үшін жалпы түрде жазылуы керек. Ашығуды пайдалану арқылы функцияға берілген кіріс типіне байланысты екі толыққандай әртүрлі нәрсені орындау мүмкін; мұндай мүмкіндік параметрлік полиморфизмде жоқ. Ашығуға тағы бір көзқарас – реттілік (routine) тек атауымен емес, атауының және оның параметрлерінің санының, ретінің және типтерінің комбинациясымен бірегей түрде анықталады. Полиморфизмнің бұл түрі объектіге бағытталған бағдарламалау тілдерінде кең таралған, олардың көпшілігі операторларды функциялар сияқты ашып (overload) беруге мүмкіндік береді (операторларды ашып беру қараңыз). Динамикалық түрде типтелмеген және ad hoc полиморфизмі жоқ (түр кластарын қоса алғанда) кейбір тілдерде print int, print string сияқты ұзын функция атаулары қолданылады. Мұны адамның көзқарасына байланысты артықшылық (түсініктірек) немесе кемшілік (әртүрлі сөздерге толы) деп қарастыруға болады. Ашып беруден кейде пайда болатын артықшылық – маманданудың көрінуі, яғни бір атаудағы функция әртүрлі жолдармен іске асырылуы мүмкін, әрқайсысы жұмыс істейтін нақты дерек типіне оңтайландырылған. Бұл өнімділік үшін бірнеше жағдайға мамандану қажет код үшін ыңғайлы интерфейс бере алады. Бірақ кемшілігі – типтік жүйе әртүрлі іске асырулардың дәйіндігін кепілдей алмайды. Ашып беру компиляция уақытында орындалатындықтан, ол кіші типтегі полиморфизмдегі кеш байланысқа (late binding) балама болып табылмайды.
Ad hoc polymorphism is a dispatch mechanism: control moving through one named function is dispatched to various other functions without having to specify the exact function being called. Overloading allows multiple functions taking different types to be defined with the same name; the compiler or interpreter automatically ensures that the right function is called. This way, functions appending lists of integers, lists of strings, lists of real numbers, and so on could be written, and all be called append—and the right append function would be called based on the type of lists being appended. This differs from parametric polymorphism, in which the function would need to be written generically, to work with any kind of list. Using overloading, it is possible to have a function perform two completely different things based on the type of input passed to it; this is not possible with parametric polymorphism. Another way to look at overloading is that a routine is uniquely identified not by its name, but by the combination of its name and the number, order and types of its parameters. This type of polymorphism is common in object oriented programming languages, many of which allow operators to be overloaded in a manner similar to functions (see operator overloading). Some languages that are not dynamically typed and lack ad hoc polymorphism (including type classes) have longer function names such as print int, print string, etc. This can be seen as advantage (more descriptive) or a disadvantage (overly verbose) depending on one's point of view. An advantage that is sometimes gained from overloading is the appearance of specialization, e. g., a function with the same name can be implemented in multiple different ways, each optimized for the particular data types that it operates on. This can provide a convenient interface for code that needs to be specialized to multiple situations for performance reasons. The downside is that the type system cannot guarantee the consistency of the different implementations. Since overloading is done at compile time, it is not a substitute for late binding as found in subtyping polymorphism.
Кейін байлау
Алдыңғы бөлімге қарамастан, ad hoc полиморфизмінің басқа да жолдары бар. Мысалы, Smalltalk тілін қарастырайық. Smalltalk-та жүктеме орындалу кезінде жасалады, себебі әрбір жүктелген хабарламаның ("жүктелген функция") әдістері ("функцияны іске асыру") орындалуға дайын тұрғанда анықталады. Бұл бағдарлама компиляцияланғаннан кейін орындалу кезінде болады. Сондықтан полиморфизм басқа тілдердегідей, субтип полиморфизмі арқылы беріледі, және орындалу уақытында ad hoc полиморфизмімен функционалдығы кеңейтіледі. Жақын қарағанда, Smalltalk арнайы полиморфизмнің сәл өзгеше түрін ұсынатынын көреміз. Smalltalk-та кеш байланыс орындалу моделі бар, және ол объектілерге түсінілмеген хабарламаларды өңдеу қабілетін береді, сондықтан нақты хабарламаны арнайы жүктеместен полиморфизмді қолдана отырып, функционалдықты іске асыруға болады. Бұл күнделікті бағдарламалау үшін әдетте ұсынылмайтын тәжірибе болғанымен, проксилерді іске асыру кезінде өте пайдалы болуы мүмкін. Сонымен қатар, жалпы алғанда, әдеттегі сынып әдістері мен конструкторларды жүктеу полиморфизм деп есептелмейді, бірақ сыныптар тұрақты объектілер болып табылатын біркелкі тілдер бар. Мысалы, Smalltalk-та сыныптар тұрақты нысандар. Бұл өз кезегінде сыныптарға жіберілген хабарламаларды жүктеуге мүмкіндік береді, сондай-ақ сыныптар иерархиясынан мұрагерлік алмайтын, сыныптар сияқты әрекет ететін объектілерді құруға болады. Бұл Smalltalk-тің қуатты рефлексия мүмкіндіктерін пайдалануға арналған тиімді техникалар. Осыған ұқсас тәсілдер Self және Newspeak сияқты тілдерде де қолданылуы мүмкін.
The previous section notwithstanding, there are other ways in which ad hoc polymorphism can work out. Consider for example the Smalltalk language. In Smalltalk, the overloading is done at run time, as the methods ("function implementation") for each overloaded message ("overloaded function") are resolved when they are about to be executed. This happens at run time, after the program is compiled. Therefore, polymorphism is given by subtyping polymorphism as in other languages, and it is also extended in functionality by ad hoc polymorphism at run time. A closer look will also reveal that Smalltalk provides a slightly different variety of ad hoc polymorphism. Since Smalltalk has a late bound execution model, and since it provides objects the ability to handle messages that are not understood, it is possible to implement functionality using polymorphism without explicitly overloading a particular message. This may not be generally recommended practice for everyday programming, but it can be quite useful when implementing proxies. Also, while in general terms common class method and constructor overloading is not considered polymorphism, there are more uniform languages in which classes are regular objects. In Smalltalk, for instance, classes are regular objects. In turn, this means messages sent to classes can be overloaded, and it is also possible to create objects that behave like classes without their classes inheriting from the hierarchy of classes. These are effective techniques that can be used to take advantage of Smalltalk's powerful reflection capabilities. Similar arrangements are also possible in languages such as Self and Newspeak.