Sunday, April 25, 2004

Iterators in Ruby (Part - 1)

Warming up to using Iterators (Part 2)
< I am yet to write a part 3 >
SICP, Fiber api and ITERATORS ! (Part 4)

 

I had a look at the implementation of iterators in C#. What follows is based on code generator I have seen on the C# Whidbey post PDC release. Things might have changed by now as things are moving to technology preview phase.

 

This is example code that is present in MSDN:

 

// yield-example.cs

using System;

using System.Collections;

public class List

{

    public static IEnumerable Power(int number, int exponent)

    {

        int counter =0;

        int result = 1;

        while(counter++ < exponent)

        {

            result = result * number;

            yield result;

        }

    }

 

    static void Main()

    {

        // Display powers of 2 up to the exponent 8:

        foreach(int i in Power(2, 8))

            Console.Write("{0} ", i);

    }

}

 

Notice the introduction of a nice little ‘yield’ keyword? The behavior of C# iterators in this context is a lot like ruby iterators that I have been talking about in previous articles. Knowing a little about the state management requirements for iterators and the fact that the CLR is stack based, how are iterators implemented in C#?

 

The implementation of iterators in C# is not driven by the CLR in any way, it is completely implemented in the language as a compiler construct.

 

Let me explain what the compiler tries to do – the compiler examines the function that does the yield

 

    public static IEnumerable Power(int number, int exponent)

    {

        int counter =0;

        int result = 1;

        while(counter++ < exponent)

        {

            result = result * number;

            yield result;

        }

    }

 

Lets just ignore the yield statement for now and look at the method as thought it contained only a loop. It would basically look like this:

 

    public static IEnumerable Power(int number, int exponent)

    {

        [initial code]

        while([loop condition])

        {

            [loop body]

        }

        [post loop code]

    }

 

This is then generated into a sequence of IL statement blocks that have the following jumps between them:

 

 

Now, what yield would require is that the method exit at each point a yield statement occurs. The next time the method is invoked, execution continues immediately past the yield statement with all variables preserving their values.

 

In the CLR, when a method returns its stack frame is torn down. So there is no way that the local variables can actually preserve state. The solution taken by the C# team is turn the method that implements the yield statement into a class.

 

Such a class would

 

·         Have all local variables of the method as members of the class

·         Have a special variable that hold the value that is being yielded.

·         Have a special variable to indicate where the method should continue from, the next time it is invoked.

 

When the caller of such a method runs and encounters the foreach loop that invokes the iterator an object of this class gets created. This object is maintained as long as the foreach lop is running. When the loop exits the object is disposed.

 

That’s how iterators are implemented in C#. :)

 

Now here are some details:

 

 

The method that implements the iterators generates not one but two classes. Both the classes are generated as nested/inner classes to the class that contains the method. The classes are named as
(method name)$(number )_IEnumerableImpl
(method name)$(number)_IEnumeratorImpl

 

I am not sure about the exact reasoning behind the generation of two classes. The earlier standard for writing enumerators in C# probably required, but from the standpoint of implementing iterators, I don’t understand the need.

 

The first of these, the IEnumerableImpl simply creates an instance of the second class and returns it to the caller.

 

The second class IEnumeratorImpl is the interesting one. This class has data members for all the local variables as well as our two special data members.

 

Compare the data members (the cyan colored diamond shapes) to the original  local variables of the method.

 

    public static IEnumerable Power(int number, int exponent)

    {

        int counter =0;

        int result = 1;

        while(counter++ < exponent)

        {

            result = result * number;

            yield result;

        }

    }

 

The parameters number and exponent are there as such and the local variables counter and result are there with some name mangling (I would expect this is to avoid clashes with duplicate names in nested scopes, though that is not allowed in C# (duh?)).

 

The two new members on the class are

·         $PC

·         $_current

 

$_current is the member that holds the yielded value. In the case of the above method, $_current holds the value of ‘result’. It is an ‘object’ type for there will be a nice boxing and gc overhead when moving around an int type – I don’t know why something was not done for special casing value types.

 

$PC is the interesting variable. Remember our little diagram above that showed execution through IL. In the case of the iterators, the method does not simply execute in a loop like shown there, but executes one iteration of the loop on each call. The $PC is the variable that keeps track of where the code should jump to, the next time the method is called. Understandably $PC is someone idea of program counter ;)

 

