Кіріспе

Бағдарламалау тілінің мүмкіндігі Компьютерлік ғылымда, егер бағдарламалау тілі функцияларды бірінші сыныптық объектілер ретінде қарастырса, онда ол бірінші сыныптық функцияларды қолдайды делінеді. Бұл тіл функцияларды басқа функцияларға аргументтер ретінде жіберуге, оларды басқа функциялардың нәтижесі ретінде қайтаруға және оларды айнымалыларға тағайындауға немесе дерек құрылымдарында сақтауға мүмкіндік береді дегенді білдіреді. Кейбір бағдарламалау тілі теорияшылары анонимді функцияларды (функциялық литералдарды) қолдауды да талап етеді. Бірінші сыныптық функцияларды қолдайтын тілдерде функциялардың аттары ешқандай арнайы мәртебеге ие болмайды; олар функция типі бар қарапайым айнымалылар сияқты қарастырылады. Бұл термин 1960 жылдардың ортасында Кристофер Стречи «функциялар – бірінші сыныптық объектілер» контекстінде қолданған. Бірінші сыныптық функциялар функционалдық бағдарламалау стилі үшін қажетті жағдай, онда жоғары ретті функцияларды пайдалану стандартты тәжірибе болып табылады. Жоғары ретті функциялардың қарапайым мысалы – `map` функциясы, ол функцияны және тізімді аргументтер ретінде қабылдайды және тізімнің әрбір элементіне функцияны қолдану арқылы құрылған жаңа тізімді қайтарады. Тіл `map` функциясын қолдау үшін функцияны аргумент ретінде жіберуге мүмкіндік беруі керек. Функцияларды аргументтер ретінде жіберу немесе оларды нәтиже ретінде қайтаруда, әсіресе ішкі және анонимді функцияларда пайда болатын жергілікті емес айнымалылардың болуында, белгілі бір орындалу қиындықтары туындайды. Тарихи тұрғыдан алғанда, бұлар `funarg` проблемалары деп аталды, бұл атау «функция аргументі» деген сөздерден шыққан. Ертедегі императивті тілдер бұл проблемаларды нәтиже типі ретінде функцияларды қолдамау арқылы (мысалы, ALGOL 60, Pascal) немесе ішкі функцияларды және осылайша жергілікті емес айнымалыларды жою арқылы (мысалы, C) шешіп келді. Ертедегі функционалдық тіл Lisp динамикалық ауқымдау тәсілін қолданды, онда жергілікті емес айнымалылар функция анықталған жерінен емес, функция орындалатын жердегі осы айнымалының ең жақын анықтамасына сілтеме жасайды. Лексикалық ауқымдағы бірінші сыныптық функцияларға толық қолдау Scheme тілінде енгізілді және функцияларға сілтемелерді қарапайым функция көрсеткіштерінің орнына жабылу ретінде қарастыруды талап етеді.

Жоғары реттік функциялар: функциялар нәтиже ретінде қайтарылады

Функцияны қайтарғанда, біз шын мәнінде оның жабылуын қайтарамыз. C мысалында, жабылуға түсірілген кез келген жергілікті айнымалылар, жабылуды құрастыратын функциядан шыққаннан кейін қолданыстан шығады. Кейіннен жабылуды пайдалануға тырысу белгісіз мінез-құлыққа алып келеді, және ықтимал түрде стекті бұзуы мүмкін. Бұл "жоғары бағытталған аргумент" проблемасы деп аталады.

Функциялардың теңдігі

Теңдік үшін көптеген мәтіндік және мәндерді сынап көре алатындықтан, бағдарламалау тілі функцияларды теңдік үшін сынап көре ала ма деген сұрақ туындайды. Көбірек тексеру кезінде бұл сұрақ қиынырақ болып көрінеді және функция теңдігінің бірнеше түрін ажырату қажет:

Экстенциялық теңдік. Егер екі функция f және g барлық кірістер үшін бірдей нәтиже берсе (∀x. f(x) = g(x)), онда олар экстенциялық тұрғыдан тең деп есептеледі. Теңдіктің осы анықтамасы бойынша, мысалы, тұрақты сұрыптау алгоритмінің кез келген екі іске асырылуы, мысалы, енгізу сұрыптау және біріктіру сұрыптау тең деп саналады. Экстенциялық теңдікті анықтау жалпы жағдайда шешілмейді және тіпті шекті домені бар функциялар үшін де көбінесе қиынға соғады. Осы себепті ешбір бағдарламалау тілі функциялық теңдікті экстенциялық теңдік ретінде іске асырмайды.

Интенциялық теңдік. Интенциялық теңдік бойынша, егер екі функция f және g бірдей "ішкі құрылымға" ие болса, онда олар тең деп есептеледі. Мұндай теңдік интерпретацияланған тілдерде функциялардың бастапқы кодын (мысалы, Interpreted Lisp 1.5-тегідей) немесе компиляцияланған тілдердегі объектілік кодты салыстыру арқылы іске асырылуы мүмкін. Интенциялық теңдік экстенциялық теңдікті білдіреді (егер функциялар детерминистік болса және жасырын кірістері болмаса, мысалы, бағдарламалық тізімдегіш немесе өзгертілетін жаһандық айнымалы).

Анықтамалық теңдік. Экстенциялық және интенциялық теңдікті іске асырудың қиындығын ескере отырып, функцияларды теңдік үшін тексеруді қолдайтын көптеген тілдер анықтамалық теңдікті пайдаланады. Барлық функцияларға немесе жабылуларға бірегей идентификатор (әдетте функция денесінің мекенжайы немесе жабылу) тағайындалады және теңдік идентификатордың теңдігі негізінде анықталады. Екі бөлек анықталған, бірақ басқа жағынан бірдей функция анықтамалары тең емес деп есептеледі. Анықтамалық теңдік интенциялық және экстенциялық теңдікті білдіреді. Анықтамалық теңдік анықтамалық ашықтықты бұзады, сондықтан Хаскелл сияқты таза тілдерде қолдау көрсетілмейді.

Тип теориясы

Тип теориясында А типіндегі мәндерді қабылдайтын және В типіндегі мәндерді қайтаратын функциялардың типі A → B немесе BA түрінде жазылуы мүмкін. Кьюри-Ховард сәйкестігінде функция типтері логикалық импликациямен байланысты; лямбда абстракциясы гипотетикалық болжамдарды түсіруге, ал функцияны қолдану modus ponens логикалық ережесіне сәйкес келеді. Бағдарламалау функцияларының қалыпты жағдайынан өзге, тип теориясы ассоциативтік массивлер және осыған ұқсас дерек құрылымдарын модельдеу үшін бірінші класс функцияларын да пайдаланады. Бағдарламалаудың категориялық теориялық тұжырымдамаларында бірінші класс функцияларының болуы жабық категория болжамымен сәйкес келеді. Мысалы, қарапайым типтелген лямбда есептеуі Картезиан жабық категорияларының ішкі тіліне сәйкес келеді.