diff --git a/macros.tex b/macros.tex index 2c66ac2..bb43187 100644 --- a/macros.tex +++ b/macros.tex @@ -427,8 +427,8 @@ \newcommand{\Set}{\keyw{set}} \newcommand{\newPrompt}{\keyw{newPrompt}} \newcommand{\Callcc}{\keyw{callcc}} -\newcommand{\Callcomc}{\ensuremath{\keyw{callcc}^\ast}} -\newcommand{\textCallcomc}{callcc$^\ast$} +\newcommand{\Callcomc}{\ensuremath{\keyw{callcomp}}} +\newcommand{\textCallcomc}{callcomp} \newcommand{\Throw}{\keyw{throw}} \newcommand{\Continue}{\keyw{resume}} \newcommand{\Catch}{\keyw{catch}} diff --git a/thesis.bib b/thesis.bib index 09d08b8..24b1873 100644 --- a/thesis.bib +++ b/thesis.bib @@ -51,24 +51,27 @@ year = {2017} } -# Efficient one-shot continuations +# Segmented stacks +@inproceedings{HiebDB90, + author = {Robert Hieb and + R. Kent Dybvig and + Carl Bruggeman}, + title = {Representing Control in the Presence of First-Class Continuations}, + booktitle = {{PLDI}}, + pages = {66--77}, + publisher = {{ACM}}, + year = {1990} +} + @inproceedings{BruggemanWD96, author = {Carl Bruggeman and Oscar Waddell and R. Kent Dybvig}, - editor = {Charles N. Fischer}, title = {Representing Control in the Presence of One-Shot Continuations}, - booktitle = {Proceedings of the {ACM} SIGPLAN'96 Conference on Programming Language - Design and Implementation (PLDI), Philadephia, Pennsylvania, May 21-24, - 1996}, + booktitle = {{PLDI}}, pages = {99--107}, publisher = {{ACM}}, - year = {1996}, - OPTurl = {http://doi.acm.org/10.1145/231379.231395}, - OPTdoi = {10.1145/231379.231395}, - timestamp = {Mon, 21 May 2012 16:19:53 +0200}, - biburl = {http://dblp.uni-trier.de/rec/bib/conf/pldi/BruggemanWD96}, - bibsource = {dblp computer science bibliography, http://dblp.org} + year = {1996} } # Programming with continuations @@ -158,21 +161,13 @@ } # Other algebraic effects and handlers -@InProceedings{Lindley14, +@inproceedings{Lindley14, author = {Sam Lindley}, - editor = {Jos{\'{e}} Pedro Magalh{\~{a}}es and - Tiark Rompf}, title = {Algebraic effects and effect handlers for idioms and arrows}, - booktitle = {Proceedings of the 10th {ACM} {SIGPLAN} workshop on Generic programming, - {WGP} 2014, Gothenburg, Sweden, August 31, 2014}, + booktitle = {WGP@ICFP}, pages = {47--58}, publisher = {{ACM}}, - year = {2014}, - OPTurl = {http://doi.acm.org/10.1145/2633628.2633636}, - OPTdoi = {10.1145/2633628.2633636}, - timestamp = {Thu, 25 Jun 2015 13:50:37 +0200}, - biburl = {http://dblp.uni-trier.de/rec/bib/conf/icfp/Lindley14}, - bibsource = {dblp computer science bibliography, http://dblp.org} + year = {2014} } @article{Pretnar15, @@ -1463,6 +1458,20 @@ month = aug } +# callcomp +@inproceedings{FlattYFF07, + author = {Matthew Flatt and + Gang Yu and + Robert Bruce Findler and + Matthias Felleisen}, + title = {Adding delimited and composable control to a production programming + environment}, + booktitle = {{ICFP}}, + pages = {165--176}, + publisher = {{ACM}}, + year = {2007} +} + # Constraining call/cc @inproceedings{FriedmanH85, author = {Daniel P. Friedman and @@ -1819,6 +1828,17 @@ address = {Scotland, {UK}} } +@article{DybvigH89, + author = {R. Kent Dybvig and + Robert Hieb}, + title = {Engines From Continuations}, + journal = {Comput. Lang.}, + volume = {14}, + number = {2}, + pages = {109--123}, + year = {1989} +} + @inproceedings{HiebD90, author = {Robert Hieb and R. Kent Dybvig}, @@ -2267,3 +2287,115 @@ year = {1994} } +# Differentiable programming with delimited continuations +@article{WangZDWER19, + author = {Fei Wang and + Daniel Zheng and + James M. Decker and + Xilun Wu and + Gr{\'{e}}gory M. Essertel and + Tiark Rompf}, + title = {Demystifying differentiable programming: shift/reset the penultimate + backpropagator}, + journal = {Proc. {ACM} Program. Lang.}, + volume = {3}, + number = {{ICFP}}, + pages = {96:1--96:31}, + year = {2019} +} + +# Probabilistic programming with continuations +@inproceedings{KiselyovS09, + author = {Oleg Kiselyov and + Chung{-}chieh Shan}, + title = {Embedded Probabilistic Programming}, + booktitle = {{DSL}}, + series = {Lecture Notes in Computer Science}, + volume = {5658}, + pages = {360--384}, + publisher = {Springer}, + year = {2009} +} + + +@InProceedings{GorinovaMH20, + title = {Automatic Reparameterisation of Probabilistic Programs}, + author = {Maria I. Gorinova and Dave Moore and Matthew D. Hoffman}, + booktitle = {{ICML}}, + pages = {3648--3657}, + year = {2020}, + OPTeditor = {Hal Daumé III and Aarti Singh}, + volume = {119}, + OPTseries = {Proceedings of Machine Learning Research}, + OPTaddress = {Virtual}, + OPTmonth = {13--18 Jul}, + publisher = {PMLR}, + OPTpdf = {http://proceedings.mlr.press/v119/gorinova20a/gorinova20a.pdf}, + OPTurl = {http://proceedings.mlr.press/v119/gorinova20a.html}, +} + +# Continuations in operating systems +@inproceedings{KiselyovS07a, + author = {Oleg Kiselyov and + Chung{-}chieh Shan}, + title = {Delimited Continuations in Operating Systems}, + booktitle = {{CONTEXT}}, + series = {Lecture Notes in Computer Science}, + volume = {4635}, + pages = {291--302}, + publisher = {Springer}, + year = {2007} +} + +# Web programming and continuations +@article{Queinnec04, + author = {Christian Queinnec}, + title = {Continuations and Web Servers}, + journal = {High. Order Symb. Comput.}, + volume = {17}, + number = {4}, + pages = {277--295}, + year = {2004} +} + +# Erlang +@book{ArmstrongVW93, + author = {Joe Armstrong and + Robert Virding and + Mike Williams}, + title = {Concurrent programming in {ERLANG}}, + publisher = {Prentice Hall}, + year = {1993} +} + +# Asynchrony with effect handlers +@inproceedings{Leijen17a, + author = {Daan Leijen}, + title = {Structured asynchrony with algebraic effects}, + booktitle = {TyDe@ICFP}, + pages = {16--29}, + publisher = {{ACM}}, + year = {2017} +} + +# Surveys of implementation strategies for continuations +@inproceedings{ClingerHO88, + author = {William D. Clinger and + Anne Hartheimer and + Eric Ost}, + title = {Implementation Strategies for Continuations}, + booktitle = {{LISP} and Functional Programming}, + pages = {124--131}, + publisher = {{ACM}}, + year = {1988} +} + +@inproceedings{FarvardinR20, + author = {Kavon Farvardin and + John H. Reppy}, + title = {From folklore to fact: comparing implementations of stacks and continuations}, + booktitle = {{PLDI}}, + pages = {75--90}, + publisher = {{ACM}}, + year = {2020} +} \ No newline at end of file diff --git a/thesis.tex b/thesis.tex index 2d1ca14..83657c2 100644 --- a/thesis.tex +++ b/thesis.tex @@ -946,20 +946,21 @@ macro-expressible. \end{equations} \paragraph{Call-with-composable-continuation} A variation of callcc is -call-with-composable-continuation, or as I call it \textCallcomc{}. +call-with-composable-continuation, abbreviated \textCallcomc{}. % As the name suggests the captured continuation is composable rather -than abortive. -% -According to the history log of Racket it appeared in November 2006 -(Racket was then known as MzScheme, version 360)~\cite{Flatt20}. The -history log classifies it as a delimited control operator. Truth to be -told nowadays in Racket virtually all control operators are delimited, -even callcc, because they are parameterised by an optional prompt -tag. If the programmer does not supply a prompt tag at invocation time -then the optional parameter assume the actual value of the top-level -prompt, effectively making the extent of the captured continuation -undelimited. +than abortive. It was introduced by \citet{FlattYFF07} in 2007, and +and implemented in November 2006 according to the history log of +Racket (Racket was then known as MzScheme, version +360)~\cite{Flatt20}. The history log classifies it as a delimited +control operator. +% +Truth to be told nowadays in Racket virtually all control operators +are delimited, even callcc, because they are parameterised by an +optional prompt tag. If the programmer does not supply a prompt tag at +invocation time then the optional parameter assume the actual value of +the top-level prompt, effectively making the extent of the captured +continuation undelimited. % In other words its default mode of operation is undelimited, hence the justification for categorising it as such. @@ -971,30 +972,31 @@ Like $\Callcc$ this operator is a value. V,W \in \ValCat ::= \cdots \mid \Callcomc \] % -Unlike $\Callcc$, the continuation returns, which the typing rule for -$\Callcomc$ reflects. -% -\begin{mathpar} - \inferrule* - {~} - {\typ{\Gamma}{\Callcomc : (\Cont\,\Record{A;A} \to A) \to A}} +% Unlike $\Callcc$, the continuation returns, which the typing rule for +% $\Callcomc$ reflects. +% % +% \begin{mathpar} +% \inferrule* +% {~} +% {\typ{\Gamma}{\Callcomc : (\Cont\,\Record{A;A} \to A) \to A}} - \inferrule* - {\typ{\Gamma}{V : A} \\ \typ{\Gamma}{W : \Cont\,\Record{A;B}}} - {\typ{\Gamma}{\Continue~W~V : B}} -\end{mathpar} -% -Both the domain and codomain of the continuation are the same as the -body type of function argument. The capture rule for $\Callcomc$ is -identical to the rule for $\Callcomc$, but the resume rule is -different. +% \inferrule* +% {\typ{\Gamma}{V : A} \\ \typ{\Gamma}{W : \Cont\,\Record{A;B}}} +% {\typ{\Gamma}{\Continue~W~V : B}} +% \end{mathpar} +% % +% Both the domain and codomain of the continuation are the same as the +% body type of function argument. +Unlike $\Callcc$, captured continuations behave as functions. % \begin{reductions} \slab{Capture} & \EC[\Callcomc~V] &\reducesto& \EC[V~\qq{\cont_{\EC}}]\\ - % \slab{Resume} & \EC[\Continue~\cont_{\EC'}~V] &\reducesto& \EC[\EC'[V]] \slab{Resume} & \Continue~\cont_{\EC}~V &\reducesto& \EC[V] \end{reductions} % +The capture rule for $\Callcomc$ is identical to the rule for +$\Callcomc$, but the resume rule is different. +% The effect of continuation invocation can be understood locally as it does not erase the global evaluation context, but rather composes with it. @@ -2132,16 +2134,31 @@ computation. If the reader ever find themselves in a quiz show asked to single out a canonical example of continuation use, then implementation of -cooperative concurrency would be a qualified guess. Various forms of -coroutines as continuations occur so frequently in the literature and -in the wild that they have become routine. +concurrency would be a qualified guess. Cooperative concurrency in +terms of various forms of coroutines as continuations occur so +frequently in the literature and in the wild that they have become +routine. % \citet{HaynesFW86} published one of the first implementations of -coroutines using first-class control. \citet{HiebD90} demonstrated how -to implement engines. An engine is a kind of scheduler for -computations running on a time budget~\cite{HaynesF84}. +coroutines using first-class control. +% +Preemptive concurrency in the form of engines were implemented by +\citet{DybvigH89}. An engine is a control abstraction that runs +computations with an allotted time budget~\cite{HaynesF84}. They used +continuations to represent strands of computation and timer interrupts +to suspend continuations. +% +\citet{KiselyovS07a} used delimited continuations to explain various +phenomena of operating systems, including multi-tasking. +% +On the web, \citet{Queinnec04} used continuations to model the +client-server interactions. This model was adapted by +\citet{CooperLWY06} in Links with support for an Erlang-style +concurrency model~\cite{ArmstrongVW93}. % -Various other forms of schedulers were developed by \citet{GanzFW99}. +\citet{Leijen17a} and \citet{DolanEHMSW17} gave two different ways of +implementing the asynchronous programming operator async/await as a +user-definable library. Continuations have also been used in meta-programming to speed up partial evaluation and @@ -2149,35 +2166,73 @@ multi-staging~\cite{LawallD94,KameyamaKS11,OishiK17,Yallop17}. Let insertion is a canonical example of use of continuations in multi-staging~\cite{Yallop17}. -The aforementioned applications of continuations is by no means -exhaustive, however, the diverse application spectrum underlines the +Probabilistic programming is yet another application domain of +continuations. \citet{KiselyovS09} used delimited continuations to +speed up probabilistic programs. \citet{GorinovaMH20} used +continuations to achieve modularise probabilistic programs and to +provide a simple and efficient mechanism for reparameterisation of +inference algorithms. +% +In the subject of differentiable programming \citet{WangZDWER19} +explained reverse-mode automatic differentiation operators in terms of +delimited continuations. + +The aforementioned applications of continuations are by no means +exhaustive, though, the diverse application spectrum underlines the versatility of continuations. \section{Constraining continuations} -\citet{FriedmanH85} argued in favour of constraining the power of -continuations~\cite{HaynesF87}. Although, they were concerned with -callcc and undelimited continuations many of their arguments are -applicable to other control operators and delimited continuations. - -For example callec is a variation of callcc where the continuation -only can be invoked during the dynamic extent of -callec~\cite{Flatt20}. - -Dynamic-wind\dots - -To avoid resource leakage the implementation of effect handlers in -Multicore OCaml provides both a \emph{continue} primitive for -continuing a given continuation and a \emph{discontinue} primitive for -aborting a given continuation~\cite{DolanWSYM15,DolanEHMSW17}. The -latter throws an exception at the operation invocation site to clean -up resources. -% -A similar approached is used by \citet{Fowler19}, who uses a +\citet{FriedmanH85} advocated for constraining the power of +(undelimited) continuations~\cite{HaynesF87}. +% +Even though, they were concerned with callcc and undelimited +continuations some of their arguments are applicable to other control +operators and delimited continuations. +% +For example, they argued in favour of restricting continuations to be +one-shot, which means continuations may only be invoked once. Firstly, +because one-shot continuations admit particularly efficient +implementations. Secondly, many applications involve only single use +of continuations. Thirdly, one-shot continuations interact more +robustly with resources, such as file handles, than general multi-shot +continuations, because multiple use of a continuation may accidentally +interact with a resource after it has been released. + +One-shot continuations by themselves are no saving grace for avoiding +resource leakage as they may be dropped or used to perform premature +exits from a block with resources. For example, Racket provides the +programmer with a facility known as \emph{dynamic-wind} to protect a +context with resources such that non-local exits properly release +whatever resources the context has acquired~\cite{Flatt20}. +% +An alternative approach is taken by Multicore OCaml, whose +implementation of effect handlers with one-shot continuations provides +both a \emph{continue} primitive for continuing a given continuation +and a \emph{discontinue} primitive for aborting a given +continuation~\cite{DolanWSYM15,DolanEHMSW17}. The latter throws an +exception at the operation invocation site to which can be caught by +local exception handlers to release resources properly. +% +This approach is also used by \citet{Fowler19}, who uses a substructural type system to statically enforce the use of continuations, either by means of a continue or a discontinue. +% For example callec is a variation of callcc where continuation +% invocation is only defined during the dynamic extent of +% callec~\cite{Flatt20}. + \section{Implementing continuations} + +There are numerous strategies for implementing continuations. There is +no best implementation strategy. Each strategy has different +trade-offs, and as such, there is no ``best'' strategy. In this +section, I will briefly outline the gist of some implementation +strategies and their trade-offs. For an in depth analysis the +interested reader may consult the respective work of +\citet{ClingerHO88} and \citet{FarvardinR20}, which contain thorough +studies of implementation strategies for first-class continuations. + Table~\ref{tbl:ctrl-operators-impls} lists some programming languages with support for first-class control operators and their implementation strategies. @@ -2208,7 +2263,7 @@ implementation strategies. \hline OchaCaml & shift/reset & Virtual machine\\ \hline - Racket & callcc, callcc$^{\ast}$, cupto, fcontrol, control/prompt, shift/reset, splitter, spawn & Continuation marks\\ + Racket & callcc, \textCallcomc{}, cupto, fcontrol, control/prompt, shift/reset, splitter, spawn & Segmented stacks\\ \hline Rhino JavaScript & JI & Interpreter \\ \hline @@ -2216,21 +2271,29 @@ implementation strategies. \hline SML/NJ & callcc & CPS\\ \hline - Wasm/k & control/prompt & ?? \\ + Wasm/k & control/prompt & Virtual machine \\ \hline \end{tabular} - \caption{Some languages and their implementation strategies for first-class control.}\label{tbl:ctrl-operators-impls} + \caption{Some languages and their implementation strategies for continuations.}\label{tbl:ctrl-operators-impls} \end{table} +% +At runtime the call stack represents the current continuation. +% +Thus continuation capture can be implemented by copying the current +stack, and continuation invocation as reinstatement of the stack. This +implementation strategy works well if continuations are captured +infrequently. A slight this implementation strategy is to defer +copying the stack until the continuation is invoked -\paragraph{Continuation marks} +% \paragraph{Continuation marks} -\paragraph{Continuation passing style} +% \paragraph{Continuation passing style} -\paragraph{Abstract and virtual machines} +% \paragraph{Abstract and virtual machines} -\paragraph{Segmented stacks} +% \paragraph{Segmented stacks} -\paragraph{Stack copying} +% \paragraph{Stack copying} \part{Design}