[plt-scheme] Re: Continuations memory accumulation problem

From: Anthony Cowley (acowley at seas.upenn.edu)
Date: Mon Mar 15 14:28:05 EDT 2010

On Mon, Mar 15, 2010 at 8:08 AM, Ciprian Dorin, Craciun
<ciprian.craciun at gmail.com> wrote:
>    Could someone explain this to me?

I'm going to give an answer that will probably only be partially
helpful. First, are you really committed to doing things this way? I
would certainly recommend a more functional approach to computing new
robot states from old ones. The continuation approach is confusing,
and ends up involving you passing around robot state in any case, it's
just that robot state is a per-robot continuation holding on to
references to who-knows-what (which can lead to memory leaks). Bear in
mind that, ideally, you have a continuation per-robot and a
continuation for the scheduler. If the per-robot continuations close
over other continuations, in particular continuations of the larger
program state that might involve running other robots, then things can
go sideways.

I'm not completely certain this does what you want, but this is a
version using delimited continuations that tries to be faithful to
your overall design.

I think it's quite a bit less code, and the robot behavior
specification is pretty well isolated from control structures. Each
time around, the robot picks up where it left off, does its work, then
stashes away a bookmark to its current state and kicks back out to the
scheduler via calls to control. The main point, though, is to simplify
the code to make debugging easier.



#lang scheme
(require scheme/control)

(define-struct robot
  (continuation) #:mutable)

(define (create-robot)
  (make-robot (void)))

(define (step-robots! robots)
  (for ((robot (in-list robots)))
         ((void? (robot-continuation robot))
          (start-robot! robot))
         ((continuation? (robot-continuation robot))
          (enter-robot! robot))
         (else (printf "died~n"))))
  (unless (andmap (compose not robot-continuation) robots)
    (step-robots! robots)))

(define (start-robot! robot)
   (printf "Starting robot~n")
   (do-robot! robot)
   (done-robot! robot)))

(define (enter-robot! robot)
  (prompt ((robot-continuation robot))))

(define (exit-robot! robot)
  (control k (set-robot-continuation! robot k) #t))

(define (done-robot! robot)
  (printf "Done!~n")
  (set-robot-continuation! robot #f))

(define (do-robot! robot (steps 100000))
  (unless (zero? steps)
    (exit-robot! robot)
    (do-robot! robot (- steps 1))))

(define robots (list (create-robot) (create-robot) (create-robot)))
(define (go) (step-robots! robots))

Posted on the users mailing list.