The code method called MoveNext() in the class actually does the work that the method power() originally did. This is what is look like in IL code.

 

 

Sorry I am not very good with diagrams, but if you look at it you will see that the code is simply built for repeated invocation. Each time according to $PC the code braches to a new location and executes. It then sets the value of $PC to a new location of entry before the function exits.

 

In C# the yielded value is assigned to the $_current member variable and the MoveNext() itself exits by returning a true or false. A true indicates that the method returned through a yield and the false indicates that the method has completed execution. Subsequent calls to the method, after it has returned false will simply cause the method to return false and the $_current will not be updated.

 

So how does the caller of an iterative method behave? In this case its the main. The  caller simply does the following –

 

Invoke Power$00000000__IEnumerableImpl. GetEnumerator() to get an instance of Power$00000000__IEnumeratorImpl

 

Invoke Power$00000000__IEnumeratorImpl.MoveNext()

 

If result is true, use invoke Power$00000000__IEnumeratorImpl.get_Current() which will return the $_current. The foreach loop will cause the MoveNext() to be invoked again after the reurned value is consumed.

 

If result is false, break out of foreach loop.

 

After the loop breaks out the instance of Power$00000000__IEnumeratorImpl is dispose and is available for garbage collection. 

 

I am looking forward to the beta preview to see f things have changed. There is a lot of rather redundant code generated by the compiler here that I have not mentioned. When you are reading IL you might want to skip over those parts.

 

Probably in the future the CLR will contain constructs that enable true iterators and closures. Present day processors don’t natively support such constructs and so implementation will have to be hacks on the C stack or using some kind of class-object mechanism like shown here.

 

As a foot note I would like to mention that the Python also implements iterators in a manner similar to C#. There the function that yields is also converted into a class that maintains state. I believe the MoveNext() equivalent in Python is simply next(). Python however raises an exception to signal end of iteration. C# uses a Boolean return value to indicate this.

 

If this topic holds your interest then I recommend reading:

 

Coroutines in C
by Simon Tatham

 

C# 2.0 Create Elegant Code with Anonymous Methods, Iterators, and Partial Classes
by Juval Lowy (MSDN Mag)

 

Charming Python: Iterators and simple generators - New constructs in Python 2.2
by David Mertz (developerWorks)

Sunday, April 25, 2004 6:16:33 AM (Eastern Standard Time, UTC-05:00)  #    Comments [7]  | 
 Friday, April 23, 2004

There is Dylan playing somewhere in my head, and some things feel crushed:

 

Though I know that evenin's empire has returned into sand,

Vanished from my hand,

Left me blindly here to stand but still not sleeping.

My weariness amazes me, I'm branded on my feet,

I have no one to meet

And the ancient empty street's too dead for dreaming.

(Tambourine Man)

 

Have you ever listened to Dylan? Actually heard the visions of what could have been move by you? Probably not, not many people like to listen.

 

Then take me disappearin' through the smoke rings of my mind,

Down the foggy ruins of time, far past the frozen leaves,

The haunted, frightened trees, out to the windy beach,

Far from the twisted reach of crazy sorrow.

Yes, to dance beneath the diamond sky with one hand waving free,

Silhouetted by the sea, circled by the circus sands,

With all memory and fate driven deep beneath the waves,

Let me forget about today until tomorrow.

 

Hey! Mr. Tambourine Man, play a song for me,

I'm not sleepy and there is no place I'm going to.

Hey! Mr. Tambourine Man, play a song for me,

In the jingle jangle morning I'll come followin' you.

 

Sometimes, the closed world of the bit and baud seems to be the only reality that matters and somewhere it cajoles you into believing in a certain brotherhood of those who seem to understand it. And then again sometimes not.

 

And do you listen to Simon and Garfunkel?

 

When you're down and out, When you're on the street
When evening falls so hard, I will comfort you
I'll take your part, when darkness comes
and pain is all around,
Like a bridge over troubled water, I will lay me down
Like a bridge over troubled water, I will lay me down

(Bridge over Troubled Waters)

Friday, April 23, 2004 2:17:13 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Thursday, April 22, 2004

