Home > Computers and Internet > Continuations, Coroutines, Closures, Iterators

Continuations, Coroutines, Closures, Iterators

Continuations
The wikipedia definition of continuation: "a continuation is a representation of the  execution state of a program (for example, the call stack or values of variables) at a certain point."
 
To quote the wikipedia entry again "Continuations are the functional expression of the GOTO statement, and the same caveats apply". Why the hell then there is so much of fuss about continuations off late (may be this has been there for a while, but I am drawn to it because of my interest in ruby and dynamic languages)?
 
If the use of goto for control flow result in code which is harder to read and comprehend, then continuations too result in the same thing. Continuations. To quote a python discussion list thread (http://mail.python.org/pipermail/python-dev/1999-July/000467.html) "Like a goto, this(continuation) is as low-level as it gets, and even hard-core continuation fans don’t use them directly except as a means to implement better-behaved abstractions."
 
What could be these better behaved abstractions?
Coroutines, Iterators, Closures etc.
 
So continuations are more language designers, compiler / interpretter / parser writers to worry about. Let us move on
 
Coroutines
In Traditional program structure there is one main routine which calls subroutine(s) to accomplish a task. When a main routine calls a  subroutine, the sub routine executes starting from the beginning (no matter how many times we call it). Once the sub routine is done it pops  the locals out of the stack and pushes the return value on to the stack and the main routine begins executing from where it left off.
 
Step 1: In a coroutine model coroutine (a) executes some stuff calls another coroutine (b) which does some other stuff and calls the original coroutine (a).
Step 2: The original coroutine (a) continues from where it left off and does something useful again. If the original coroutine (a) calls the other coroutine (b) again, the execution continues in the other coroutine (b) from where it left off in step 1.
 
In other words each coroutine acts as if it is the main routine. The main routine – sub routine model is a master (main) – slave (sub routines) model . The coroutine – coroutine model is a peer – peer model.
 
Where are coroutines useful?
The traditional producer consumer problem. The producer produces an entity which the consumer consumes. The producer and consumer themselves can be expressed a separate coroutines. In an environment without threads this could be handy. Coroutine 1: read input coroutine 2: process input and return to coroutine 1 and so on…
 
Iterators:
Iterators are one place where this suspend resume model will be helpful a lot. Let us see a simple example in C#
public class Person {
 private ArrayList friends;
 public Person() {
  friends = new ArrayList();
 }
 public void AddFriend(Person friend) {
  friends.Add(friend);
 }
 public void RemoveFriend(Person friend) {
  friends.Remove(friend);
 }
 public IEnumerable<Person> Friends {
  foreach(Person friend in friends) {
   yield return friend;
  } 
 }
}
public class Program {
 public static void Main(string[]  args) {
  Person sendhil = new Person();
  sendhil.AddFriend("Hitesh");
  sendhil.AddFriend("Prakash");
  sendhil.AddFriend("Sridhar");
  sendhil.AddFriend("Manu");
  foreach(Person friend in sendhil.Friends) {
   // Do something
  }
 }
}
No one would ever write such a program, may be they’ll just expose the ArrayList’s IEnumerable / IEnumerator evil twin. Anyways this is just to demonstrate the use of iterators. At the yeild return key word the execution state of the program is saved (this is all compiler magic) and the call returns to the caller (Main function). When the next iteration starts the execution resumes in where it left off early. In trivial
examples this seems like syntactic sugar. But as the data structure to iterate gets complex the iterators are really useful.
 
Generators:
Sequence generators can be implemented using the yield return statements. For an example see Don’s blog entry (a fibonacci  example using iterators is there). http://pluralsight.com/blogs/dbox/archive/2005/04/17/7467.aspx
 
Closures:
http://www.intertwingly.net/blog/2005/04/18/Blocks-for-Box
http://www.martinfowler.com/bliki/Closure.html
The above entries describe closures in a nice way. To quote Sam the following statement describes the power of closures. "The lock example above is a specific example whereby the language designers had enough foresight to build a similar feature into the language.  In Ruby, such features need not be a part of the language, as you can build your own." C# Using block is another one which i can think of. Rather than having a static language with these features built in wouldn’t it be better if you work in a language that gives you power and
flexibility to do it yourself. I have started liking dynamic languages.languages.
 
The entry is open for discussions using comments 🙂
Advertisements
  1. Bi Cheng
    December 18, 2006 at 4:52 am

    I’m Chinese . JAVAA?

  2. Sendhil Kumar
    December 18, 2006 at 4:06 pm

    Hmm… My expertise on Java is no good :).
    The problem with these features is that most of them are explained using one of the dynamic languages like perl, python or ruby. That’s reason i learnt ruby. If you really want to understand these learn one of the truly dynamic languages. IMHO, it will help in the future as Java, C# everything is moving towards being dynamic (or they are trying to mimic using some neat tricks atleast).
     
     

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: