Kaj je repni klic?

V računalniškem programiranju je repni klic specifična situacija znotraj izvorne kode programa, v kateri funkcija, podprogram ali procedura vrne pričakovano vrednost s klicem druge funkcije, namesto da preprosto posreduje spremenljivko, ki vsebuje vrnjeno vrednost. Samo ime označuje, da je funkcija, ki je poklicana za izračun vrednosti, ki jo je treba vrniti, na koncu ali repu funkcije, ki jo kliče, da zagotovi vrnjeno vrednost. Repni klic je zanimiv za nekatere programerje, ker se z določenimi optimizacijami ali vedenjem prevajalnika ne uporablja dodaten prostor sklada za shranjevanje kodnih lokacij glavne funkcije; funkcija rep se namesto tega uporablja za generiranje poročil o vrnjeni vrednosti neposredno nazaj do klicne točke, kjer je bila priklicana izvirna funkcija. Uporaba repnega klica je še posebej uporabna v situacijah, v katerih se uporablja rekurzija, saj bi količina prostora sklada, ki se uporablja za shranjevanje naslovov klicatelja, v primerih, ko se rekurzivni klici gnezdijo zelo globoko, lahko hitro zmanjka in ustavi izvajanje programa. Čeprav lahko uporaba repnih klicev pomaga povečati hitrost, porabo pomnilnika in učinkovitost v programu, lahko privede tudi do situacij, v katerih je izvorna koda prestrukturirana za uporabo klicev na način, ki otežuje odpravljanje napak in sledenje, zlasti v primerih rekurzija.

Obstoj repnega klica je v veliki meri posledica tega, kako deluje sklad klicev v večini računalniških programov in sistemskih arhitektur. Sklad, ki je kot sveženj plošč, je podatkovna struktura prvi v, zadnji ven. Ko se pokliče funkcija, podprogram ali procedura, se naslov, s katerega je opravljen klic, imenovan okvir sklada, shrani v sklad. To pomeni, da bo program, ki pokliče funkcijo A, ki nato pokliče funkcijo B, imel dva okvirja sklada, enega za funkcijo B in drugega pod njim za funkcijo A. Ko se funkcija B konča z izvajanjem, se njen okvir sklada prikaže z vrha sklad in izvedba se vrne na funkcijo A, katere okvir se po končanem delu vrne iz sklada in končno vrne nadzor programa na točko, od koder je bila prvotno poklicana prva funkcija.

Ko se uporabi repni klic, stavek return v funkciji neposredno uporabi vrnjeno vrednost druge funkcije kot podatke, ki se pošljejo klicni kodi. V zgornjem primeru, če funkcija A pokliče funkcijo B neposredno s stavkom return, je bil oblikovan repni klic. Znotraj sklada klicev, namesto da bi imela okvir sklada za obe funkciji A in B, bo funkcija B prejela povratni naslov iz funkcije A, okvir sklada funkcije A pa bo prikazan in odstranjen, kar pomeni, da bo funkcija B svojo vrnjeno vrednost posredovala neposredno nazaj. na lokacijo, ki je poklicala funkcijo A, ne da bi bilo treba najprej prenesti nadzor nazaj funkciji A. To poveča hitrost klicev funkcij in pomaga zmanjšati količino informacij v skladu.

Lastnosti repnega klica jih lahko naredijo zelo privlačno možnost za rekurzivne funkcije. Rekurzivna funkcija je tista, ki se večkrat kliče za izračun vrednosti, kot je to lahko v primeru prečkanja strukture podatkov seznama. Za ugnezdene klice funkcij niso ustvarjeni nobeni dodatni okvirji sklada, zato je mogoče varno izvesti zelo globoke ravni rekurzije brez neposredne grožnje prelivanja sklada in možnega zaključka programa.