I downloaded and tried the new programming language Groovy today. In short groovy is like having Ruby on JVM. Maybe only better, because, it now has the power of the whole JVM to leverage. This is the homepage:

http://groovy.codehaus.org

 

 

The language is a stunner.

 

There is a lot of neat language design going on here.

http://wiki.codehaus.org/groovy/BlocksAndClosures

Imagine something like Ruby actually being available to code JSP, beans and what not in the Java world.

 

Being from the .Net background, I wish this was being done for the CLR. Imagine the power to the multi language support of the CLR brought into something like Ruby. For now I am content with gaping at features like this:

 

def counter(a)

{

      c = a;

      x = {c +=1; c};

      x

}

 

a_counter = counter(0)

b_counter = counter(20)

 

println(a_counter())

println(b_counter())

println(a_counter())

println(a_counter())

println(b_counter())

 

This actually works. Real closures!
If you are a lost C or VB soul, what is happening is that the function/method called counter() creates and returns a closure called x. A closure is a block of code that maintains state and scope based access to its variables. So closure x has the maintains state and has access to the variables of the method counter().

a_counter and b_counter are instance of the closure in the counter() method, that live after the invocations to the counter() method has exited. You can see that state is maintained between calls as the value of ‘c’ is incremented in each successive call.  

 

This is way ahead of languages like C# which are just grappling with their implementation of yield. This is of course not to blame the C# team, because admittedly the concept of programming with closures is yet to hit ‘the masses’

 

Groovy seems to do a whole pile of exciting things that Ruby can do

·         Closures

·         Iterators and Blocks

·         Regular expressions

·         Flexible collection types

·         Dynamic Method Invocations and types

I haven’t seen any mention of continuations, extendible classes, mixins and the like yet.

 

Of course, being on the JVM is slow and implementing a lot of features like the ones above, accounts for expensive constructs, which make the language even slower. However for most scripting language speeds, it should be acceptable.

 

What I think is more important is that languages of Ruby stature are being implemented on popular OO virtual machines. This is a sign for a possible trend in the future – a good one. It will be interesting times ahead when we have dynamic languages and functional languages move onto popular VMs.

 

I really like C and I think that simplicity is a feature (EricGu), however there is a real wealth of possibilities to be gleaned if constructs that have long been available only to students and researchers actually hit popular programming.

 

I am excited about the possibilities of a Ruby like implementation under .Net. Python is already getting there with Jim Hugunin and his IronPython.

 

Here are the folk behind Groovy:

http://groovy.codehaus.org/team-list.html

 

If you enjoy programming in Ruby or in a language that supports lists, iterators, closures etc, you might enjoy Groovy. It is still under development, so there might be things that are missing. You will also have to get the JVM.

 

Thursday, April 22, 2004 3:09:35 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Wednesday, April 21, 2004

