SlideShare a Scribd company logo
Continuations &
Web Applications
        -Balaji Damodaran, ThoughtWorks
Continuations
Continuations
Contiuation

●
    Continuation is Time Travel


●
    Continuation is saving the control flow of
    a program's execution
Continuations
class ControlCentre

      def exploreTerrain
          marsPlateau = Plateau.new(5, 5)
          alpha = Rover.new("alpha")
          source = Position.new(1, 2, "N")
          alpha.land(marsPlateau, source)
          destination = alpha.explore("LMLMLMLMM")
          print destination
      end
end
class ControlCentre

      def exploreTerrain
          marsPlateau = Plateau.new(5, 5)
          alpha = Rover.new("alpha")
          source = Position.new(1, 2, "N")
          alpha.land(marsPlateau, source)
          destination = alpha.explore("LMLMLMLMM")
          print destination
      end
end
class ControlCentre

      def exploreTerrain
          marsPlateau = Plateau.new(5, 5)
          alpha = Rover.new("alpha")
          source = Position.new(1, 2, "N")
          alpha.land(marsPlateau, source)
          destination = alpha.explore("LMLMLMLMM")
          print destination
      end
end




  Control Scope
  Execution Context
  marsPlateau
  alpha
class ControlCentre

      def exploreTerrain
          marsPlateau = Plateau.new(5, 5)
          alpha = Rover.new("alpha")
          source = Position.new(1, 2, "N")
          alpha.land(marsPlateau, source)
          destination = alpha.explore("LMLMLMLMM")
          print destination
      end
end




  Control Scope                          Current Continuation
  Execution Context        source = Position.new(1, 2, "N")
  marsPlateau              alpha.land(marsPlateau, source)
                           destination = alpha.explore("LMLMLMLMM")
  alpha                    print destination
class ControlCentre

      def exploreTerrain
          marsPlateau = Plateau.new(5, 5)
          alpha = Rover.new("alpha")
          callcc{|@cc|}
          source = Position.new(1, 2, "N")
          alpha.land(marsPlateau, source)
          destination = alpha.explore("LMLMLMLMM")
          print destination
          return @cc
      end
end
class ControlCentre

      def exploreTerrain
          marsPlateau = Plateau.new(5, 5)
          alpha = Rover.new("alpha")
          callcc{|@cc|}
          source = Position.new(1, 2, "N")
          alpha.land(marsPlateau, source)
          destination = alpha.explore("LMLMLMLMM")
          print destination
          return @cc
      end
end

> c = exploreTerrain
“1 3 N”
=> #<Continuation:0xb744a8c4>

> c.call
“1 3 N”
=> #<Continuation:0xb744a8c4>
Normal      Control Flow with
                                    Continuation invoked
Control Flow     Continuations




                           continuation           continuation
Isn't that just a glorified GOTO?
class ControlCentre

      def exploreTerrain
          marsPlateau = Plateau.new(5, 5)
          alpha = Rover.new("alpha")
          c = nil
          source = callcc do |cc|
                     c = cc
                     Position.new(1, 2, "N")
                   end
          alpha.land(marsPlateau, source)
          destination = alpha.explore("LMLMLMLMM")
          print destination
          return c
      end
end

> c = exploreTerrain
“1 3 N”
=> #<Continuation:0xb7466240>


> c.call(Position.new(2, 3, “E”))
“2 4 E”
=> #<Continuation:0xb7466240>
Normal      Control Flow with Continuation invoked
Control Flow     Continuations with different parameters




                                                continuation
                           continuation         With different
                                                parameters
def continuation
    puts "i do some computation " +
              "& save the state of execution."
    m = callcc { |cc| return cc }
    puts "then i restart the execution from " +
              "the saved state & pass custom " +
              "values such as "#{m[0]}" and "#{m[1]}""
end



> c = continuation

i do some computation & save the state of execution.


> c.call("so..", "then..")

then i restart the execution from the saved state & pass custom
values such as "so.." and "then.."
Normal        Control Flow with Continuation reinvoked
Control Flow   Continuations paused   with parameters




                                             continuation
                                             With parameters

                             continuation
Continuations
Continuation?
●
    A continuation reifies the control flow of a
    program as just another data value



●
    Reify – To consider an abstract concept to be
    real. To make control flow as first class
    functions/objects.
Continuation
●
    Continuation is an object that takes a
    snapshot copy of the running process.


●
    The current process is copied and saved.


●
    Current process – execution context and
    all local variables
Normal      Control Flow marked with
Control Flow         continuation

                                                         Memory



                                      Local variables
                                                           #




                                          continuation
A new process that
        invokes a continuation

                                               Memory



                                                 #




          The current execution is abandoned




Note: Global data does not
get stored in a continuation
Continuations
●
    A Continuation stores the execution context, its
    references and pointers.


●
    However, it does not store the heap data or
    data that is outside the scope of local
    references and pointers.


●
    So any change made to them will stay changed
    even after invoking the continuation.
Continuations Sandwich Analogy
Continuations
call-with-current-continuation
●
    call-with-current-continuation, in short
    called as “call/cc” is a procedure first
    introduced in Scheme.


