Continuation
Continuation, česky pokračování, se jako speciální pojem užívá při programování počítačů, kde se chápe jako abstraktní reprezentace okamžitého stavu vykonávání nějakého programu. Programovací jazyky, které s takovým pokračováním umějí pracovat, ho uchovávají jako datovou strukturu obsahující všechny údaje o výpočetním procesu v určitém momentu jeho provádění. Tyto údaje jsou v počítači vždy k dispozici, ovšem pouze skrytě, v tzv. běhovém prostředí (runtime environment). Zde zmiňovaná datová struktura pokračování je však přístupná v programovacím jazyce a dá se výhodně využít k programování některých speciálních řídicích mechanismů, například ke zpracování výjimek (exception handling), vytváření koprogramů (coroutines), generátorů, vícevláknových programů (thread computing), při programování webových aplikací, aj.
Slovo pokračování má v tomto případě jasný význam, protože příslušná datová struktura opravdu zachycuje pokračování programu od toho bodu zpracování, v němž byla vytvořena. Kdyby se program v tom momentu přerušil a měl pokračovat někdy později, může se řídit tímto pokračováním. Zjednodušeně si pokračování lze představit jako všechny příkazy, které mají následovat za místem, kde se zpracování programu právě nachází. To se ovšem nesmí chápat staticky, protože počítač některé operace provádí v jiném pořadí, než byly zapsány v programu, například v aritmetických výrazech vždy pořadí určují priority operátorů a závorky.
First-class continuations, česky asi pokračování první kategorie, představují datový typ, který splňuje požadavky na objekty první kategorie. Programovací jazyk, který taková pokračování obsahuje, dovoluje stav provádění v kterémkoli bodu programu uložit a později se k němu zase vrátit, a to i opakovaně.
Pokračování se poprvé objevilo v jazyce Scheme, v současnosti je možné ho využívat ve velké řadě programovacích jazyků.
Funkcionálně
Z funkcionálního pohledu je kontinuace monáda definovaná takto: Jednotka je a vázání je . V jazyce Idris vypadá implementace takto:
total Cont : Type -> Type -> Type
Cont r a = (a -> r) -> r
total unit : a -> Cont r a
unit x = \f => f x
total bind : Cont r a -> (a -> Cont r b) -> Cont r b
bind c f = \g => c $ \x => (f x) g
V jazyce Lean vypadá implementace takto:
def cont (r : Type) (a : Type) : Type := (a -> r) -> r
def contUnit (x : a) : cont r a := fun f => f x
def contBind (c : cont r a) (f : a -> cont r b) : cont r b := fun g => c (fun x => (f x) g)
Přímočará implementace v C++ vypadá takto:
template<typename A> using Cont = std::function<std::any(std::function<std::any(A)>)>;
template<typename A> Cont<A> contUnit(A x) {
return [x](std::function<std::any(A)> f) { return f(x); };
}
template<typename A, typename B> Cont<B> contBind(Cont<A> m, std::function<Cont<B>(A)> f) {
return [m,f](std::function<std::any(B)> g) {
return m([f,g](A x) { return f(x)(g); });
};
}
Reference
V tomto článku byl použit překlad textu z článku Continuation na anglické Wikipedii.