This is a Wish List for Ruby. Ruby is an excellent language, however here are some small things that I would like to see added to Ruby:

 

  • Threading
    I wish ruby had real threads. The threading support currently provided is really sad. If Rite could actually have OS threads as Ruby threads, like in the .Net framework it would be awesome, instead of doing them as interpreter threads. Write now doing any sort of meaningful multithreaded application in ruby is meaningless.

  • C/C++ style operators
    I wish ruby had ++, -- operators. They really do not contribute to unmanageable code and on the whole are nice things to have.
  • Use of Curly Braces { }
    I wish that Ruby would let the usage of curly braces to define blocks of code other than just parameter blocks that receive yield results. I would like to use {} to enclose methods, classes, if statements, loops etc.

    Write now code that is written like:

    def func(a)
       [1,2,3].each {|n|
          if(n % 2 == 0)
             print “This is even”
           else
             print “Odd”
             print “Multiple of 3” if (n%3==0)
           end
       }
    end


    being very C-ish in my ways I would really like it if I could avoid all those clumsy ends.

    def func(a) {
      [1,2,3].each {|n|
        if(n%2 == 0)
          print “This is even”
         else {
             print “Odd”
             print “Multiple of 3” if (n%3==0)
         }
      }
    }

     
    These days since the Python bug has bitten a bit, I am warming up to the idea of scope by indentation.

    def func(a)
      [1,2,3].each |n|
        if(n%2 == 0)
          print “This is even”
         else
             print “Odd”
             print “Multiple of 3” if (n%3==0)

    This actually looks quiet nice, but it may not be a good think to have because such code often tends to get messed up real bad when you copy paste it around and spoils the indentation.


  • Better Win32Ole libraries
    This is something that I must have. I use scripting to be able to talk to WMI (Windows Management Instrumentation).

    The libraries that Ruby ship for this is really sad. Very unstable. At the time of this writing the current Ruby distribution has removed the win32ole libraries from Ruby. I hope they will come back, stabler.

    The reason why Win32Ole is important to me is that it is the mechanism used to talk to WMI and WMI can let you some really awesome stuff.

    WMI Primer on MSDN

  • Auto Initialization of variables
    When I write code like this

    sum = 0
    10.times{|n| sum = sum + n }


    I wish I need not have to initialize ‘sum’. I wish there was some unambiguous way of saying that ‘I know sum hasn’t been defined before, so please use its initial value as ’. I would just like to be able to say 10.times {|n| sum = sum + n } and things should just work, assuming that sum gets initialized as 0. I wish there was some shorthand hand initializing a variable for its first appearance in an expression.

    Like I could probably replace:

    sum  = 0
    prod = 1
    10.times {|n| sum = sum + n; prod = prod * n }

    with

    10.times {|n| sum = sum<0> + n; prod = prod<1> + n; }

    or better if I had support for C++ style operators, I could write

    10.times{|n| sum<0> += n; prod<1> *= n; }


  •  Run on .Net
    I wish ruby could run on .Net. There are python variants that run on Java and now Python is coming up for .Net (
    IronPython). Imagine the power of having the flexibility of Ruby with the power and expanse of the .Net framework.

    Maybe more work needs to be done before this is possible.

  •  Currying of Methods and Partial Evaluations
    I wish I could have currying/partial evaluation possible for ruby methods.
    In many functional languages, functions are defined like this:

    - fn add x y = x + y
    > int -> int -> int

    Consider the ML like code above. The first line I have defines a function called ‘add’ that takes x and y and does x+y. The second line is what the interpreter echoes back to me about the function.

    It is simply is trying to say that the method consumes two integers and produces an integer. The two integers how ever are not used up at one go, rather, they are used up sequentially. First the integer x is taken and bound to the function and then the value y.

    By being able to do that, we can define other function instances of add that have one of the variables bound.

    - fn add10 = add 10
    - fn add5 = add 5
    - add10 2
    > 12
    - add5 2
    > 7

    This shows off some very powerful features of what currying can do. Here add10 and add5 are created as new functions, but with the value of x substituted as 10 and 5 respectively. Now we can treat add10 and add5 as proper functions that take only one parameter. 


    What these languages let us do is that we can apply a subset of the parameters of a function and created a curried or partially evaluated function instance. Such an instance can, if the runtime is optimizing enough, already do all the processes possible in the code upfront. Whenever the remaining parameters are supplied, it could just go on to complete the operations.  

Imagine that the method we were calling is this

fn mult x y = 10 * x * y

and then we wish to do


mult 10 2

mult 10 3

mult 10 4

 

These calls will now cause it to do 10 * 10 * 2, 10 * 10 * 3 and 10 * 10 * 4

However if we could partially evaluate a function we could say

 

fn mult10 = mult 10
mult10 2

mult10 3

mult10 4

 

When mult10 is created it is already evaluated to being “100 * y”. So, subsequent calls would cause it to do only 100 * 2, 100 * 3 and 100 * 4.

 

To add this sort of support to Ruby will have to bring large changes to the language. A simpler implementation would be to create a method object (yes that’s possible in Ruby) and also a hash of the partial list of parameters. The call itself could be formally executed only when all formal parameters are satisfied by the parameter hash table collection.

 

If you are still reading this might interest you:

http://www.svendtofte.com/code/curried_javascript/

 

Whew!

Well, that’s about it for now. But as you can see most of what I am asking for here are simple things and superficial changes. I would however really like to see the win32ole, threads and ++ operators in Ruby, even if none of the others work out.

 

Matz, (Yukihiro Matsumoto), the creator of Ruby is planning to introduce some significant changes to the language and more importantly going to get it running off a formal virtual machine that he is writing for Ruby called Rite.

