コンティニュエーション

この節では例のみを示す。まず、引数 #common difference で与えられた数の倍数を次々に出力するサブルーチンを考える。

code
procedure arithmetic progression
write: to (cn +) value (0)
loop
 print: [cn +]
 write: to (cn +) value ([cn +] + #common difference)
endcode

次に、このサブルーチンを、コンティニュエーションで中断するようにする。

code
procedure arithmetic progression
write: to (cn +) value (0)
write: to (return continuation +) value (#return continuation)
loop
continuation resume continuation +
  [return continuation +]: resume continuation [resume continuation +] value [cn +]
end
 free: [get dynamic environment anonymous vector: [resume continuation +]]
 write: to (return continuation +) value (@return continuation)
 write: to (cn +) value ([cn +] + #common difference)
endcode

continuation ブロックでコンティニュエーションが作成されるとき、動的環境の固有ベクトルも作成される。この固有ベクトルは明示的に解放する必要がある。1 度作成したコンティニュエーションを 1 回しか実行しないならば、コンティニュエーションが実行された直後に固有ベクトルを解放するのが確実である。この例はそれに該当する。コンティニュエーションが実行された直後の実行位置は continuation ブロックの終端の直後なので、そこにプリミティブ演算 free を置く。ここで解放される無名ベクトルは実行中の動的環境の固有ベクトルである。実行中の動的環境の固有ベクトルは、他の無名ベクトルに保持されていなくても解放されないので、実際に解放されるのは、この動的環境の実行を終了したときである。

さらに、このサブルーチンを呼び出すメインルーチンは以下のようにする。長いので、初期化部分とループに部分に分けて示す。

code
continuation return continuation +
 arithmetic progression:
 > return continuation [return continuation +]
 > common difference (3)
end
free: [get dynamic environment anonymous vector: [return continuation +]]
write: to (step 3 + resume continuation +) value (@resume continuation)
write: to (step 3 + value +) value (@value)
continuation return continuation +
 arithmetic progression:
 > return continuation [return continuation +]
 > common difference (5)
end
free: [get dynamic environment anonymous vector: [return continuation +]]
write: to (step 5 + resume continuation +) value (@resume continuation)
write: to (step 5 + value +) value (@value)
endcode

メインルーチンのループ部分は以下のようにする。

code
write: to (cn +) value (0)
loop
 break: [cn +] < 20
 write: to (flag + step 3 less than step 5 +)
 > value ([step 3 + value +] < [step 5 + value +])
if [flag + step 3 less than step 5 +]
  print: [step 3 + value +]
  continuation return continuation +
   [step 3 + resume continuation +]: return continuation [return continuation +]
  end
  free: [get dynamic environment anonymous vector: [return continuation +]]
  write: to (step 3 + resume continuation +) value (@resume continuation)
  write: to (step 3 + value +) value (@value)
end
if ¬ [flag + step 3 less than step 5 +]
  print: [step 5 + value +]
  continuation return continuation +
   [step 5 + resume continuation +]: return continuation [return continuation +]
  end
  free: [get dynamic environment anonymous vector: [return continuation +]]
  write: to (step 5 + resume continuation +) value (@resume continuation)
  write: to (step 5 + value +) value (@value)
end
 write: to (cn +) value ([cn +] + 1)
endcode

このプログラムは 3 の倍数または 5 の倍数を小さい順に 20 個表示する。すなわち 0, 0, 3, 5, 6, 9, 10, 12, 15, 15, 12, 28, 20, 21, 24, 25, 27, 30, 30, 33 が表示される。0, 15, 30 は 3 の倍数でも 5 の倍数でもあるので、それぞれ 2 回表示される。