●
    Now exists in several other programming
    languages such as Ruby, known as
    “callcc”
call-with-current-continuation
●   call/cc takes in only one argument, which is a
    function f.
●   It takes the current continuation as an object and
    applies f to it.

      –   continuation = new Continuation()
      –   function(continuation)


●
    When, callcc gets invoked, the program flow will
    continue from the point it was captured and the
    argument to the continuation will become its
    return value
call-with-current-continuation
Method definition:
function: call/cc(function: f) {
   c = new: Continuation
   f(c)
}

JavaScript (Rhino):
function callcc(f) {
   var c = new Continuation();
   return f(c);
}

Ruby:
callcc {|cont|} cont => Continuation object
cont.call(*args)
call-with-current-continuation
function callcc(fun) {
  var continuation = new Continuation()
  return fun(continuation)
}

var cc
print(3 * (8 + callcc(function(c) {
                 cc = c
                 return 4
               })))

js> 36
call-with-current-continuation
function callcc(fun) {
  var continuation = new Continuation()
  return fun(continuation)
}

var cc
print(3 * (8 + callcc(function(c) {
                 cc = c
                 return 4
               })))

js> 36

js> cc(6)
42
def continue_example
  i = 0
  print "Before callcc #{i}n"
  callcc do |cc|
    for i in 1..10 do
      print "In callcc #{i}n"
      return cc if i > 5
    end
  end
  print "After callcc #{i}n"
end
def continue_example
  i = 0
  print "Before callcc #{i}n"
  callcc do |cc|
    for i in 1..10 do
      print "In callcc #{i}n"
      return cc if i > 5
    end
  end
  print "After callcc #{i}n"
end




puts "begin control flow."
c = continue_example()
puts "after invoking the method"
if c
  c.call
  puts "this will not get executed"
end
def continue_example
  i = 0
  print "Before callcc #{i}n"
  callcc do |cc|                      begin control flow.
    for i in 1..10 do                 Before callcc 0
      print "In callcc #{i}n"        In callcc 1
      return cc if i > 5              In callcc 2
    end                               In callcc 3
  end                                 In callcc 4
  print "After callcc #{i}n"         In callcc 5
end                                   In callcc 6
                                      after invoking the method
                                      After callcc 6
                                      after invoking the method

puts "begin control flow."
c = continue_example()
puts "after invoking the method"
if c
  c.call
  puts "this will not get executed"
end
call-with-current-continuation
●
    Continuations are sort of goto labels. But
    more powerful.
    ●
        We can store the continuation in a variable or
        object field, unlike a goto label.
    ●
        Goto labels are restricted within a functional
        scope, continuations are not limited by that.
The following code is strictly for session purposes
only. Implementing this in usable code may cause
               harm to life and limb.
Continuation as a GOTO
def goto_in_ruby_1
  i = 0
  callcc {|@label|}
  i = i + 1
  print "#{i}t"
  @label.call if i < 10
end
Continuation as a GOTO
def goto_in_ruby_1
  i = 0
  callcc {|@label|}
  i = i + 1
  print "#{i}t"
  @label.call if i < 10
end




output:
1 2 3     4   5   6   7   8   9   10
Continuation as a GOTO
def goto_in_ruby_1                     def goto_in_ruby_2
  i = 0                                  i = 0
  callcc {|@label|}                      callcc do |label|
  i = i + 1                                  label.call
  print "#{i}t"                             i = 99
  @label.call if i < 10                   end
end                                       print i
                                       end




output:
1 2 3     4   5   6   7   8   9   10
Continuation as a GOTO
def goto_in_ruby_1                     def goto_in_ruby_2
  i = 0                                  i = 0
  callcc {|@label|}                      callcc do |label|
  i = i + 1                                  label.call
  print "#{i}t"                             i = 99
  @label.call if i < 10                   end
end                                       print i
                                       end




output:                                output:
1 2 3     4   5   6   7   8   9   10   0
Summary
●
    Continuation is a procedure that represents
    the remaining steps in a computation.


●
    It is a "snapshot" of the current control
    context or control state of the program


●
    The continuation can be later invoked
    (repeatedly) with custom arguments
Continuations
●
    Languages that support first class
    continuations
    ●
        Scheme (call/cc)
    ●
        Ruby (callcc)
    ●
        Smalltalk (Continuation currentDo:)
    ●
        Rhino [JavaScript] (new Continuation())
    ●
        Scala (Responder & shift, reset)
    ●
        Perl (Coro)
    ●
        Haskell (Control.Monad.Cont)
Continuations Types


●
    First class continuations
●
    Continuation Passing Style (CPS)
●
    Delimited Continuations
Continuations
Continuation Passing Style
●
    A function, instead of returning an explict
    value, it takes an explict 'continuation'
    argument – another function which is
    meant to receive the result of the
    computation
Continuation Passing Style



function (arg) {    function (arg, k) {
   //computation       //computation
   return result;      k(result);
}                   }
CPS - Example
function add(x, y) {
   return x + y
}

function square(x) {
   return x * x
}

function calculate(x, y) {
   return add(square(x), square(y))
}