Here are some of the plans for Rite and Ruby:

http://www.rubygarden.org/ruby?Rite

 

I found this on one of the websites, this is about how Matz wanted to work on Rite:

 

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/76588
|* will Rite be developed publicly.. Or will you keep it souce secret?

From my experience and observation, an open source software needs to

have running code before the ball rolling to success.  I think I need to work alone until the first running version.

 

|* still use Ruby license scheme?

It will be open source software for sure.  License terms may be

changed.

 

|* do you need help?  Say what we should do and we will do it :-)

This is very important.  Listen carefully.

 

From the reason I stated above, I feel like I will work alone.

But if someone shows his talent, and comes up with his own _good_

implementation of new Ruby earlier than me, and if he is willing to

contribute his code, and if he allows me to hack and chop his code to

make it "Rite", I will name it "Rite".  And he will be honored for ever.

Wednesday, April 21, 2004 4:21:08 AM (Eastern Standard Time, UTC-05:00)  #    Comments [1]  | 
 Tuesday, April 20, 2004

An old Time magazine article on Bill Gates:
In Search of the Real Bill Gates

http://www.time.com/time/gates/cover0.html

 

A write up on Ruby by Matz himself:
The Ruby Programming Language

http://www.informit.com/articles/article.asp?p=18225&seqNum=2
The following is the outcome of a simple longest-word search program over
      /usr/share/dict/words (409067 bytes). These were tested on my Pentium-200MHz
      Linux machine.

Program

Lines

Seconds

Ruby

14

1.046

Perl

15

0.593

Python

16

5.001

As stated before, Ruby is a bit slower than Perl because of the overhead
      for method searching; however, it's much faster than Python.

 

 

Groovy programming language, reputed to be a lot Ruby like:
http://groovy.codehaus.org/

Groovy is a new agile dynamic language for the JVM combining lots of great features from languages like Python, Ruby and Smalltalk and making them available to the Java developers using a Java-like syntax.

(Groovy Entry)

 

Codehaus

Finally a project site that encourages the need to commercially use projects

http://codehaus.org/

The Codehaus differentiates itself from other similar efforts in several ways. The Codehaus places a firm priority on the production of useful code, and less on non-coding exercises such as voting, committee-forming and proposal-writing. Each project is provided autonomy to organize as it wishes and to address its own customer concerns and requirements directly. Codehaus is not entirely open to any and all projects. Projects must be sponsored or introduced through an informal manner by an existing haus-member and deemed to be "interesting".

 

Codehaus aims to support commercially useful projects, and thus does not sponsor or assist with projects licensed under the GPL or other business-hostile licenses.

 

 

Structure and Interpretation of Computer Programs (SICP)

If you are a fresher or are getting started on programming, or like thinking about programming I highly recommend reading the SICP.

http://mitpress.mit.edu/sicp/

"I think that it's extraordinarily important that we in computer science keep fun in computing. When it started out, it was an awful lot of fun. Of course, the paying customers got shafted every now and then, and after a while we began to take their complaints seriously. We began to feel as if we really were responsible for the successful, error-free perfect use of these machines. I don't think we are. I think we're responsible for stretching them, setting them off in new directions, and keeping fun in the house. I hope the field of computer science never loses its sense of fun. Above all, I hope we don't become missionaries. Don't feel as if you're Bible salesmen. The world has too many of those already. What you know about computing other people will learn. Don't feel as if the key to successful computing is only in your hands. What's in your hands, I think and hope, is intelligence: the ability to see the machine as more than when you were first led up to it, that you can make it more."

 

Alan J. Perlis (April 1, 1922-February 7, 1990)

Tuesday, April 20, 2004 7:56:35 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Monday, April 19, 2004

Last night we did it again.

We went for this movie (50 First Dates) and came home feeling a little giddish. I was feeling a little giddish before the movie after nearly having my head ripped off sitting on a Torra Torra, in a fair in Bangalore.

 

So after the movie and the drive back home, what do we decide to do, like the nice normal people we are? We decide that we need to drink coffee at 12am and discuss programming. So we head off to Leela Palace where there is a late night Barista.

 

