Co to jest wezwanie do ogona?
W programowaniu komputerowym wywołanie ogonowe to specyficzna sytuacja w kodzie źródłowym programu, w której funkcja, podprogram lub procedura zwraca oczekiwaną wartość przez wywołanie innej funkcji zamiast po prostu przekazania zmiennej przechowującej wartość zwracaną. Sama nazwa oznacza, że funkcja wywoływana w celu obliczenia zwracanej wartości znajduje się na końcu lub na końcu funkcji wywołującej ją w celu podania wartości zwracanej. Wywołanie tail jest interesujące dla niektórych programistów, ponieważ przy pewnych optymalizacjach lub zachowaniach kompilatora nie jest wykorzystywana dodatkowa przestrzeń stosu do przechowywania lokalizacji kodu głównej funkcji; zamiast tego funkcja tail służy do generowania raportów wartości zwracanych bezpośrednio z powrotem do punktu wywoławczego, w którym wywołano funkcję oryginalną. Zastosowanie wywołania ogonowego jest szczególnie przydatne w sytuacjach, w których stosowana jest rekurencja, ponieważ ilość miejsca na stosie używana do przechowywania adresów wywołujących w przypadkach, w których wywołania rekurencyjne bardzo głęboko się zagnieżdżają, może szybko zabraknąć i zatrzymać wykonywanie programu. Chociaż użycie wywołań tail może pomóc zwiększyć szybkość, zużycie pamięci i wydajność programu, może również prowadzić do sytuacji, w których kod źródłowy jest przekształcany w celu używania wywołań w sposób, który utrudnia debugowanie i śledzenie, szczególnie w przypadkach rekurencja.
Istnienie wywołania ogonowego wynika w dużej mierze ze sposobu działania stosu wywołań w większości programów komputerowych i architektur systemowych. Stos, który jest jak stos płyt, jest strukturą danych „pierwsze i ostatnie”. Gdy wywoływana jest funkcja, podprogram lub procedura, adres, z którego wykonane jest wywołanie, zwany ramką stosu, jest zapisywany na stosie. Oznacza to, że program wywołujący funkcję A, który następnie wywołuje funkcję B, będzie miał dwie ramki stosu, jedną dla funkcji B, a drugą dla funkcji A. Po zakończeniu wykonywania funkcji B ramka stosu zostanie wysunięta z góry stos i wykonanie wraca do funkcji A, której ramka odrywa się od stosu, gdy jest wykonywana, ostatecznie zwracając kontrolę programu do punktu, z którego pierwotnie wywołano pierwszą funkcję.
Gdy używane jest wywołanie ogonowe, instrukcja return w funkcji bezpośrednio wykorzystuje wartość zwracaną przez inną funkcję jako dane do wysłania do kodu wywołującego. W powyższym przykładzie, jeśli funkcja A wywołuje funkcję B bezpośrednio za pomocą instrukcji return, wówczas zostało utworzone wywołanie ogonowe. Wewnątrz stosu wywołań zamiast ramki stosu dla obu funkcji A i B, funkcja B otrzyma adres zwrotny z funkcji A, a ramka stosu funkcji A zostanie usunięta i usunięta, co oznacza, że funkcja B przekaże swoją wartość zwrotną bezpośrednio z powrotem do miejsca, które wywołało Funkcję A bez uprzedniego przekazania kontroli z powrotem do Funkcji A. Zwiększa to szybkość wywołań funkcji, a także pomaga ograniczyć ilość informacji na stosie.
Właściwości wywołania ogona mogą uczynić je bardzo atrakcyjną opcją dla funkcji rekurencyjnych. Funkcja rekurencyjna to taka, która wywołuje się wielokrotnie w celu obliczenia wartości, tak jak ma to miejsce podczas przeglądania struktury danych listy. Żadne dodatkowe ramki stosu nie są tworzone dla zagnieżdżonych wywołań funkcji, więc bardzo głębokie poziomy rekurencji można bezpiecznie wykonać bez bezpośredniego zagrożenia przepełnieniem stosu i możliwym zakończeniem programu.