js> print(calculate(3, 4))
=> 25
CPS - Example
function add_cps(x, y, c) {
   c(x + y)
}

function square_cps(x, c) {
   c(x * x)
}
CPS - Example
function add_cps(x, y, c) {
   c(x + y)
}

function square_cps(x, c) {
   c(x * x)
}

function calculate_cps(x, y, c) {
   square_cps(x, function(v) {
                     square_cps(y, function(r){
                                       add_cps(v,r,c)
                                    })
                  })
}
CPS - Example
function add_cps(x, y, c) {
   c(x + y)
}

function square_cps(x, c) {
   c(x * x)
}

function calculate_cps(x, y, c) {
   square_cps(x, function(v) {
                     square_cps(y, function(r){
                                       add_cps(v,r,c)
                                    })
                  })
}

js> calculate_cps(3, 4, print)
=> 25
js> calculate_cps(3, 4, function(v) {print(sqrt(v))});
=> 5
CPS
●   CPS is used in programming languages that do not
    have first – class continuations, but have first –
    class functions


●   Every call is a tail call and if used without Tail Call
    Optimization (TCO), the continuation would grow
    during recursion


●   Using CPS and TCO, compilers and interperters of
    some programming languages managed to
    eliminate the need for a runtime stack.
Continuations
Delimited Continuations
●   Delimited (or partial, or composable) continuations are
    more like regular functions and less like GOTOs. They
    do not embody the entire rest of the computation, but
    just a partial rest, up to a programmer-defined outer
    bound.


●   delimited continuations will return control to the caller
    after they are invoked, and they may also return values


      –   Tiark Rompf, Ingo Maier, Martin Odersky
Normal         Control Flow with
Control Flow   Delimited Continuations        Continuation invoked




                               Continuation -
                               start

                                                           Delimited
                                                           continuation



                             Continuation -
                             end
Delimited Continuations
●
    Delimited Continuations are manipulated
    by means of two primitives, shift and
    reset.


●
    Calling shift captures the current
    continuation, and reset defines the
    boundary up to which the continuation
    reaches.
Delimited Continuations
reset {
   shift { k: (Int=>Int) =>
      k(7)
   } + 1
} * 2


scala>
16




CPS transformed
2 * (1 + 7)
Delimited Continuations
reset {
   shift { k: (Int=>Int) =>
      k(7)
   } + 1
} * 2


scala>
16
__________________________________________________________

reset {            def foo() {
   foo() + 1          shift { k: (Int=>Int) =>
} * 2                    k(7)
                      }
                   }

CPS transformed
2 * (1 + 7)
Delimited Continuations
reset{
   1 + shift{ k: (Int=>Int) =>
         k(k(7))
      }
} * 3

scala>
27


reset{
   1 + shift{ k: (Int=>Int) =>
         k(k(7))
      } * 3
}

scala>
67
Delimited Continuations
reset{
   1 + shift{ k: (Int=>Int) =>
         k(k(7))
      }
} * 3

scala>
27        CPS Transform:   (1 + (1 + 7)) * 3 = 27


reset{
   1 + shift{ k: (Int=>Int) =>
         k(k(7))
      } * 3
}

scala>
67        CPS Transform:   (1 + (1 + 7 * 3) * 3) = 67
So... ummm..
Whats the real world use of this thing?
Continuations
Applications of Continuations
●
    Pause and Play e.g. User Interface design
●
    Backtracking
●
    Coroutines
●
    Exception Handling
●
    Web Frameworks
●
    Compiler & Interpreter implementation
Problems
●
    Page centric
●
    HTTP Stateless-ness causes heavy use of
    session, cookies
●
    'Back' button in user interaction pages
●
    Browser cloning in user interaction pages
●
    Inversion of control
def add_two_numbers
  n1 = callcc { |cc| return ask("1st number:", cc) }
  n2 = callcc { |cc| return ask("2nd number:", cc) }
  print "sum of two numbers is #{n1 + n2}n"
end
def add_two_numbers
  n1 = callcc { |cc| return ask("1st number:", cc) }
  n2 = callcc { |cc| return ask("2nd number:", cc) }
  print "sum of two numbers is #{n1 + n2}n"
end



irb> add_two_numbers
1st number:
respond with: submit(25, ...): => #<Continuation:0xb76e0e58>
irb> submit(25, 30)
2nd number:
respond with: submit(37, ...): => #<Continuation:0xb76ddde8>
irb> submit(37, 12)
sum of two numbers is 42
=> nil
def add_two_numbers
  n1 = callcc { |cc| return ask("1st number:", cc) }
  n2 = callcc { |cc| return ask("2nd number:", cc) }
  print "sum of two numbers is #{n1 + n2}n"
end

@session = Hash.new

def ask(str, cc)
  r = rand(100).to_i
  print "#{str}nrespond with: submit(#{r}, ...): "
  @session[r] = cc
  cc
end

def submit(id, number)
  @session[id].call(number)
End
Continuations lookup table (session)



Server renders the
page and saves the                     The continuation
 continuation in the                  object is looked up