Something about the way coffee affects my head, when drunk late at night, especially after a movie needs some investigation. Sidharth was my comrade is arms, or rather comrade in coffee. So what do we do? we go there and sit down and drink coffee and I start off on SICP (Structure and Interpretation of Computer Programs) which I have been postponing for several years now.

 

I think part of why I was so adamant about starting out on SICP in the middle of the night is that I feel life (like usual) isn’t going anywhere. It turns out that a lot of smart people at various Universities decided that I was wasn’t smart enough to warrant a formal higher education in Computer Science and the place I want to be the most, doesn’t seem to want me around because of some technicality (for the fifth time). So since life wasn’t going anywhere, I figured I’d just have teach myself the things I want to know, my own way.

 

A little fast-forward in time and what finally ends up happening is that Sidharth and I end up talking about a certain MSDN article.

Implementing Coroutines for .NET by Wrapping the Unmanaged Fiber API

http://msdn.microsoft.com/msdnmag/issues/03/09/CoroutinesinNET/default.aspx

We ended up in a rather (heated) philosophic discussion about how iterators could be implemented, till 4am, which is what this blog entry is about.

 

If you have been reading about iterators in my previous blog entries

Iterators in Ruby (Part - 1)

Warming up to using Iterators (Part 2)

Then the idea is probably growing on you already. What Sidharth and I did is put in some thinking about how iterators could be implemented. This entry is going to break the logical flow of these two articles, but I am letting it be. I will probably have a part 3 post that will bridge the gap between Parts 1 and 2 and what I am going to say here about iterators.

Also, like a lot of things on this blog, I am not an authority on the subject so I am just guessing at how these things actually work.

 

 

Iterators

The thing about iterators is that there are two functions involved that have to maintain execution state at the same time. So example when a function calls another function, the caller is frozen and the callee executes – so the caller maintains execution state during the run time of the callee.

 

def callee

      yield 1

      yield 2

      yield 3

end

 

def caller

      callee { |n|

#parameter block to the iterator

puts n
}

end

 

When the callee is an iterator, the control actual leaves the callee and returns to the caller, when the execution is in the parameter block of the iterator. However we don’t see this sort of behavior in a normal C stack. Why? because when a function on the C stack returns to the caller, the function’s activation record on the stack is destroyed.

 

How do we do this?

The approach in the MSDN article uses an API called the fiber API.

 

Fiber Approach

The fibers can the thought of as threads that don’t have the scheduler attached to them.  So unless a fiber is explicitly passed control it will not be executed, unlike a thread which is invoked by scheduler for a time slice.

 

What Ajai Shankar (the author of the MSDN article) does is use fibers to represent iterators. So in the above snippet, the function callee() would actually execute on a different fiber from  caller. So when control needs to shift to the parameter block, which is to be executed in the caller() function, a fiber is a switch occurs.

 

When the parameter has finished execution a context switch occurs again.

 

What further happens is that the author has wrapped up all this dirty jumping around into a managed C++ class that invokes the OS api. He then goes onto write C# code (really!) that uses yield, almost the same way Ruby would use it.

 

(pasted)

class CorIter {

    public void Next() {

        object[] array = new object[] {1, 2, 3, 4};

        for(int ndx = 0; true; ++ndx)

            Yield(arr[ndx]);

    }

}

 

If you get the general idea, then lets move on.

 

The problems with using the fiber API, among other problems, are

·         Every fiber is like a thread, which means that the more the iterators the more the number of fiber specific stack frames and such that get created – which means  more the code bloat for code like this.

·         Using the fiber api actually makes this a very OS specific solution – other OSes that the CLR may wish to target may not have provisions for building up such an API.

·         Exceptions: exceptions in the windows world are strung to the TLS (Thread Local Storage) of the thread of execution – this may behave rather odd when fibers are mixed into the picture.

 

Let ignore everything and just examine the first problem, the issue of creating separate stack frames per fiber and thus bloating the system – if we could solve this one, then I think (and I might be wrong), would bring more credit to this approach.

 

Wrapping State in a Caller Object

One other approach to supporting iterators is to ensure that one of the two functions (the caller or the callee) maintain state using some mechanism other than the C stack.

 

Lets take a look at the caller:

 

def caller

      callee { |n|

            puts n

      }

end

 

