Back in the day, I thought I understood call/cc
. These days I'm seeing a lot more references to "delimited" continuation operators, which seem to come in pairs like shift
/reset
, prompt
/control
, and sometimes more exotic ones. But I haven't seen a clear explanation anywhere of the basics, so
An operator T is said to be closed if its graph Γ(T) is a closed set. (Here, the graph Γ(T) is a linear subspace of the direct sum X ⊕ Y, defined as the set of all pairs (x, Tx), where x runs over the domain of T .)
A symmetric operator A is always closable; that is, the closure of the graph of A is the graph of an operator. A symmetric operator A is said to be essentially self-adjoint if the closure of A is self-adjoint. Equivalently, A is essentially self-adjoint if it has a unique self-adjoint extension.
Functional Analysis The operator T*: H2 → H1 is a bounded linear operator called the adjoint of T. If T is a bounded linear operator, then ∥T∥ = ∥T*∥ and T** = T. and hence T* is the integral operator generated by the kernel k* (·, ·) defined by k*(t, s) = k(s,t).
Thus, the identity operator on H is not compact. Here are some examples of compact opera- tors: Finite rank operators. A bounded linear transformation is said to be of finite rank if its range is finite dimensional.
The continuing operations should the primary income source for businesses which means that the bulk of the revenue that a business earns should be from its daily, regular operations. The continuing operations are reported separately from discontinued operations in the financial statements.
A continuation implements (reifies) the program control state, i.e. the continuation is a data structure that represents the computational process at a given point in the process's execution; the created data structure can be accessed by the programming language, instead of being hidden in the runtime environment.
Delimited continuation operators address this by providing two separate control mechanisms: a prompt that delimits a continuation operation and a reification operator such as shift or control. Continuations captured using delimited operators thus only represent a slice of the program context.
Four Phases of Continuity of Operations Activation Phase I - Readiness and Preparedness Phase II - Activation and Relocation: plans, procedures, and schedules to transfer activities, personnel, records, and equipment to alternate facilities are activated Phase III - Continuity Operations: full execution of essential operations at
I have read a few articles and I can explain the idea. So I do not know how to implement it and how to use it in practical way, but I understood the main idea.
Suppose you have a call like
(f (h (g x)) 2)
^ << scheme undelimited cont. captures from here
and g
captures the continuation.
In scheme, if you call call/cc
within g
, it will copy all the execution stack starting from the top-level (starting from the point where f
was invoked) -- in case you have many expressions at the top level each one will have its own stacklet and invoking the saved continuation will stop at the top level (so, in the above expression, it will stop after f and at that point it has the value of f
).
If you want the continuation to be captured from inside g
up to the exit point of h
, and each invocation of the continuation to return a value to f it is enough to capture the stack starting from the point of invocation of h
, not the full stacklet of the invocation of f
, so you want to tell the system that calling a call/cc-like function not to duplicate the rest of computation from the top level, but from a given point, and return each time a value at that point:
(f (h (g x)) 2)
^ << delimited cont. captures from here
In this case, you instrument the system, something like:
(f (shift (h (g x)) 2))
and call the reset
inside g
, in the place where you would need to capture the continuation.
Delimited continuations can be simulated by undelimited continuations, but I think it is more practical to be able to use delimited, in some cases. So you cannot do it in scheme in a practical way of duplicating the stack only in the region of interest, it obliges you to copy a full stacklet (I say "stacklet" instead of stack, as the real stack is bigger, and the outside chained stacklets represent the continuation of the initialization code that is executed when you quit your code).
These are a few ideas that I glaned from the papers I have read. I am also interested to hear a more detailed answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With