session with a uuid                   based on the uuid         The page is
                       1    4            in the url and      rendered with the
                                           executed           uuid given in the
                                                                     url


             server
                                                       2
             call: page a
             call: page b                                             client
             call: page c
                                                       3




                                                 Client makes a
                                                server response
                                                  with required
                                                   information
Web Frameworks
●
    Seaside in Smalltalk (v 3.1)
●
    Wee in Ruby (v 2.1)
●
    Nagare in Python (v 0.3)
●
    Apache Cocoon in Java (v 2.2)
●
    RIFE in Java (v 1.6)
●
    Ocsigen in OCaml (v 1.3)
●
    Weblocks in Common Lisp
Web Servers with Continuations
           support
●   Continuity (Perl)
●   Jetty 6 (Java)
●   Plt-Scheme web server (Scheme)
Continuations
Seaside
●   Written in Smalltalk


●   Often called the 'heretic' framework because it doesn't
    follow the 'conventional' web wisdom


      –   Clean urls
      –   Templates to separate model and view
      –   Share as little state as possible


      –   Urls contain session identifiers
      –   There is no 'view' or html templates. Views are part of smalltalk objects
      –   Seaside continuations & callbacks give a stateful behavior
Seaside - Installation
     One – click install experience
Seaside - Workspace
●
    Smalltalk deals with image snapshots for
    saving the workspace.


●
    There is no concept of 'files' and 'editors'


●
    Class objects are created through 'object
    browser' and code is executed through a
    'workspace'
Seaside - Components
●   Components represent the whole of a page or portion of
    pages


●   The inherit from 'WAComponent' class


●   Components maintain state


●   Component's response loop
      –   Renders the component
      –   Waits for user's input
      –   Executes a block of code when a link or button is pressed
      –   Re-renders itself or another component in place
Image from - Seaside – A Multiple Control Flow Web Application Framework, Stéphane Ducasse
Seaside - callbacks
●   Every user interaction on the web page triggers a
    callback.


●
    A callback can be on a link, button or any other
    form elements


●
    The callback will execute a block of code whose
    result will end in re-rendering the component or
    a new component
SimpleCounter>>initialize
  super initialize.
  counter := 0.

SimpleCounter>>renderContentOn: html
  html heading: 'the counter is ', counter asString.
  html anchor
     callback: [ counter := counter + 1 ];
     with: 'increase'.
Seaside - Continuations
●   Call / Answer
    ●   call: takes a component as a parameter and it swaps
        the current component for the new component


    ●   The new component will be rendered and user action
        will cause a callback to run that'll send an answer:


    ●   The value passed to answer: will be returned to call:
        and the program will continue from there.
Image from - Seaside – A Multiple Control Flow Web Application Framework, Stéphane Ducasse
Problem with full continuation


        Response 1          Response 2




      Continuation saved   Continuation invoked




     Request 1               Request 2
Solved with delimited
    continuation
 Response 1

                      Response 2
 Delimited
 Continuation saved


                       Delimited
                       Continuation invoked




 Request 1            Request 2
Challenges
●
    Understanding continuations as a concept
●
    Debugging
●
    Buying into the 'heretic' idea
Seaside – Demo
References
●   http://en.wikipedia.org/wiki/Continuation
●   http://idea-log.blogspot.com/2005/10/why-are-continuations-so-confusing-
    and.html
●   http://www.iam.unibe.ch/~scg/Archive/Papers/Duca04eSeaside.pdf
●   http://vimeo.com/13304075
●   http://www.intertwingly.net/blog/2005/04/13/Continuations-for-Curmudgeons
●   http://www.cs.indiana.edu/~dfried/appcont.pdf
●   http://lambda-the-ultimate.org/node/86
●   http://en.wikipedia.org/wiki/Continuation-passing_style
●   http://lamp.epfl.ch/~rompf/continuations-icfp09.pdf
●   http://book.seaside.st/book
●   http://en.wikipedia.org/wiki/Call-with-current-continuation
●   http://www.ibm.com/developerworks/java/library/j-contin.html
●   http://www.cs.brown.edu/~sk/Publications/Papers/Published/khmgpf-impl-use-
    plt-web-server-journal/
●   http://double.co.nz/pdf/continuations.pdf

More Related Content

PPTX
OOPS In JAVA.pptx
PPT
Introduction to Compiler design
PPTX
System Programming Unit II
PPTX
Pseudocode
PPTX
ASP.NET Page Life Cycle
PPTX
Kraken js at paypal
PDF
The Concept of Abstract Window Took Kit In Java
PDF
Deterministic Finite Automata (DFA)
OOPS In JAVA.pptx
Introduction to Compiler design
System Programming Unit II
Pseudocode
ASP.NET Page Life Cycle
Kraken js at paypal
The Concept of Abstract Window Took Kit In Java
Deterministic Finite Automata (DFA)

What's hot (20)

