Кіріспе
Бағдарламалық қамтамасыз етуді оңтайландыру әдісі
Бағдарламалау тілі теориясында, жалқау бағалау немесе қажеттілік бойынша шақыру – бұл өрнектің мәні қажет болғанға дейін бағалануын кешіктіретін (қатаң емес бағалау) және қайталап бағалаудан аулақ болатын (ақпаратты бөлісу арқылы) бағалау стратегиясы. Жалқау бағалаудың артықшылықтарына мыналар жатады:
Басқару ағынын (құрылымдарын) примитивтердің орнына абстракциялар ретінде анықтау мүмкіндігі. Потенциалды шексіз дерек құрылымдарын анықтау мүмкіндігі. Бұл кейбір алгоритмдерді тікелейрақ іске асыруға мүмкіндік береді. Кейбір элементтері қателік болатын, жартылай анықталған дерек құрылымдарын анықтау мүмкіндігі. Бұл прототиптерді жылдам жасауға мүмкіндік береді. Жалқау бағалау көбінесе мемоизациямен біріктіріледі, Джон Бентлидің «Тиімді бағдарламаларды жазу» кітабында сипатталғандай. Функцияның мәні осы параметр немесе параметрлер жиынтығы үшін есептелгеннен кейін, нәтиже осы параметрлердің мәндерімен индекстелген іздеу кестесіне сақталады; келесі рет функция шақырылғанда, параметрлердің осы комбинациясы үшін нәтиже бар-жоғын анықтау үшін кесте қарастырылады. Егер бар болса, сақталған нәтиже қайтарылады. Егер жоқ болса, функция бағаланады және қайта пайдалану үшін іздеу кестесіне жаңа жазба қосылады. Жалқау бағалауды ерекше жағдайларды өңдеу және кіріс/шығыс сияқты императивті мүмкіндіктермен біріктіру қиын, өйткені операциялардың реті анықталмайды. Жалқау бағалаудың қарама-қарсысы – ынталы бағалау, кейде қатаң бағалау деп те аталады. Ынталы бағалау – көптеген бағдарламалау тілдерінде қолданылатын бағалау стратегиясы.
The ability to define control flow (structures) as abstractions instead of primitives. The ability to define potentially infinite data structures. This allows for more straightforward implementation of some algorithms. The ability to define partly defined data structures where some elements are errors. This allows for rapid prototyping. Lazy evaluation is often combined with memoization, as described in Jon Bentley's Writing Efficient Programs. After a function's value is computed for that parameter or set of parameters, the result is stored in a lookup table that is indexed by the values of those parameters; the next time the function is called, the table is consulted to determine whether the result for that combination of parameter values is already available. If so, the stored result is simply returned. If not, the function is evaluated, and another entry is added to the lookup table for reuse. Lazy evaluation is difficult to combine with imperative features such as exception handling and input/output, because the order of operations becomes indeterminate. The opposite of lazy evaluation is eager evaluation, sometimes known as strict evaluation. Eager evaluation is the evaluation strategy employed in most programming languages.
Тарих
Кристофер Уодсворт lambda calculus үшін жалқау бағалауды енгізді, ал Plessey System 250 жүйесі оны Lambda Calculus Meta Machine-нің маңызды бөлігі ретінде қолданды, бұл мүмкіндіктері шектеулі адрестік кеңістікте объектілерге қол жеткізуге кеткен уақытты қысқартты. Бағдарламалау тілдері үшін оны Питер Хендерсон мен Джеймс Х. Моррис, сондай-ақ Дэниел П. Фридман мен Дэвид С. Уайз дербес түрде енгізді.
Қолданбалар
Кейінгі бағалау әсіресе функционалдық бағдарламалау тілдерінде қолданылады. Кейінгі бағалауды пайдаланғанда, өрнек бірден айнымалыға тағайындалғанда емес, бағалаушы оның мәнін алуға мәжбүр болғанда бағаланады. Яғни, x = өрнек; (яғни өрнектің нәтижесін айнымалыға беру) сияқты оператор өрнекті бағалауды және нәтижені x-ке орналастыруды тікелей талап етеді, бірақ x-те не бар екені маңызды емес, оның мәні кейінірек өрнекте x-ке сілтеме жасау арқылы қажет болғанша, оның бағалауы кейінге шегелеуге болады. Бірақ, ақырында тәуелділіктердің тез өсіп келе жатқан ағашы сыртқы әлемге белгілі бір символ көрінуі үшін қысқартылады, басқа емес.
Өнер көрсету
Қажеттілік бойынша шақыру арқылы ламбда терминін азайту үшін қажетті бета-кішірейтулер саны, құндылық бойынша шақыру немесе атау бойынша шақыру арқылы қажетті санынан көп емес. Белгілі бір бағдарламаларда қадамдар саны әлдеқайда аз болуы мүмкін, мысалы, Шіркеу сандарын қолданатын ламбда терминдерінің нақты бір тобы құндылық бойынша шақырумен шексіз көп қадамдарды қажет етеді (яғни, ешқашан аяқталмайды), атау бойынша шақырумен экспоненциалдық санды, ал қажеттілік бойынша шақырумен тек полиномиалдық санды. Қажеттілік бойынша шақыру екі түрлі оңтайландыруды біріктіреді: ешқашан жұмысты қайталамау (құндылық бойынша шақыру сияқты) және қажетсіз жұмыс істемеу (атау бойынша шақыру сияқты). Тәуелсіз бағалау жадты үнемдеуге де мүмкіндік береді, себебі мәндер қажет болғанда ғана жасалады. Бірақ, тәжірибеде тәуелсіз бағалау, белсенді бағалаумен салыстырғанда маңызды өнімділік мәселелерін тудыруы мүмкін. Мысалы, қазіргі заманғы компьютерлік архитектураларда, есептеуді кейінге шегеріп, оны кейін орындау, дереу орындаудан баяу болады. Бұл мәселе қатаңдық талдауы арқылы шешілуі мүмкін.
Іске асыру
Кейбір бағдарламалау тілдері өрнектерді бағалауды әдетте кешіктіреді, ал басқалары бағалауды кешіктіру үшін функцияларды немесе арнайы синтаксисті ұсынады. Миранда мен Хаскеллде функция аргументтерін бағалау әдетте кешіктіріледі. Көптеген басқа тілдерде бағалауды арнайы синтаксис арқылы есептеуді тоқтату арқылы кешіктіруге болады (мысалы, Scheme-нің "delay" және "force" және OCaml-дің "lazy" және "Lazy.force") немесе, жалпы алғанда, өрнекті thunk-қа орау арқылы. Мұндай ашық түрде кешіктірілген бағалауды білдіретін объект "жалкоо болашақ" деп аталады. Raku тізімдерді жалкоо бағалауды қолданады, сондықтан шексіз тізімдерді айнымалыларға тағайындауға және оларды функцияларға аргумент ретінде пайдалануға болады, бірақ Хаскелл мен Мирандадан айырмашылығы, Raku арифметикалық операторлар мен функцияларды жалкоо бағалауды әдетте қолданбайды.