[comp.lang.rexx] First class continuations

schwartz@psuvax1.cs.psu.edu (Scott Schwartz) (12/17/89)

I wrote:
    Not really...  It doesn't have continuations (like Scheme or Self)
And later:
    Anyway, let's not get carried away with this.  REXX is a fine language;
    not supporting every known control structure is nothing to be ashamed
    of!

I still think that, but since a number of people have emailed me
asking about this, I'm offering some more explanation in this note.

David Wright writes:
>	You obviously have never really USED Rexx, or any other extensible
>language. Your argument that because it doesn't do something "out of the
>box", Rexx must be lacking something is completely wrong.

No need to be insulting.  In fact, I have used REXX and Forth.  (In
fact, sparcstations use a forth interpreter as their prom monitor!!  Go
Sun!) If I were feeling cynical, I'd suggest that you have obviously
never used Scheme, or you'd realize what I was getting at.

>	As any FORTH programmer can tell you, what comes out of the
>box is just the beginning. The only limits to ANY language are the real,
>factual, limitations of the implementation.

Agreed.  Forth, like lisp, is especially good at this kind of thing,
too, since you can alter the behavour of the system itself at runtime.
Rexx is more traditional in that you can't (as far as I know) alter
the _Rexx_interpreter_itself_ while it is running. 

>	Now if Rexx did not really support the writing of modules in other
>languages, and these additions were just "patch jobs", you would be at least
>half right. 

It is not enough to be able to write modules in other languages.  I'm
sure you can do coroutines to some extent with a little hacking, if
your OS offers support for interprocess communication, but I'd really
be surprised if first class continuations could be done directly in
Rexx.

A continuation is the next state a program is about to enter; in a
sense all programming languages have them.  The difference is that
Scheme treats them as first class objects:  you can store them in
variables, execute them, etc.  A very weak analogy is C's
setjump/longjump facility.  Continuations are more general; longjump
requires that the saved stack frame still be valid.  In Scheme all
stack frames are valid as long as someone is capable of returning to
them.   Coroutines are very easily implemented in terms of
continuations.

A continuation is captured with the primative
"call-with-current-continuation", or "call/cc" as it is often
abbreviated.  This takes as an argument a procedure of one argument.
The procedure is invoked with the current continuation as its argument,
allowing you to operate on the continuation in some way.

A nice example of all this is from a paper by Haynes and Friedman of
Indiana University ["Embedding Continuations in Procedural Objects" in
ACM TOPLAS, vol 9 no 4, Oct 1987].  They offer the case of a program
doing nonblind backtracking; the backtracking is nonblind because you
work on one approach for a while, then try a second approach for a
while, and then go back and finish up the first approach.  In Scheme
you render this as:

(let ([backtrack-k any]		; initialize to 
      [non-blind-k any])	; 	any value.

  (if (call/cc			; capture continuation; branch on retval.
        (lambda (k)	
          (set! backtrack-k k)		; record state.  the continuation we
					; captured was after evaluating the
					; first argument to "if".
          (backtrack-k #t)))    	; resume "if" with value true.

      (begin			; true -> try first approach.
        (do-first-approach-for-a-while)
        (when time-to-backtrack
          (call/cc			; capture current state, ignore retval.
            (lambda (k)
              (set! non-blind-k k)	; store state we might return to.
              (backtrack-k #f))))	; restart search, use other method.
					; this causes execution to resume 
					; in the midst of the "if" above, 
					; with argument false.
        (continue-first-approach))

      (begin			; else try other approach.
         (try-another-approach)
         (if have-answer
           answer
           (non-blind-k any)))))	; resume saved state

>	To judge modern or by definition extensible langues such as
>Rexx or FORTH with the same standards used for more limited languages such
>as BASIC, Fortran, or COBOL is like comparing apples and oranges. 

What are BASIC, Fortran and COBOL, and why are you mentioning them?
-- 
Scott Schwartz		<schwartz@shire.cs.psu.edu>
"More mips; cheaper mips; never too many." -- John Mashey