[comp.lang.c] A method for suspending functions in C

dave@charyb.COM (Dave Rifkind) (03/06/90)

A few languages allow subroutines to be temporarily suspended
and their execution resumed later.  Icon, for one, uses this
mechanism for implementing generators (functions that return a
sequence of values):

     procedure onetoten()
       every i := 1 to 10 do
         suspend i
     end

or equivalently:

     procedure onetoten()
       every suspend 1 to 10
     end

Clearly this does *not* translate into C as:

     int onetoten()
     {
          int i;

          for (i = 1; i <= 10; i++)
               return i;
          return 0;
     }

Here's a possible way to write the same function in C:

     int onetoten()
     {
          static int state = 0;
          static int i;

          switch (state) {
          case 0:
               for (i = 1; i <= 10; i++) {
                    state = 1;
                    return i;
          case 1:
               }
               state = 0;
               return 0;
          }
     }

This can be extended to much more complex functions.  There are
other ways to reach the same result, probably much less twisted
in most cases, but this method has one advantage: a function can
be turned into a generator without rearranging its logic, simply
by embedding it in a switch statement.

There are some obvious restrictions.  The function cannot be
recursive or reentrant, and only one instance can be alive at a
time.  Variables that need to live across suspensions must be
static.  There cannot be suspensions within other switches
inside the function (but those can usually be rewritten using
"if" and "else").

Perhaps the largest disadvantage of this method is that your
colleagues may be tempted to do you physical harm if they find
you writing this kind of code.

Tim_N_Roberts@cup.portal.com (03/07/90)

Someone who's name I've lost writes:

>     int onetoten()
>     {
>          static int state = 0;
>          static int i;
>
>          switch (state) {
>          case 0:
>               for (i = 1; i <= 10; i++) {
>                    state = 1;
>                    return i;
>          case 1:
>               }
>               state = 0;
>               return 0;
>          }
>     }

Mommy mommy, this man is scaring me.

I started shaking when I read this and I'm still shaking.  If I EVER find
code like this in a program I'm supposed to maintain, I intend to dial 911.

Can anyone convince me that this is guaranteed to work as designed?
 
TNR@cup.portal.com                |  "We come in peace. Set phasers to kill."
...!sun!portal!cup.portal.com!tnr |    - Star Trek Philosophy 101