2010-05-28

Perlesque Obtains Reified Continuations

Yesterday Perlesque obtained reified continuations with semantics sortof a hybrid between setjmp/longjmp and let/cc/call/cc.  The _cc keyword is an expression that returns a reference to the currently-executing stack frame (activation record), which itself holds an instruction pointer as to its progress through the routine's instructions.

The resulting Frame, whose type derives FrameBase, can be "backtracked to" by using the syntax   goto $frame   as in the below:

my $e = sub (FrameBase $f-->int) {
  say(1);
  goto $f;
  say(2);
  return 1
};
sub callcc(Callable[:(FrameBase-->int)] $func, FrameBase $frame --> int) {
  $func($frame);
  say(3);
  return 1
};
callcc($e, _cc);
say(4);

Here, the subroutine named "callcc" takes two parameters: the first is a closure that ostensibly takes a stack frame and returns an int; the second is a stack frame.  "callcc" applies its first argument to its second argument, and then prints "3".  The closure that is stored in $e prints "1", does a "longjmp" (non-local goto) to the continuation stack-frame passed in as its argument, and then prints "2" (except say("2") is unreachable, since it immediately follows a goto statement).

The output of the above is:    1  4   since the "goto $f" statement in closure $e immediately returns control to the outermost scope, at the last point it called out from it.

Note: The semantics of these continuations are slightly different from other languages' reified continuations, in that the instruction pointer is tied to the stack frame itself, and not to the continuation of the stack frame only (since in this scheme, they're one-in-the-same).

This means that if a continuation reference is "goto'd" and then "returns" and that same continuation reference is then "goto'd" again from elsewhere (if, let's say, the continuation reference was stashed in a global variable somewhere), the routine will immediately return, and/or the behavior will be undefined, since other frames could exist on the "cactus stack" that have already returned.

Edit:  awwaiid pointed out that these are coroutines, not full-blown continuations, since they aren't cloned.  So I'm adding to FrameBase an abstract .Clone() method that will be generated by the compiler, so that a cloned continuation can be restarted from where it was originally captured (or cloned again). :)

Edit:  I finished adding .Clone() method generators to the compiler, so perlesque now truly has reified *full* continuations.

26 comments:

  1. This comment has been removed by a blog administrator.

    ReplyDelete
  2. This comment has been removed by a blog administrator.

    ReplyDelete
  3. 嗨!很喜歡來這欣賞你的作品,幫你推推推當上人氣王唷..................................................................

    ReplyDelete
  4. 人生有如洶湧的波濤,如果沒有岩石的阻擋,怎能激起美麗的浪花?............................................................

    ReplyDelete
  5. 生命就像騎單車一樣,除非你停止踩踏板,否則不會掉下去。.......................................................

    ReplyDelete
  6. 愛情是一種發明,需要不斷改良。只是,這種發明和其他發明不一樣,它沒有專利權,隨時會被人搶走。.................................................................

    ReplyDelete
  7. 真正仁慈的人,會忘記他們做過的善行,他們全心投入現在的工作,過去的事已被遺忘。.................................................

    ReplyDelete
  8. 讓好心情回味發酵;壞心情留在文字裡隨時間消逝吧!............................................................

    ReplyDelete