PPT
Intent, Service and BroadcastReciver (2).ppt
PPT
PDF
Difference between ActionResult() and ViewResult()
PPT
Regular expressions and languages pdf
PPTX
Semantic Analysis.pptx
PPTX
PPTX
BNF & EBNF
DOCX
Chapter 5: Names, Bindings and Scopes (review Questions and Problem Set)
PDF
Tiered Compilation in Hotspot JVM
PPTX
Introduction to xampp
PPTX
asp.net Webconfiguration
PPT
Type Checking(Compiler Design) #ShareThisIfYouLike
PDF
Prova 01 de Autômatos e Computabilidade
PPTX
Asynchronous programming
PPT
Java beans
PDF
Tdd with python unittest for embedded c
ODP
Functional programming
PPTX
Apache Storm - Real Time Analytics
PPTX
Java Introduction
PPT
Introduction to CLIPS Expert System
Intent, Service and BroadcastReciver (2).ppt
Difference between ActionResult() and ViewResult()
Regular expressions and languages pdf
Semantic Analysis.pptx
BNF & EBNF
Chapter 5: Names, Bindings and Scopes (review Questions and Problem Set)
Tiered Compilation in Hotspot JVM
Introduction to xampp
asp.net Webconfiguration
Type Checking(Compiler Design) #ShareThisIfYouLike
Prova 01 de Autômatos e Computabilidade
Asynchronous programming
Java beans
Tdd with python unittest for embedded c
Functional programming
Apache Storm - Real Time Analytics
Java Introduction
Introduction to CLIPS Expert System
Ad

Similar to Continuations (20)

PDF
Continuations in Ruby (Anton Vasiljev)
PDF
Anton Vasiljev: Continuations in Ruby.
PDF
Blocks and loops.pptx
PDF
EventStudio: Sequence Diagram Based System Modeling Tool
PDF
Continuations in scala (incomplete version)
PDF
Ruby & Machine Vision - Talk at Sheffield Hallam University Feb 2009
PPT
Class 9 Lecture Notes
PDF
Pydiomatic
PDF
Python idiomatico
KEY
Lecture on Rubinius for Compiler Construction at University of Twente
PPTX
Ruby introduction part1
PDF
Monadologie
PDF
00 ruby tutorial
PPTX
Ruby -the wheel Technology
KEY
Test First Teaching
PDF
Detecting Occurrences of Refactoring with Heuristic Search
PPTX
Exploit exercises.com stack-overflows
PDF
C言語静的解析ツールと Ruby 1.9 trunk
PDF
ruby1_6up
PDF
ruby1_6up
Continuations in Ruby (Anton Vasiljev)
Anton Vasiljev: Continuations in Ruby.
Blocks and loops.pptx
EventStudio: Sequence Diagram Based System Modeling Tool
Continuations in scala (incomplete version)
Ruby & Machine Vision - Talk at Sheffield Hallam University Feb 2009
Class 9 Lecture Notes
Pydiomatic
Python idiomatico
Lecture on Rubinius for Compiler Construction at University of Twente
Ruby introduction part1
Monadologie
00 ruby tutorial
Ruby -the wheel Technology
Test First Teaching
Detecting Occurrences of Refactoring with Heuristic Search
Exploit exercises.com stack-overflows
C言語静的解析ツールと Ruby 1.9 trunk
ruby1_6up
ruby1_6up
Ad