or maybe a C# equivalent.

 

void caller()
{

      foreach(int n in callee())

      {

            Console.WriteLine(n);

      }

}

 

This method can actually be though off as consisting of three parts

 

void caller()
{

     

      foreach(int n in callee())

      {

           

            Console.WriteLine(n);

      }

     

}

 

We could create an object to hold the state of the function that would hold these three parts. Something like this:

 

class caller_object

{

      //declare all local variable so the class as member variables here

      void do_part1()

      {

}

 

void do_codeblock() //part 2

{
}

 

void do_part3()

{

}

}

 

The idea is that we create an object that has member variables that represent the local variable of the caller.  So we execute the caller as three parts

 

void caller()

{

      caller_object co = new caller_object()

      co.do_part1();

      callee(co);

      co.do_part3();

}

 

The caller method now is simply a wrapper around the class that represents the caller function as an object. When the method do_part1() is called on the class, the object will have the same state as the original caller() function when it has just run till the point where the iterator is invoked.

 

Then the callee() is invoked and the object that represents the caller’s state is passed to the callee. The callee then goes on to invoke the object’s do_codeblock() every time a yield is required.

 

Since the callee never returns till it has completed execution it maintains state on the runtime stack, like a normal function. The do_codeblock() has the same code that the code block of the for each loop had and it can also maintain any state changes into the object. Finally when the callee() exits the object’s do_part3() is invoked.

 

This is similar to what the iterators accomplish. Here the state is stored in an object and not on the stack. However, here a full managed type that represents that caller has to be created. I didn’t like that too much.

 

Wrapping State in a Callee Object

This is similar to the above approach, except that roles are reversed. We create an object that can represent the callee. The callee then returns to the caller at every yield statement.

 

The callee state is maintained in the object representing it. There is an excellent write up you can read about a similar approach here:

Coroutines in C

http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html

 

The idea there is that the state of the function is retained in a state variable. The state variable is used to jump back to the point where the function had previously yielded from. Code would look a little like this:

 

(pasted)

int function(void) {

    static int i, state = 0;

    switch (state) {

        case 0: /* start of function */

        for (i = 0; i < 10; i++) {

            state = 1; /* so we will come back to "case 1" */

            return i;

            case 1: /* resume control straight after the return */

        }

    }

}

 

Now this example uses static variables but it is easy to imagine this being extended such that each variable is the member of some object.

 

(pasted)

It's a little bit ugly, because suddenly you have to use ctx->i as a loop counter where you would previously just have used i; virtually all your serious variables become elements of the coroutine context structure. But it removes the problems with re-entrancy, and still hasn't impacted the structure of the routine.

 

(Kudos to Pooja, for coming up with this idea at one sitting).

 

 

 

When C# announced the coming of iterators in the language and a new yield keyword, I was excited. In the mood of the MSN co-routines article, I had expected a CLR level support for iterators.

 

It turns out that the C# teams approach is similar to that of the saving the callee state in an object. (I am not very sure about whether its the caller or the callee, in case I am wrong in assuming that it’s the callee, which seems to be the more logical choice, I will blog about it).

 

In the Co-routines in C article, the author talks of writing macros that wraps up the behavior.  Since the compiler does the temporary object creation and hides all the mess from you, in the case of C#, it seems like a reasonable alternative.

 

 

A modified form of the Fiber API idea

The reason I don’t really like the way C# does iterators right now is because it is a hack. They did not want to change the CLR for a feature that may not catch on. So I guess, they used a less expensive approach. If I am wrong, I would like to be corrected. I would expect that more serious CLR level support will come up for iterators if the idea’s introduced in Whidbey C# become popular.

 

The other reason I don’t really like the approach, the real reason, is that the .Net type system is a fairly comprehensive type system designed to propagate an idea of types as a level playing field for language agnostic components to interact. Introducing a type into the system just to retain a function’s state does not seem consistent with this philosophy.

 

Fiber API on the other hand more naturally lend themselves to the way I would choose to think of iterators – as functions that can be frozen during execution and be continued.

 

Now this might seem like a weak argument, but it seems to better to use the processors abilities to do a context switch to actually freeze execution of a block of code, that write the code as code that manages members of an object (only for the purpose that the object can be used to retain the state of the code).

 <