Continuations

  • 1. Continuations & Web Applications -Balaji Damodaran, ThoughtWorks
  • 4. Contiuation ● Continuation is Time Travel ● Continuation is saving the control flow of a program's execution
  • 6. class ControlCentre def exploreTerrain marsPlateau = Plateau.new(5, 5) alpha = Rover.new("alpha") source = Position.new(1, 2, "N") alpha.land(marsPlateau, source) destination = alpha.explore("LMLMLMLMM") print destination end end
  • 7. class ControlCentre def exploreTerrain marsPlateau = Plateau.new(5, 5) alpha = Rover.new("alpha") source = Position.new(1, 2, "N") alpha.land(marsPlateau, source) destination = alpha.explore("LMLMLMLMM") print destination end end
  • 8. class ControlCentre def exploreTerrain marsPlateau = Plateau.new(5, 5) alpha = Rover.new("alpha") source = Position.new(1, 2, "N") alpha.land(marsPlateau, source) destination = alpha.explore("LMLMLMLMM") print destination end end Control Scope Execution Context marsPlateau alpha
  • 9. class ControlCentre def exploreTerrain marsPlateau = Plateau.new(5, 5) alpha = Rover.new("alpha") source = Position.new(1, 2, "N") alpha.land(marsPlateau, source) destination = alpha.explore("LMLMLMLMM") print destination end end Control Scope Current Continuation Execution Context source = Position.new(1, 2, "N") marsPlateau alpha.land(marsPlateau, source) destination = alpha.explore("LMLMLMLMM") alpha print destination
  • 10. class ControlCentre def exploreTerrain marsPlateau = Plateau.new(5, 5) alpha = Rover.new("alpha") callcc{|@cc|} source = Position.new(1, 2, "N") alpha.land(marsPlateau, source) destination = alpha.explore("LMLMLMLMM") print destination return @cc end end
  • 11. class ControlCentre def exploreTerrain marsPlateau = Plateau.new(5, 5) alpha = Rover.new("alpha") callcc{|@cc|} source = Position.new(1, 2, "N") alpha.land(marsPlateau, source) destination = alpha.explore("LMLMLMLMM") print destination return @cc end end > c = exploreTerrain “1 3 N” => #<Continuation:0xb744a8c4> > c.call “1 3 N” => #<Continuation:0xb744a8c4>
  • 12. Normal Control Flow with Continuation invoked Control Flow Continuations continuation continuation
  • 13. Isn't that just a glorified GOTO?
  • 14. class ControlCentre def exploreTerrain marsPlateau = Plateau.new(5, 5) alpha = Rover.new("alpha") c = nil source = callcc do |cc| c = cc Position.new(1, 2, "N") end alpha.land(marsPlateau, source) destination = alpha.explore("LMLMLMLMM") print destination return c end end > c = exploreTerrain “1 3 N” => #<Continuation:0xb7466240> > c.call(Position.new(2, 3, “E”)) “2 4 E” => #<Continuation:0xb7466240>
  • 15. Normal Control Flow with Continuation invoked Control Flow Continuations with different parameters continuation continuation With different parameters
  • 16. def continuation puts "i do some computation " + "& save the state of execution." m = callcc { |cc| return cc } puts "then i restart the execution from " + "the saved state & pass custom " + "values such as "#{m[0]}" and "#{m[1]}"" end > c = continuation i do some computation & save the state of execution. > c.call("so..", "then..") then i restart the execution from the saved state & pass custom values such as "so.." and "then.."
  • 17. Normal Control Flow with Continuation reinvoked Control Flow Continuations paused with parameters continuation With parameters continuation
  • 19. Continuation? ● A continuation reifies the control flow of a program as just another data value ● Reify – To consider an abstract concept to be real. To make control flow as first class functions/objects.
  • 20. Continuation ● Continuation is an object that takes a snapshot copy of the running process. ● The current process is copied and saved. ● Current process – execution context and all local variables
  • 21. Normal Control Flow marked with Control Flow continuation Memory Local variables # continuation
  • 22. A new process that invokes a continuation Memory # The current execution is abandoned Note: Global data does not get stored in a continuation
  • 23. Continuations ● A Continuation stores the execution context, its references and pointers. ● However, it does not store the heap data or data that is outside the scope of local references and pointers. ● So any change made to them will stay changed even after invoking the continuation.
  • 26. call-with-current-continuation ● call-with-current-continuation, in short called as “call/cc” is a procedure first introduced in Scheme. ● Now exists in several other programming languages such as Ruby, known as “callcc”
  • 27. call-with-current-continuation ● call/cc takes in only one argument, which is a function f. ● It takes the current continuation as an object and applies f to it. – continuation = new Continuation() – function(continuation) ● When, callcc gets invoked, the program flow will continue from the point it was captured and the argument to the continuation will become its return value
  • 28. call-with-current-continuation Method definition: function: call/cc(function: f) { c = new: Continuation f(c) } JavaScript (Rhino): function callcc(f) { var c = new Continuation(); return f(c); } Ruby: callcc {|cont|} cont => Continuation object cont.call(*args)
  • 29. call-with-current-continuation function callcc(fun) { var continuation = new Continuation() return fun(continuation) } var cc print(3 * (8 + callcc(function(c) { cc = c return 4 }))) js> 36
  • 30. call-with-current-continuation function callcc(fun) { var continuation = new Continuation() return fun(continuation) } var cc print(3 * (8 + callcc(function(c) { cc = c return 4 }))) js> 36 js> cc(6) 42
  • 31. def continue_example i = 0 print "Before callcc #{i}n" callcc do |cc| for i in 1..10 do print "In callcc #{i}n" return cc if i > 5 end end print "After callcc #{i}n" end
  • 32. def continue_example i = 0 print "Before callcc #{i}n" callcc do |cc| for i in 1..10 do print "In callcc #{i}n" return cc if i > 5 end end print "After callcc #{i}n" end puts "begin control flow." c = continue_example() puts "after invoking the method" if c c.call puts "this will not get executed" end
  • 33. def continue_example i = 0 print "Before callcc #{i}n" callcc do |cc| begin control flow. for i in 1..10 do Before callcc 0 print "In callcc #{i}n" In callcc 1 return cc if i > 5 In callcc 2 end In callcc 3 end In callcc 4 print "After callcc #{i}n" In callcc 5 end In callcc 6 after invoking the method After callcc 6 after invoking the method puts "begin control flow." c = continue_example() puts "after invoking the method" if c c.call puts "this will not get executed" end
  • 34. call-with-current-continuation ● Continuations are sort of goto labels. But more powerful. ● We can store the continuation in a variable or object field, unlike a goto label. ● Goto labels are restricted within a functional scope, continuations are not limited by that.
  • 35. The following code is strictly for session purposes only. Implementing this in usable code may cause harm to life and limb.
  • 36. Continuation as a GOTO def goto_in_ruby_1 i = 0 callcc {|@label|} i = i + 1 print "#{i}t" @label.call if i < 10 end
  • 37. Continuation as a GOTO def goto_in_ruby_1 i = 0 callcc {|@label|} i = i + 1 print "#{i}t" @label.call if i < 10 end output: 1 2 3 4 5 6 7 8 9 10
  • 38. Continuation as a GOTO def goto_in_ruby_1 def goto_in_ruby_2 i = 0 i = 0 callcc {|@label|} callcc do |label| i = i + 1 label.call print "#{i}t" i = 99 @label.call if i < 10 end end print i end output: 1 2 3 4 5 6 7 8 9 10
  • 39. Continuation as a GOTO def goto_in_ruby_1 def goto_in_ruby_2 i = 0 i = 0 callcc {|@label|} callcc do |label| i = i + 1 label.call print "#{i}t" i = 99 @label.call if i < 10 end end print i end output: output: 1 2 3 4 5 6 7 8 9 10 0
  • 40. Summary ● Continuation is a procedure that represents the remaining steps in a computation. ● It is a "snapshot" of the current control context or control state of the program ● The continuation can be later invoked (repeatedly) with custom arguments
  • 41. Continuations ● Languages that support first class continuations ● Scheme (call/cc) ● Ruby (callcc) ● Smalltalk (Continuation currentDo:) ● Rhino [JavaScript] (new Continuation()) ● Scala (Responder & shift, reset) ● Perl (Coro) ● Haskell (Control.Monad.Cont)
  • 42. Continuations Types ● First class continuations ● Continuation Passing Style (CPS) ● Delimited Continuations
  • 44. Continuation Passing Style ● A function, instead of returning an explict value, it takes an explict 'continuation' argument – another function which is meant to receive the result of the computation
  • 45. Continuation Passing Style function (arg) { function (arg, k) { //computation //computation return result; k(result); } }
  • 46. CPS - Example function add(x, y) { return x + y } function square(x) { return x * x } function calculate(x, y) { return add(square(x), square(y)) } js> print(calculate(3, 4)) => 25
  • 47. CPS - Example function add_cps(x, y, c) { c(x + y) } function square_cps(x, c) { c(x * x) }
  • 48. CPS - Example function add_cps(x, y, c) { c(x + y) } function square_cps(x, c) { c(x * x) } function calculate_cps(x, y, c) { square_cps(x, function(v) { square_cps(y, function(r){ add_cps(v,r,c) }) }) }
  • 49. CPS - Example function add_cps(x, y, c) { c(x + y) } function square_cps(x, c) { c(x * x) } function calculate_cps(x, y, c) { square_cps(x, function(v) { square_cps(y, function(r){ add_cps(v,r,c) }) }) } js> calculate_cps(3, 4, print) => 25 js> calculate_cps(3, 4, function(v) {print(sqrt(v))}); => 5
  • 50. CPS ● CPS is used in programming languages that do not have first – class continuations, but have first – class functions ● Every call is a tail call and if used without Tail Call Optimization (TCO), the continuation would grow during recursion ● Using CPS and TCO, compilers and interperters of some programming languages managed to eliminate the need for a runtime stack.
  • 52. Delimited Continuations ● Delimited (or partial, or composable) continuations are more like regular functions and less like GOTOs. They do not embody the entire rest of the computation, but just a partial rest, up to a programmer-defined outer bound. ● delimited continuations will return control to the caller after they are invoked, and they may also return values – Tiark Rompf, Ingo Maier, Martin Odersky
  • 53. Normal Control Flow with Control Flow Delimited Continuations Continuation invoked Continuation - start Delimited continuation Continuation - end
  • 54. Delimited Continuations ● Delimited Continuations are manipulated by means of two primitives, shift and reset. ● Calling shift captures the current continuation, and reset defines the boundary up to which the continuation reaches.
  • 55. Delimited Continuations reset { shift { k: (Int=>Int) => k(7) } + 1 } * 2 scala> 16 CPS transformed 2 * (1 + 7)
  • 56. Delimited Continuations reset { shift { k: (Int=>Int) => k(7) } + 1 } * 2 scala> 16 __________________________________________________________ reset { def foo() { foo() + 1 shift { k: (Int=>Int) => } * 2 k(7) } } CPS transformed 2 * (1 + 7)
  • 57. Delimited Continuations reset{ 1 + shift{ k: (Int=>Int) => k(k(7)) } } * 3 scala> 27 reset{ 1 + shift{ k: (Int=>Int) => k(k(7)) } * 3 } scala> 67
  • 58. Delimited Continuations reset{ 1 + shift{ k: (Int=>Int) => k(k(7)) } } * 3 scala> 27 CPS Transform: (1 + (1 + 7)) * 3 = 27 reset{ 1 + shift{ k: (Int=>Int) => k(k(7)) } * 3 } scala> 67 CPS Transform: (1 + (1 + 7 * 3) * 3) = 67
  • 59. So... ummm.. Whats the real world use of this thing?
  • 61. Applications of Continuations ● Pause and Play e.g. User Interface design ● Backtracking ● Coroutines ● Exception Handling ● Web Frameworks ● Compiler & Interpreter implementation
  • 62. Problems ● Page centric ● HTTP Stateless-ness causes heavy use of session, cookies ● 'Back' button in user interaction pages ● Browser cloning in user interaction pages ● Inversion of control
  • 63. def add_two_numbers n1 = callcc { |cc| return ask("1st number:", cc) } n2 = callcc { |cc| return ask("2nd number:", cc) } print "sum of two numbers is #{n1 + n2}n" end
  • 64. def add_two_numbers n1 = callcc { |cc| return ask("1st number:", cc) } n2 = callcc { |cc| return ask("2nd number:", cc) } print "sum of two numbers is #{n1 + n2}n" end irb> add_two_numbers 1st number: respond with: submit(25, ...): => #<Continuation:0xb76e0e58> irb> submit(25, 30) 2nd number: respond with: submit(37, ...): => #<Continuation:0xb76ddde8> irb> submit(37, 12) sum of two numbers is 42 => nil
  • 65. def add_two_numbers n1 = callcc { |cc| return ask("1st number:", cc) } n2 = callcc { |cc| return ask("2nd number:", cc) } print "sum of two numbers is #{n1 + n2}n" end @session = Hash.new def ask(str, cc) r = rand(100).to_i print "#{str}nrespond with: submit(#{r}, ...): " @session[r] = cc cc end def submit(id, number) @session[id].call(number) End
  • 66. Continuations lookup table (session) Server renders the page and saves the The continuation continuation in the object is looked up session with a uuid based on the uuid The page is 1 4 in the url and rendered with the executed uuid given in the url server 2 call: page a call: page b client call: page c 3 Client makes a server response with required information
  • 67. Web Frameworks ● Seaside in Smalltalk (v 3.1) ● Wee in Ruby (v 2.1) ● Nagare in Python (v 0.3) ● Apache Cocoon in Java (v 2.2) ● RIFE in Java (v 1.6) ● Ocsigen in OCaml (v 1.3) ● Weblocks in Common Lisp
  • 68. Web Servers with Continuations support ● Continuity (Perl) ● Jetty 6 (Java) ● Plt-Scheme web server (Scheme)
  • 70. Seaside ● Written in Smalltalk ● Often called the 'heretic' framework because it doesn't follow the 'conventional' web wisdom – Clean urls – Templates to separate model and view – Share as little state as possible – Urls contain session identifiers – There is no 'view' or html templates. Views are part of smalltalk objects – Seaside continuations & callbacks give a stateful behavior
  • 71. Seaside - Installation One – click install experience
  • 72. Seaside - Workspace ● Smalltalk deals with image snapshots for saving the workspace. ● There is no concept of 'files' and 'editors' ● Class objects are created through 'object browser' and code is executed through a 'workspace'
  • 73. Seaside - Components ● Components represent the whole of a page or portion of pages ● The inherit from 'WAComponent' class ● Components maintain state ● Component's response loop – Renders the component – Waits for user's input – Executes a block of code when a link or button is pressed – Re-renders itself or another component in place
  • 74. Image from - Seaside – A Multiple Control Flow Web Application Framework, Stéphane Ducasse
  • 75. Seaside - callbacks ● Every user interaction on the web page triggers a callback. ● A callback can be on a link, button or any other form elements ● The callback will execute a block of code whose result will end in re-rendering the component or a new component
  • 76. SimpleCounter>>initialize super initialize. counter := 0. SimpleCounter>>renderContentOn: html html heading: 'the counter is ', counter asString. html anchor callback: [ counter := counter + 1 ]; with: 'increase'.
  • 77. Seaside - Continuations ● Call / Answer ● call: takes a component as a parameter and it swaps the current component for the new component ● The new component will be rendered and user action will cause a callback to run that'll send an answer: ● The value passed to answer: will be returned to call: and the program will continue from there.
  • 78. Image from - Seaside – A Multiple Control Flow Web Application Framework, Stéphane Ducasse
  • 79. Problem with full continuation Response 1 Response 2 Continuation saved Continuation invoked Request 1 Request 2
  • 80. Solved with delimited continuation Response 1 Response 2 Delimited Continuation saved Delimited Continuation invoked Request 1 Request 2
  • 81. Challenges ● Understanding continuations as a concept ● Debugging ● Buying into the 'heretic' idea
  • 83. References ● http://en.wikipedia.org/wiki/Continuation ● http://idea-log.blogspot.com/2005/10/why-are-continuations-so-confusing- and.html ● http://www.iam.unibe.ch/~scg/Archive/Papers/Duca04eSeaside.pdf ● http://vimeo.com/13304075 ● http://www.intertwingly.net/blog/2005/04/13/Continuations-for-Curmudgeons ● http://www.cs.indiana.edu/~dfried/appcont.pdf ● http://lambda-the-ultimate.org/node/86 ● http://en.wikipedia.org/wiki/Continuation-passing_style ● http://lamp.epfl.ch/~rompf/continuations-icfp09.pdf ● http://book.seaside.st/book ● http://en.wikipedia.org/wiki/Call-with-current-continuation ● http://www.ibm.com/developerworks/java/library/j-contin.html ● http://www.cs.brown.edu/~sk/Publications/Papers/Published/khmgpf-impl-use- plt-web-server-journal/ ● http://double.co.nz/pdf/continuations.pdf