C# iterators and suspend/resume in Simula 67

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Jiri Kripac

    C# iterators and suspend/resume in Simula 67

    Languages such as Simula 67 contain a general concept of coroutines that
    allow the execution of a method to be suspended without rolling back the
    stack and then later resumed at the same place as it has been suspended.

    The C# iterators seem to be a special case of this general suspend/resume
    concept. The "yield" statement suspends the execution of the current method
    and calling MoveNext() resumes it.

    I think it would be cleaner to introduce the general suspend/resume concept
    to C# and then implement C# iterators on top of this general foundation. The
    way C# iterators have been added to C# seems to be somewhat ad hoc; it is a
    very specific and distinct functionality that does not naturally blend with
    the rest of the language.

    Jiri


  • William Stacey [MVP]

    #2
    Re: C# iterators and suspend/resume in Simula 67

    Not sure I follow that. C# has a yield statement?
    I think if you want to schedule your own methods, you might look into
    Fibers.

    --
    William Stacey, MVP

    "Jiri Kripac" <jiri.kripac@au todesk.com> wrote in message
    news:uxm72i19DH A.3820@tk2msftn gp13.phx.gbl...[color=blue]
    > Languages such as Simula 67 contain a general concept of coroutines that
    > allow the execution of a method to be suspended without rolling back the
    > stack and then later resumed at the same place as it has been suspended.
    >
    > The C# iterators seem to be a special case of this general suspend/resume
    > concept. The "yield" statement suspends the execution of the current[/color]
    method[color=blue]
    > and calling MoveNext() resumes it.
    >
    > I think it would be cleaner to introduce the general suspend/resume[/color]
    concept[color=blue]
    > to C# and then implement C# iterators on top of this general foundation.[/color]
    The[color=blue]
    > way C# iterators have been added to C# seems to be somewhat ad hoc; it is[/color]
    a[color=blue]
    > very specific and distinct functionality that does not naturally blend[/color]
    with[color=blue]
    > the rest of the language.
    >
    > Jiri
    >
    >[/color]


    Comment

    • Jiri Kripac

      #3
      Re: C# iterators and suspend/resume in Simula 67

      "William Stacey [MVP]"[color=blue]
      > Not sure I follow that. C# has a yield statement?[/color]

      See the C# 2.0 spec.


      Comment

      • Daniel O'Connell [C# MVP]

        #4
        Re: C# iterators and suspend/resume in Simula 67


        "Jiri Kripac" <jiri.kripac@au todesk.com> wrote in message
        news:uxm72i19DH A.3820@tk2msftn gp13.phx.gbl...[color=blue]
        > Languages such as Simula 67 contain a general concept of coroutines that
        > allow the execution of a method to be suspended without rolling back the
        > stack and then later resumed at the same place as it has been suspended.
        >
        > The C# iterators seem to be a special case of this general suspend/resume
        > concept. The "yield" statement suspends the execution of the current
        > method
        > and calling MoveNext() resumes it.
        >
        > I think it would be cleaner to introduce the general suspend/resume
        > concept
        > to C# and then implement C# iterators on top of this general foundation.
        > The
        > way C# iterators have been added to C# seems to be somewhat ad hoc; it is
        > a
        > very specific and distinct functionality that does not naturally blend
        > with
        > the rest of the language.[/color]

        I've had the same opinion since I first read about iterators, however my
        main problem is finding a real use outside of iteration where coroutines
        would be of value and still be a clean solution. Is there a reason for
        it(and derived from that a reason for the added complexity) outside of
        iterating across a series of values that can't be solved in a cleaner manner
        using class state instead of method state?

        [color=blue]
        >
        > Jiri
        >
        >[/color]


        Comment

        • Matthew W. Jackson

          #5
          Re: C# iterators and suspend/resume in Simula 67

          > I've had the same opinion since I first read about iterators, however my[color=blue]
          > main problem is finding a real use outside of iteration where coroutines
          > would be of value and still be a clean solution. Is there a reason for
          > it(and derived from that a reason for the added complexity) outside of
          > iterating across a series of values that can't be solved in a cleaner[/color]
          manner[color=blue]
          > using class state instead of method state?[/color]

          I agree about the complexity being a big issue, especially since it looks
          like C# will basically convert your iterator method into a class that keeps
          track of the state.

          However, it might be handy for A.I. bots in a real-time game. If there were
          several bots, it wouldn't be wise to run each in its own thread. Fibers are
          a good solution, but since .NET doesn't support them natively, those are out
          in my book (the one implentation of Fibers on .NET that I have seen is very
          hackish).

          In this situation it would be nice to have co-routines. Rather than having
          to write lots of state-management code, you can think about the bots actions
          at a higher level. Basically, if this happens, do this. But each bot would
          get its share of the controlling thread's time, without the overhead of
          multithreading.

          Back to my first point. The added complexity isn't really needed, as
          coroutines could be simulated with C# 2.0 iterators. The controlling
          routine would just have to keep a list of IEnumerator objects and call
          MoveNext, using some sort of Scheduling algorithm. Depending on the
          situation, the iterators could return several different types of
          information, from a simple dummy value indicating that more processing is
          needed, to a time estimate to how much work is left remaining, or even a
          priority that changes dynamically. In a game, one might return some kind of
          Action object representing what the controlling routine should be doing for
          that entity, which it will perform automatically until the action is
          complete, at which point it will call MoveNext again to get the next action
          from the entity. Then the entity coroutine (implemented as an iterator)
          might look something like this.

          while(this.IsAl ive) {
          Entity[] enemies = World.GetVisibl eEnemies(this.L ocation);
          if(enemies.Leng th > 0) {
          yield new AttackAction(en emies[0]);
          }
          else if(health < 10) {
          Entity healthPickup = World.FindNeare stHealthPickup( this.Location);
          yield new MoveToAction(he althPickup.Loca tion);
          }
          else {
          yield new WanderAimlessly Action();
          }
          }
          return;

          (The yield new syntax could be made a bit cleaner with static methods...even
          cleaner if C# supported executing the yield statement outside the iterator
          method itself---which if I understand correctly it won't.)

          The scheduling routine's code might look yucky (as IEnumerators don't really
          help indicate that coroutines are being used), but this could probably be
          abstracted a bit. Still, I'm a bit worried about code bloat, if the C#
          compiler does in fact turn the iterator into a class that manages the state.

          Of course, I'm just speculating here. I have no idea if this will actually
          work. I hear that Python is good for things like this, so maybe I'll give
          it a try there until I can get my hands on C# 2.0.

          Anyway, there are other areas where coroutines would be helpful (mostly
          simulations, hence why they're useful in games), and I'm surprised that IL
          doesn't support them at some level---even if C# didn't have support for
          them---since it would make it easier for certain languages to target the
          runtime.

          Perhaps Jiri is right, a managed fiber/coroutine API is what is needed, with
          iterators implemented on top of that API. While I'm grateful that C# is
          getting iterators, I still kind of feel like it's just a compiler hack. I
          might feel a lot better about it with real support for coroutines in IL.

          Does anyone have any links to discussions on how C# iterators are actually
          implemented?

          --Matthew W. Jackson


          Comment

          • Daniel O'Connell [C# MVP]

            #6
            Re: C# iterators and suspend/resume in Simula 67


            "Matthew W. Jackson" <themuujAThotma ilDOTcom@NOSPAM .NOSPAM> wrote in message
            news:eA0sxF59DH A.1116@TK2MSFTN GP09.phx.gbl...[color=blue][color=green]
            >> I've had the same opinion since I first read about iterators, however my
            >> main problem is finding a real use outside of iteration where coroutines
            >> would be of value and still be a clean solution. Is there a reason for
            >> it(and derived from that a reason for the added complexity) outside of
            >> iterating across a series of values that can't be solved in a cleaner[/color]
            > manner[color=green]
            >> using class state instead of method state?[/color]
            >
            > I agree about the complexity being a big issue, especially since it looks
            > like C# will basically convert your iterator method into a class that
            > keeps
            > track of the state.
            >
            > However, it might be handy for A.I. bots in a real-time game. If there
            > were
            > several bots, it wouldn't be wise to run each in its own thread. Fibers
            > are
            > a good solution, but since .NET doesn't support them natively, those are
            > out
            > in my book (the one implentation of Fibers on .NET that I have seen is
            > very
            > hackish).
            >
            > In this situation it would be nice to have co-routines. Rather than
            > having
            > to write lots of state-management code, you can think about the bots
            > actions
            > at a higher level. Basically, if this happens, do this. But each bot
            > would
            > get its share of the controlling thread's time, without the overhead of
            > multithreading.
            >[/color]

            I see the point here, oddly this is basically iteration that you don't want
            to look like interation. It may be a sufficent reason however. It would be
            nice to have plain, non-iterator styled coroutines, something that doesn't
            require an extra class or anything, without requiring an enumerator.[color=blue]
            > Back to my first point. The added complexity isn't really needed, as
            > coroutines could be simulated with C# 2.0 iterators. The controlling
            > routine would just have to keep a list of IEnumerator objects and call
            > MoveNext, using some sort of Scheduling algorithm. Depending on the
            > situation, the iterators could return several different types of
            > information, from a simple dummy value indicating that more processing is
            > needed, to a time estimate to how much work is left remaining, or even a
            > priority that changes dynamically. In a game, one might return some kind
            > of
            > Action object representing what the controlling routine should be doing
            > for
            > that entity, which it will perform automatically until the action is
            > complete, at which point it will call MoveNext again to get the next
            > action
            > from the entity. Then the entity coroutine (implemented as an iterator)
            > might look something like this.
            >
            > while(this.IsAl ive) {
            > Entity[] enemies = World.GetVisibl eEnemies(this.L ocation);
            > if(enemies.Leng th > 0) {
            > yield new AttackAction(en emies[0]);
            > }
            > else if(health < 10) {
            > Entity healthPickup = World.FindNeare stHealthPickup( this.Location);
            > yield new MoveToAction(he althPickup.Loca tion);
            > }
            > else {
            > yield new WanderAimlessly Action();
            > }
            > }
            > return;
            >
            > (The yield new syntax could be made a bit cleaner with static
            > methods...even
            > cleaner if C# supported executing the yield statement outside the iterator
            > method itself---which if I understand correctly it won't.)[/color]

            What do you mean here? I am not entirely familiar with coroutines and don't
            think I've run across this concept.[color=blue]
            >
            > The scheduling routine's code might look yucky (as IEnumerators don't
            > really
            > help indicate that coroutines are being used), but this could probably be
            > abstracted a bit. Still, I'm a bit worried about code bloat, if the C#
            > compiler does in fact turn the iterator into a class that manages the
            > state.
            >
            > Of course, I'm just speculating here. I have no idea if this will
            > actually
            > work. I hear that Python is good for things like this, so maybe I'll give
            > it a try there until I can get my hands on C# 2.0.
            >
            > Anyway, there are other areas where coroutines would be helpful (mostly
            > simulations, hence why they're useful in games), and I'm surprised that IL
            > doesn't support them at some level---even if C# didn't have support for
            > them---since it would make it easier for certain languages to target the
            > runtime.
            >
            > Perhaps Jiri is right, a managed fiber/coroutine API is what is needed,
            > with
            > iterators implemented on top of that API. While I'm grateful that C# is
            > getting iterators, I still kind of feel like it's just a compiler hack. I
            > might feel a lot better about it with real support for coroutines in IL.
            >
            > Does anyone have any links to discussions on how C# iterators are actually
            > implemented?[/color]

            Using a quick scan across the mono code for iterators, it certaily appears
            to create a nested class that handles iteration, so a sort of
            psuedo-coroutines.

            A pure coroutine api would be nice, a fiber API is probably best left
            out(There is no guarentee that a managed Thread is actually a thread, it
            could be implemented as a fiber or a user thread(similar to fibers) in a
            given runtime. I'm not sure, realistically, what IL can do as far as
            coroutines go, but the Mono generation uses standard return and the
            contained class for state. This method should work(its how anonymous methods
            work as well, the only thing I am really worried about is how would security
            work in full coroutines, if the stack isn't maintained. The prolog for a
            routine would have to maintain security, complicating the language a bit(It
            wouldn't be particularly safe, IMHO, to change the security of a method
            already executing in part between calls, thats asking for obscure bugs).[color=blue]
            >
            > --Matthew W. Jackson
            >
            >[/color]


            Comment

            • Daniel O'Connell [C# MVP]

              #7
              Re: C# iterators and suspend/resume in Simula 67


              "Matthew W. Jackson" <themuujAThotma ilDOTcom@NOSPAM .NOSPAM> wrote in message
              news:eA0sxF59DH A.1116@TK2MSFTN GP09.phx.gbl...[color=blue][color=green]
              >> I've had the same opinion since I first read about iterators, however my
              >> main problem is finding a real use outside of iteration where coroutines
              >> would be of value and still be a clean solution. Is there a reason for
              >> it(and derived from that a reason for the added complexity) outside of
              >> iterating across a series of values that can't be solved in a cleaner[/color]
              > manner[color=green]
              >> using class state instead of method state?[/color]
              >
              > I agree about the complexity being a big issue, especially since it looks
              > like C# will basically convert your iterator method into a class that
              > keeps
              > track of the state.
              >
              > However, it might be handy for A.I. bots in a real-time game. If there
              > were
              > several bots, it wouldn't be wise to run each in its own thread. Fibers
              > are
              > a good solution, but since .NET doesn't support them natively, those are
              > out
              > in my book (the one implentation of Fibers on .NET that I have seen is
              > very
              > hackish).
              >
              > In this situation it would be nice to have co-routines. Rather than
              > having
              > to write lots of state-management code, you can think about the bots
              > actions
              > at a higher level. Basically, if this happens, do this. But each bot
              > would
              > get its share of the controlling thread's time, without the overhead of
              > multithreading.
              >[/color]

              I see the point here, oddly this is basically iteration that you don't want
              to look like interation. It may be a sufficent reason however. It would be
              nice to have plain, non-iterator styled coroutines, something that doesn't
              require an extra class or anything, without requiring an enumerator.[color=blue]
              > Back to my first point. The added complexity isn't really needed, as
              > coroutines could be simulated with C# 2.0 iterators. The controlling
              > routine would just have to keep a list of IEnumerator objects and call
              > MoveNext, using some sort of Scheduling algorithm. Depending on the
              > situation, the iterators could return several different types of
              > information, from a simple dummy value indicating that more processing is
              > needed, to a time estimate to how much work is left remaining, or even a
              > priority that changes dynamically. In a game, one might return some kind
              > of
              > Action object representing what the controlling routine should be doing
              > for
              > that entity, which it will perform automatically until the action is
              > complete, at which point it will call MoveNext again to get the next
              > action
              > from the entity. Then the entity coroutine (implemented as an iterator)
              > might look something like this.
              >
              > while(this.IsAl ive) {
              > Entity[] enemies = World.GetVisibl eEnemies(this.L ocation);
              > if(enemies.Leng th > 0) {
              > yield new AttackAction(en emies[0]);
              > }
              > else if(health < 10) {
              > Entity healthPickup = World.FindNeare stHealthPickup( this.Location);
              > yield new MoveToAction(he althPickup.Loca tion);
              > }
              > else {
              > yield new WanderAimlessly Action();
              > }
              > }
              > return;
              >
              > (The yield new syntax could be made a bit cleaner with static
              > methods...even
              > cleaner if C# supported executing the yield statement outside the iterator
              > method itself---which if I understand correctly it won't.)[/color]

              What do you mean here? I am not entirely familiar with coroutines and don't
              think I've run across this concept.[color=blue]
              >
              > The scheduling routine's code might look yucky (as IEnumerators don't
              > really
              > help indicate that coroutines are being used), but this could probably be
              > abstracted a bit. Still, I'm a bit worried about code bloat, if the C#
              > compiler does in fact turn the iterator into a class that manages the
              > state.
              >
              > Of course, I'm just speculating here. I have no idea if this will
              > actually
              > work. I hear that Python is good for things like this, so maybe I'll give
              > it a try there until I can get my hands on C# 2.0.
              >
              > Anyway, there are other areas where coroutines would be helpful (mostly
              > simulations, hence why they're useful in games), and I'm surprised that IL
              > doesn't support them at some level---even if C# didn't have support for
              > them---since it would make it easier for certain languages to target the
              > runtime.
              >
              > Perhaps Jiri is right, a managed fiber/coroutine API is what is needed,
              > with
              > iterators implemented on top of that API. While I'm grateful that C# is
              > getting iterators, I still kind of feel like it's just a compiler hack. I
              > might feel a lot better about it with real support for coroutines in IL.
              >
              > Does anyone have any links to discussions on how C# iterators are actually
              > implemented?[/color]

              Using a quick scan across the mono code for iterators, it certaily appears
              to create a nested class that handles iteration, so a sort of
              psuedo-coroutines.

              A pure coroutine api would be nice, a fiber API is probably best left
              out(There is no guarentee that a managed Thread is actually a thread, it
              could be implemented as a fiber or a user thread(similar to fibers) in a
              given runtime. I'm not sure, realistically, what IL can do as far as
              coroutines go, but the Mono generation uses standard return and the
              contained class for state. This method should work(its how anonymous methods
              work as well, the only thing I am really worried about is how would security
              work in full coroutines, if the stack isn't maintained. The prolog for a
              routine would have to maintain security, complicating the language a bit(It
              wouldn't be particularly safe, IMHO, to change the security of a method
              already executing in part between calls, thats asking for obscure bugs).[color=blue]
              >
              > --Matthew W. Jackson
              >
              >[/color]


              Comment

              • Matthew W. Jackson

                #8
                Re: C# iterators and suspend/resume in Simula 67

                > > (The yield new syntax could be made a bit cleaner with static[color=blue][color=green]
                > > methods...even
                > > cleaner if C# supported executing the yield statement outside the[/color][/color]
                iterator[color=blue][color=green]
                > > method itself---which if I understand correctly it won't.)[/color]
                >
                > What do you mean here? I am not entirely familiar with coroutines and[/color]
                don't[color=blue]
                > think I've run across this concept.[/color]

                (btw, ooops--Forgot the updated iterator syntax in my examples...not that it
                matters much).

                Oh, I was just saying that rather than doing a bunch of "yield return new
                MoveToCommand(p os);" it could be made to read better with a static method
                that returns a command, such as "yield return MoveTo(pos);", and if the
                yield could be fired in another method, then you could just simply to
                "MoveTo(pos );"--saving two keywords and improving readability a bit
                (although you will get no indication that execution will yield--so maybe
                it's not such a good idea).

                But the yield statement (as I understand) has to be in the iterator method,
                in order to make the job of the compiler MUCH easier--since these do seem to
                be compiled IEnumerable classes and not true fibers or coroutines.

                This also means that, given a binary tree class, one can not use a recursive
                method to traverse the tree. The following
                won't be legal:

                public IEnumerable InOrder {
                get {
                if(root != null) Iterate(root);
                yield break;
                }
                }

                public void Iterate(Node node) {
                if(node.Left != null) Iterate(left);
                yield return node.Value;
                if(node.Right != null) Iterate(right);
                }

                If this were legal, then iterating even the most complicated of data
                structures would be easy. However, since the "yield" cannot occur outside
                of your iterator method, it won't be as simple as that.

                Mind you, it will be easier to write with iterators in this case than it was
                with a separate Enumerator class, but not too much easier...You still need
                to use your own Stack to do the iteration efficiently. The only difference
                is the Stack is now a local variable and not a instance variable.

                I can't really think of a way to easily allow the iterator to be recursive
                without being build on top of fibers or coroutines. Maybe I'm missing
                something here. Maybe the compiler could determine which routines
                containing yield statemetns were called by an iterator and somehow figure
                out how to build the pseudo-call-stack for you. It would also mean that any
                routine containing a yield could not be called by a non-iterator method. In
                the end, it seems like it'd be more complicated than it is worth (especially
                when you take security into account).
                [color=blue]
                > Using a quick scan across the mono code for iterators, it certaily appears
                > to create a nested class that handles iteration, so a sort of
                > psuedo-coroutines.[/color]

                I had forgot that Mono already has these features in it (at least
                partially).

                I guess I should play around with my Mono install some more and see if my
                idea for using iterators to simulate true coroutines in a simulation will
                work well.
                [color=blue]
                > A pure coroutine api would be nice, a fiber API is probably best left
                > out(There is no guarentee that a managed Thread is actually a thread, it
                > could be implemented as a fiber or a user thread(similar to fibers) in a
                > given runtime.[/color]

                I forgot about that, too, but it makes sense, with Unix being fiber-based
                and not thread-based
                [color=blue]
                > I'm not sure, realistically, what IL can do as far as
                > coroutines go, but the Mono generation uses standard return and the
                > contained class for state. This method should work(its how anonymous[/color]
                methods[color=blue]
                > work as well, the only thing I am really worried about is how would[/color]
                security[color=blue]
                > work in full coroutines, if the stack isn't maintained.[/color]

                Yeap, I forgot this too. I tend to forget about code security when I think
                about features that IL should have implemented. Still, aren't there some
                languages that can't be fully supported in IL because of it's lack of
                coroutines? Or would all of those compilers have to do pseudo-coroutines as
                well? Then what about the previously mentioned problem of calling other
                methods from the coroutine?

                Or do .NET versions of these languages have to be restricted in what they
                support? Or maybe the compiler could make use of an unmanaged fiber API.
                But this brings up security issues again.

                I guess this is similar to the problem of getting SmallTalk to run on IL. I
                guess some language features have to be left out.
                [color=blue]
                > The prolog for a routine would have to maintain security, complicating
                > the language a bit(It wouldn't be particularly safe, IMHO, to change the
                > security of a method already executing in part between calls, thats asking
                > for obscure bugs).[/color]

                Right you are. I need to think about the problem some more.

                But for now I'm happy with the (proposed) implementation of iterators. It
                certainly makes it easier to provide multiple enumerators for a data type
                (such as reverse enumerators, enumerators that only travel through a subset
                of the items, etc.).

                Back to my example:
                After thinking about it, perhaps a better way to implement the problem in my
                example is as follows: (The bot-manager class would be in charge of
                checking the Action property after each MoveNext call.)

                class Bot : Entity {

                private IAction action;
                private int health;
                // etc.

                public IAction Action {
                get { return action; }
                }

                private void Attack(Entity entity) {
                action = new AttackAction(en tity);
                }

                private void MoveTo(Point location) {
                action = new MoveToAction(lo cation);
                }

                private void WanderAimlessly () {
                action = new WanderAimlessly Action();
                }

                // bool return value is a dummy, I suppose (I need to think about
                whether a value is really needed)
                // I don't suppose IEnumerable<Voi d> is possible .. ???
                public IEnumerable<boo l> Update {
                get {
                while(alive) {
                if(health < 10) {
                Entity healthPickup =
                World.FindNeare stHealthPickup( this.Location);
                MoveTo(healthPi ckup.Location);
                yield return true;
                }
                else {
                Entity[] enemies =
                World.GetVisibl eEnemies(this.L ocation);
                if(enemies.Leng th > 0) {
                Attack(enemies[0]);
                yield return true; // odd syntax, but it does the
                job I guess
                }
                else {
                WanderAimlessly ();
                yield return true;
                }
                }
                }
                yield break;
                }
                }

                }

                This is still pretty clean, and abstracts away a lot of the state
                management. It's a good example one of my favorite situations in
                programming---lots of messy ground work in order to make the higher-level
                code cleaner. I still wish the "yield return true" statement could be
                better....like I said, if non-iterator private-methods could yield, then
                that statement could go in MoveTo(), Attack(), and WanderAimlessly ();

                Maybe I just miss the pre-multitasking days of programming in DOS where you
                never had to worry about programming finite-state-machines all the time.
                *sigh*. These "problems" are even worse in games, and although threads can
                help, they often open a whole new can of worms.

                Now time to go play with Mono a bit... Maybe I can improve my
                implementation further. I'm curious to what the generated IEnumerable
                class's source will look like if I put really complicated logic into the
                iterator method.


                --Matthew W. Jackson


                Comment

                • Matthew W. Jackson

                  #9
                  Re: C# iterators and suspend/resume in Simula 67

                  > > (The yield new syntax could be made a bit cleaner with static[color=blue][color=green]
                  > > methods...even
                  > > cleaner if C# supported executing the yield statement outside the[/color][/color]
                  iterator[color=blue][color=green]
                  > > method itself---which if I understand correctly it won't.)[/color]
                  >
                  > What do you mean here? I am not entirely familiar with coroutines and[/color]
                  don't[color=blue]
                  > think I've run across this concept.[/color]

                  (btw, ooops--Forgot the updated iterator syntax in my examples...not that it
                  matters much).

                  Oh, I was just saying that rather than doing a bunch of "yield return new
                  MoveToCommand(p os);" it could be made to read better with a static method
                  that returns a command, such as "yield return MoveTo(pos);", and if the
                  yield could be fired in another method, then you could just simply to
                  "MoveTo(pos );"--saving two keywords and improving readability a bit
                  (although you will get no indication that execution will yield--so maybe
                  it's not such a good idea).

                  But the yield statement (as I understand) has to be in the iterator method,
                  in order to make the job of the compiler MUCH easier--since these do seem to
                  be compiled IEnumerable classes and not true fibers or coroutines.

                  This also means that, given a binary tree class, one can not use a recursive
                  method to traverse the tree. The following
                  won't be legal:

                  public IEnumerable InOrder {
                  get {
                  if(root != null) Iterate(root);
                  yield break;
                  }
                  }

                  public void Iterate(Node node) {
                  if(node.Left != null) Iterate(left);
                  yield return node.Value;
                  if(node.Right != null) Iterate(right);
                  }

                  If this were legal, then iterating even the most complicated of data
                  structures would be easy. However, since the "yield" cannot occur outside
                  of your iterator method, it won't be as simple as that.

                  Mind you, it will be easier to write with iterators in this case than it was
                  with a separate Enumerator class, but not too much easier...You still need
                  to use your own Stack to do the iteration efficiently. The only difference
                  is the Stack is now a local variable and not a instance variable.

                  I can't really think of a way to easily allow the iterator to be recursive
                  without being build on top of fibers or coroutines. Maybe I'm missing
                  something here. Maybe the compiler could determine which routines
                  containing yield statemetns were called by an iterator and somehow figure
                  out how to build the pseudo-call-stack for you. It would also mean that any
                  routine containing a yield could not be called by a non-iterator method. In
                  the end, it seems like it'd be more complicated than it is worth (especially
                  when you take security into account).
                  [color=blue]
                  > Using a quick scan across the mono code for iterators, it certaily appears
                  > to create a nested class that handles iteration, so a sort of
                  > psuedo-coroutines.[/color]

                  I had forgot that Mono already has these features in it (at least
                  partially).

                  I guess I should play around with my Mono install some more and see if my
                  idea for using iterators to simulate true coroutines in a simulation will
                  work well.
                  [color=blue]
                  > A pure coroutine api would be nice, a fiber API is probably best left
                  > out(There is no guarentee that a managed Thread is actually a thread, it
                  > could be implemented as a fiber or a user thread(similar to fibers) in a
                  > given runtime.[/color]

                  I forgot about that, too, but it makes sense, with Unix being fiber-based
                  and not thread-based
                  [color=blue]
                  > I'm not sure, realistically, what IL can do as far as
                  > coroutines go, but the Mono generation uses standard return and the
                  > contained class for state. This method should work(its how anonymous[/color]
                  methods[color=blue]
                  > work as well, the only thing I am really worried about is how would[/color]
                  security[color=blue]
                  > work in full coroutines, if the stack isn't maintained.[/color]

                  Yeap, I forgot this too. I tend to forget about code security when I think
                  about features that IL should have implemented. Still, aren't there some
                  languages that can't be fully supported in IL because of it's lack of
                  coroutines? Or would all of those compilers have to do pseudo-coroutines as
                  well? Then what about the previously mentioned problem of calling other
                  methods from the coroutine?

                  Or do .NET versions of these languages have to be restricted in what they
                  support? Or maybe the compiler could make use of an unmanaged fiber API.
                  But this brings up security issues again.

                  I guess this is similar to the problem of getting SmallTalk to run on IL. I
                  guess some language features have to be left out.
                  [color=blue]
                  > The prolog for a routine would have to maintain security, complicating
                  > the language a bit(It wouldn't be particularly safe, IMHO, to change the
                  > security of a method already executing in part between calls, thats asking
                  > for obscure bugs).[/color]

                  Right you are. I need to think about the problem some more.

                  But for now I'm happy with the (proposed) implementation of iterators. It
                  certainly makes it easier to provide multiple enumerators for a data type
                  (such as reverse enumerators, enumerators that only travel through a subset
                  of the items, etc.).

                  Back to my example:
                  After thinking about it, perhaps a better way to implement the problem in my
                  example is as follows: (The bot-manager class would be in charge of
                  checking the Action property after each MoveNext call.)

                  class Bot : Entity {

                  private IAction action;
                  private int health;
                  // etc.

                  public IAction Action {
                  get { return action; }
                  }

                  private void Attack(Entity entity) {
                  action = new AttackAction(en tity);
                  }

                  private void MoveTo(Point location) {
                  action = new MoveToAction(lo cation);
                  }

                  private void WanderAimlessly () {
                  action = new WanderAimlessly Action();
                  }

                  // bool return value is a dummy, I suppose (I need to think about
                  whether a value is really needed)
                  // I don't suppose IEnumerable<Voi d> is possible .. ???
                  public IEnumerable<boo l> Update {
                  get {
                  while(alive) {
                  if(health < 10) {
                  Entity healthPickup =
                  World.FindNeare stHealthPickup( this.Location);
                  MoveTo(healthPi ckup.Location);
                  yield return true;
                  }
                  else {
                  Entity[] enemies =
                  World.GetVisibl eEnemies(this.L ocation);
                  if(enemies.Leng th > 0) {
                  Attack(enemies[0]);
                  yield return true; // odd syntax, but it does the
                  job I guess
                  }
                  else {
                  WanderAimlessly ();
                  yield return true;
                  }
                  }
                  }
                  yield break;
                  }
                  }

                  }

                  This is still pretty clean, and abstracts away a lot of the state
                  management. It's a good example one of my favorite situations in
                  programming---lots of messy ground work in order to make the higher-level
                  code cleaner. I still wish the "yield return true" statement could be
                  better....like I said, if non-iterator private-methods could yield, then
                  that statement could go in MoveTo(), Attack(), and WanderAimlessly ();

                  Maybe I just miss the pre-multitasking days of programming in DOS where you
                  never had to worry about programming finite-state-machines all the time.
                  *sigh*. These "problems" are even worse in games, and although threads can
                  help, they often open a whole new can of worms.

                  Now time to go play with Mono a bit... Maybe I can improve my
                  implementation further. I'm curious to what the generated IEnumerable
                  class's source will look like if I put really complicated logic into the
                  iterator method.


                  --Matthew W. Jackson


                  Comment

                  • Daniel O'Connell [C# MVP]

                    #10
                    Re: C# iterators and suspend/resume in Simula 67


                    "Matthew W. Jackson" <themuujAThotma ilDOTcom@NOSPAM .NOSPAM> wrote in message
                    news:%232uAbgQ% 23DHA.2216@TK2M SFTNGP10.phx.gb l...[color=blue][color=green][color=darkred]
                    >> > (The yield new syntax could be made a bit cleaner with static
                    >> > methods...even
                    >> > cleaner if C# supported executing the yield statement outside the[/color][/color]
                    > iterator[color=green][color=darkred]
                    >> > method itself---which if I understand correctly it won't.)[/color]
                    >>
                    >> What do you mean here? I am not entirely familiar with coroutines and[/color]
                    > don't[color=green]
                    >> think I've run across this concept.[/color]
                    >
                    > (btw, ooops--Forgot the updated iterator syntax in my examples...not that
                    > it
                    > matters much).
                    >
                    > Oh, I was just saying that rather than doing a bunch of "yield return new
                    > MoveToCommand(p os);" it could be made to read better with a static method
                    > that returns a command, such as "yield return MoveTo(pos);", and if the
                    > yield could be fired in another method, then you could just simply to
                    > "MoveTo(pos );"--saving two keywords and improving readability a bit
                    > (although you will get no indication that execution will yield--so maybe
                    > it's not such a good idea).
                    >
                    > But the yield statement (as I understand) has to be in the iterator
                    > method,
                    > in order to make the job of the compiler MUCH easier--since these do seem
                    > to
                    > be compiled IEnumerable classes and not true fibers or coroutines.
                    >
                    > This also means that, given a binary tree class, one can not use a
                    > recursive
                    > method to traverse the tree. The following
                    > won't be legal:
                    >
                    > public IEnumerable InOrder {
                    > get {
                    > if(root != null) Iterate(root);
                    > yield break;
                    > }
                    > }
                    >
                    > public void Iterate(Node node) {
                    > if(node.Left != null) Iterate(left);
                    > yield return node.Value;
                    > if(node.Right != null) Iterate(right);
                    > }
                    >
                    > If this were legal, then iterating even the most complicated of data
                    > structures would be easy. However, since the "yield" cannot occur outside
                    > of your iterator method, it won't be as simple as that.
                    >
                    > Mind you, it will be easier to write with iterators in this case than it
                    > was
                    > with a separate Enumerator class, but not too much easier...You still need
                    > to use your own Stack to do the iteration efficiently. The only
                    > difference
                    > is the Stack is now a local variable and not a instance variable.
                    >
                    > I can't really think of a way to easily allow the iterator to be recursive
                    > without being build on top of fibers or coroutines. Maybe I'm missing
                    > something here. Maybe the compiler could determine which routines
                    > containing yield statemetns were called by an iterator and somehow figure
                    > out how to build the pseudo-call-stack for you. It would also mean that
                    > any
                    > routine containing a yield could not be called by a non-iterator method.
                    > In
                    > the end, it seems like it'd be more complicated than it is worth
                    > (especially
                    > when you take security into account).
                    >[/color]

                    Actually, from what I can tell, yield *defines* the iterator method, making
                    it entirely impossible to use it outside of the method you want as an
                    iterator.
                    Also, another issue I have is that the analysis of the flow to determine
                    where yields could occur is simply rather complex, if you consider virtuals
                    and other such things, it would be really tricky. A method may be to create
                    something like a iterator property or definition, more or less literally
                    designing a class but with the compiler still generating the state machine
                    and simply filling in pieces(enter, exit, etc), or even simply grouping
                    associated methods into one scope, using a defined entry point. The downside
                    of hte latter approach is you couldn't have reusable code(unless
                    complexities of iterator inheritance came into the picture...and I really
                    don't think the feature is worth the complexity of inheritance.)[color=blue][color=green]
                    >> Using a quick scan across the mono code for iterators, it certaily
                    >> appears
                    >> to create a nested class that handles iteration, so a sort of
                    >> psuedo-coroutines.[/color]
                    >
                    > I had forgot that Mono already has these features in it (at least
                    > partially).
                    >
                    > I guess I should play around with my Mono install some more and see if my
                    > idea for using iterators to simulate true coroutines in a simulation will
                    > work well.
                    >[color=green]
                    >> A pure coroutine api would be nice, a fiber API is probably best left
                    >> out(There is no guarentee that a managed Thread is actually a thread, it
                    >> could be implemented as a fiber or a user thread(similar to fibers) in a
                    >> given runtime.[/color]
                    >
                    > I forgot about that, too, but it makes sense, with Unix being fiber-based
                    > and not thread-based[/color]

                    Not to mention hosts, etc. I was reading in Chris Brumme's blog[1] today
                    that the hosting system in whidbey should allow the option of using fibers,
                    for things like SQL server and other high performance hosts.[color=blue]
                    >[color=green]
                    >> I'm not sure, realistically, what IL can do as far as
                    >> coroutines go, but the Mono generation uses standard return and the
                    >> contained class for state. This method should work(its how anonymous[/color]
                    > methods[color=green]
                    >> work as well, the only thing I am really worried about is how would[/color]
                    > security[color=green]
                    >> work in full coroutines, if the stack isn't maintained.[/color]
                    >
                    > Yeap, I forgot this too. I tend to forget about code security when I
                    > think
                    > about features that IL should have implemented. Still, aren't there some
                    > languages that can't be fully supported in IL because of it's lack of
                    > coroutines? Or would all of those compilers have to do pseudo-coroutines
                    > as
                    > well? Then what about the previously mentioned problem of calling other
                    > methods from the coroutine?
                    >
                    > Or do .NET versions of these languages have to be restricted in what they
                    > support? Or maybe the compiler could make use of an unmanaged fiber API.
                    > But this brings up security issues again.
                    >
                    > I guess this is similar to the problem of getting SmallTalk to run on IL.
                    > I
                    > guess some language features have to be left out.
                    >[/color]

                    Yes, there are features that won't make it, functional languages are
                    especially hard hit by this(There is some research in the area, MS research
                    had a project porting...ML I think to the framework, including some extra IL
                    instructions, maybe that will make it into the system some day). On its
                    surface(best I can tell anyway) IL was really designed for imperative,
                    semi-OO languages, things like MI and a few other bits are left out,
                    restricting even C++. When targetting alot of languages its very hard to
                    abstract and still allow them all to run. Hopefully solutions will come,
                    with or without IL enhancements.[color=blue][color=green]
                    >> The prolog for a routine would have to maintain security, complicating
                    >> the language a bit(It wouldn't be particularly safe, IMHO, to change the
                    >> security of a method already executing in part between calls, thats
                    >> asking
                    >> for obscure bugs).[/color]
                    >
                    > Right you are. I need to think about the problem some more.
                    >
                    > But for now I'm happy with the (proposed) implementation of iterators. It
                    > certainly makes it easier to provide multiple enumerators for a data type
                    > (such as reverse enumerators, enumerators that only travel through a
                    > subset
                    > of the items, etc.).
                    >[/color]

                    Agreed[color=blue]
                    > Back to my example:
                    > After thinking about it, perhaps a better way to implement the problem in
                    > my
                    > example is as follows: (The bot-manager class would be in charge of
                    > checking the Action property after each MoveNext call.)
                    >
                    > class Bot : Entity {
                    >
                    > private IAction action;
                    > private int health;
                    > // etc.
                    >
                    > public IAction Action {
                    > get { return action; }
                    > }
                    >
                    > private void Attack(Entity entity) {
                    > action = new AttackAction(en tity);
                    > }
                    >
                    > private void MoveTo(Point location) {
                    > action = new MoveToAction(lo cation);
                    > }
                    >
                    > private void WanderAimlessly () {
                    > action = new WanderAimlessly Action();
                    > }
                    >
                    > // bool return value is a dummy, I suppose (I need to think about
                    > whether a value is really needed)
                    > // I don't suppose IEnumerable<Voi d> is possible .. ???
                    > public IEnumerable<boo l> Update {
                    > get {
                    > while(alive) {
                    > if(health < 10) {
                    > Entity healthPickup =
                    > World.FindNeare stHealthPickup( this.Location);
                    > MoveTo(healthPi ckup.Location);
                    > yield return true;
                    > }
                    > else {
                    > Entity[] enemies =
                    > World.GetVisibl eEnemies(this.L ocation);
                    > if(enemies.Leng th > 0) {
                    > Attack(enemies[0]);
                    > yield return true; // odd syntax, but it does the
                    > job I guess
                    > }
                    > else {
                    > WanderAimlessly ();
                    > yield return true;
                    > }
                    > }
                    > }
                    > yield break;
                    > }
                    > }
                    >
                    > }
                    >
                    > This is still pretty clean, and abstracts away a lot of the state
                    > management. It's a good example one of my favorite situations in
                    > programming---lots of messy ground work in order to make the higher-level
                    > code cleaner. I still wish the "yield return true" statement could be
                    > better....like I said, if non-iterator private-methods could yield, then
                    > that statement could go in MoveTo(), Attack(), and WanderAimlessly ();
                    >
                    > Maybe I just miss the pre-multitasking days of programming in DOS where
                    > you
                    > never had to worry about programming finite-state-machines all the time.
                    > *sigh*. These "problems" are even worse in games, and although threads
                    > can
                    > help, they often open a whole new can of worms.
                    >
                    > Now time to go play with Mono a bit... Maybe I can improve my
                    > implementation further. I'm curious to what the generated IEnumerable
                    > class's source will look like if I put really complicated logic into the
                    > iterator method.[/color]

                    Hopefully iterators will supply a solution, it may not be as apparent but I
                    agree it is far better than writing state machines(I hate state machines,
                    especially wrt xml), and there are some interesting points. I wonder if it
                    would be possible with some sneaky thread level tricks to pop and store the
                    stack, in a manner similar to fibers but restoring it in the
                    compiler...prob ably not but it may be a solution as well.

                    Another option would be to add a requirement for CLR hosts that wish to
                    support coroutines need to provide a way to create a user-controlable
                    thread, be it a fiber or unix style user threads its irrelevent.

                    And yet another option would be to research how user threads work and
                    implement a small user-thread\fiber like library within the framework itself
                    to handle the code. I don't know if its possible but it is a curiosity.[color=blue]
                    >
                    >
                    > --Matthew W. Jackson
                    >
                    >[/color]


                    Comment

                    • Daniel O'Connell [C# MVP]

                      #11
                      Re: C# iterators and suspend/resume in Simula 67


                      "Matthew W. Jackson" <themuujAThotma ilDOTcom@NOSPAM .NOSPAM> wrote in message
                      news:%232uAbgQ% 23DHA.2216@TK2M SFTNGP10.phx.gb l...[color=blue][color=green][color=darkred]
                      >> > (The yield new syntax could be made a bit cleaner with static
                      >> > methods...even
                      >> > cleaner if C# supported executing the yield statement outside the[/color][/color]
                      > iterator[color=green][color=darkred]
                      >> > method itself---which if I understand correctly it won't.)[/color]
                      >>
                      >> What do you mean here? I am not entirely familiar with coroutines and[/color]
                      > don't[color=green]
                      >> think I've run across this concept.[/color]
                      >
                      > (btw, ooops--Forgot the updated iterator syntax in my examples...not that
                      > it
                      > matters much).
                      >
                      > Oh, I was just saying that rather than doing a bunch of "yield return new
                      > MoveToCommand(p os);" it could be made to read better with a static method
                      > that returns a command, such as "yield return MoveTo(pos);", and if the
                      > yield could be fired in another method, then you could just simply to
                      > "MoveTo(pos );"--saving two keywords and improving readability a bit
                      > (although you will get no indication that execution will yield--so maybe
                      > it's not such a good idea).
                      >
                      > But the yield statement (as I understand) has to be in the iterator
                      > method,
                      > in order to make the job of the compiler MUCH easier--since these do seem
                      > to
                      > be compiled IEnumerable classes and not true fibers or coroutines.
                      >
                      > This also means that, given a binary tree class, one can not use a
                      > recursive
                      > method to traverse the tree. The following
                      > won't be legal:
                      >
                      > public IEnumerable InOrder {
                      > get {
                      > if(root != null) Iterate(root);
                      > yield break;
                      > }
                      > }
                      >
                      > public void Iterate(Node node) {
                      > if(node.Left != null) Iterate(left);
                      > yield return node.Value;
                      > if(node.Right != null) Iterate(right);
                      > }
                      >
                      > If this were legal, then iterating even the most complicated of data
                      > structures would be easy. However, since the "yield" cannot occur outside
                      > of your iterator method, it won't be as simple as that.
                      >
                      > Mind you, it will be easier to write with iterators in this case than it
                      > was
                      > with a separate Enumerator class, but not too much easier...You still need
                      > to use your own Stack to do the iteration efficiently. The only
                      > difference
                      > is the Stack is now a local variable and not a instance variable.
                      >
                      > I can't really think of a way to easily allow the iterator to be recursive
                      > without being build on top of fibers or coroutines. Maybe I'm missing
                      > something here. Maybe the compiler could determine which routines
                      > containing yield statemetns were called by an iterator and somehow figure
                      > out how to build the pseudo-call-stack for you. It would also mean that
                      > any
                      > routine containing a yield could not be called by a non-iterator method.
                      > In
                      > the end, it seems like it'd be more complicated than it is worth
                      > (especially
                      > when you take security into account).
                      >[/color]

                      Actually, from what I can tell, yield *defines* the iterator method, making
                      it entirely impossible to use it outside of the method you want as an
                      iterator.
                      Also, another issue I have is that the analysis of the flow to determine
                      where yields could occur is simply rather complex, if you consider virtuals
                      and other such things, it would be really tricky. A method may be to create
                      something like a iterator property or definition, more or less literally
                      designing a class but with the compiler still generating the state machine
                      and simply filling in pieces(enter, exit, etc), or even simply grouping
                      associated methods into one scope, using a defined entry point. The downside
                      of hte latter approach is you couldn't have reusable code(unless
                      complexities of iterator inheritance came into the picture...and I really
                      don't think the feature is worth the complexity of inheritance.)[color=blue][color=green]
                      >> Using a quick scan across the mono code for iterators, it certaily
                      >> appears
                      >> to create a nested class that handles iteration, so a sort of
                      >> psuedo-coroutines.[/color]
                      >
                      > I had forgot that Mono already has these features in it (at least
                      > partially).
                      >
                      > I guess I should play around with my Mono install some more and see if my
                      > idea for using iterators to simulate true coroutines in a simulation will
                      > work well.
                      >[color=green]
                      >> A pure coroutine api would be nice, a fiber API is probably best left
                      >> out(There is no guarentee that a managed Thread is actually a thread, it
                      >> could be implemented as a fiber or a user thread(similar to fibers) in a
                      >> given runtime.[/color]
                      >
                      > I forgot about that, too, but it makes sense, with Unix being fiber-based
                      > and not thread-based[/color]

                      Not to mention hosts, etc. I was reading in Chris Brumme's blog[1] today
                      that the hosting system in whidbey should allow the option of using fibers,
                      for things like SQL server and other high performance hosts.[color=blue]
                      >[color=green]
                      >> I'm not sure, realistically, what IL can do as far as
                      >> coroutines go, but the Mono generation uses standard return and the
                      >> contained class for state. This method should work(its how anonymous[/color]
                      > methods[color=green]
                      >> work as well, the only thing I am really worried about is how would[/color]
                      > security[color=green]
                      >> work in full coroutines, if the stack isn't maintained.[/color]
                      >
                      > Yeap, I forgot this too. I tend to forget about code security when I
                      > think
                      > about features that IL should have implemented. Still, aren't there some
                      > languages that can't be fully supported in IL because of it's lack of
                      > coroutines? Or would all of those compilers have to do pseudo-coroutines
                      > as
                      > well? Then what about the previously mentioned problem of calling other
                      > methods from the coroutine?
                      >
                      > Or do .NET versions of these languages have to be restricted in what they
                      > support? Or maybe the compiler could make use of an unmanaged fiber API.
                      > But this brings up security issues again.
                      >
                      > I guess this is similar to the problem of getting SmallTalk to run on IL.
                      > I
                      > guess some language features have to be left out.
                      >[/color]

                      Yes, there are features that won't make it, functional languages are
                      especially hard hit by this(There is some research in the area, MS research
                      had a project porting...ML I think to the framework, including some extra IL
                      instructions, maybe that will make it into the system some day). On its
                      surface(best I can tell anyway) IL was really designed for imperative,
                      semi-OO languages, things like MI and a few other bits are left out,
                      restricting even C++. When targetting alot of languages its very hard to
                      abstract and still allow them all to run. Hopefully solutions will come,
                      with or without IL enhancements.[color=blue][color=green]
                      >> The prolog for a routine would have to maintain security, complicating
                      >> the language a bit(It wouldn't be particularly safe, IMHO, to change the
                      >> security of a method already executing in part between calls, thats
                      >> asking
                      >> for obscure bugs).[/color]
                      >
                      > Right you are. I need to think about the problem some more.
                      >
                      > But for now I'm happy with the (proposed) implementation of iterators. It
                      > certainly makes it easier to provide multiple enumerators for a data type
                      > (such as reverse enumerators, enumerators that only travel through a
                      > subset
                      > of the items, etc.).
                      >[/color]

                      Agreed[color=blue]
                      > Back to my example:
                      > After thinking about it, perhaps a better way to implement the problem in
                      > my
                      > example is as follows: (The bot-manager class would be in charge of
                      > checking the Action property after each MoveNext call.)
                      >
                      > class Bot : Entity {
                      >
                      > private IAction action;
                      > private int health;
                      > // etc.
                      >
                      > public IAction Action {
                      > get { return action; }
                      > }
                      >
                      > private void Attack(Entity entity) {
                      > action = new AttackAction(en tity);
                      > }
                      >
                      > private void MoveTo(Point location) {
                      > action = new MoveToAction(lo cation);
                      > }
                      >
                      > private void WanderAimlessly () {
                      > action = new WanderAimlessly Action();
                      > }
                      >
                      > // bool return value is a dummy, I suppose (I need to think about
                      > whether a value is really needed)
                      > // I don't suppose IEnumerable<Voi d> is possible .. ???
                      > public IEnumerable<boo l> Update {
                      > get {
                      > while(alive) {
                      > if(health < 10) {
                      > Entity healthPickup =
                      > World.FindNeare stHealthPickup( this.Location);
                      > MoveTo(healthPi ckup.Location);
                      > yield return true;
                      > }
                      > else {
                      > Entity[] enemies =
                      > World.GetVisibl eEnemies(this.L ocation);
                      > if(enemies.Leng th > 0) {
                      > Attack(enemies[0]);
                      > yield return true; // odd syntax, but it does the
                      > job I guess
                      > }
                      > else {
                      > WanderAimlessly ();
                      > yield return true;
                      > }
                      > }
                      > }
                      > yield break;
                      > }
                      > }
                      >
                      > }
                      >
                      > This is still pretty clean, and abstracts away a lot of the state
                      > management. It's a good example one of my favorite situations in
                      > programming---lots of messy ground work in order to make the higher-level
                      > code cleaner. I still wish the "yield return true" statement could be
                      > better....like I said, if non-iterator private-methods could yield, then
                      > that statement could go in MoveTo(), Attack(), and WanderAimlessly ();
                      >
                      > Maybe I just miss the pre-multitasking days of programming in DOS where
                      > you
                      > never had to worry about programming finite-state-machines all the time.
                      > *sigh*. These "problems" are even worse in games, and although threads
                      > can
                      > help, they often open a whole new can of worms.
                      >
                      > Now time to go play with Mono a bit... Maybe I can improve my
                      > implementation further. I'm curious to what the generated IEnumerable
                      > class's source will look like if I put really complicated logic into the
                      > iterator method.[/color]

                      Hopefully iterators will supply a solution, it may not be as apparent but I
                      agree it is far better than writing state machines(I hate state machines,
                      especially wrt xml), and there are some interesting points. I wonder if it
                      would be possible with some sneaky thread level tricks to pop and store the
                      stack, in a manner similar to fibers but restoring it in the
                      compiler...prob ably not but it may be a solution as well.

                      Another option would be to add a requirement for CLR hosts that wish to
                      support coroutines need to provide a way to create a user-controlable
                      thread, be it a fiber or unix style user threads its irrelevent.

                      And yet another option would be to research how user threads work and
                      implement a small user-thread\fiber like library within the framework itself
                      to handle the code. I don't know if its possible but it is a curiosity.[color=blue]
                      >
                      >
                      > --Matthew W. Jackson
                      >
                      >[/color]


                      Comment

                      • Daniel O'Connell [C# MVP]

                        #12
                        Re: C# iterators and suspend/resume in Simula 67

                        oops, forgot the link to the blog I referenced:

                        "Daniel O'Connell [C# MVP]" <onyxkirx@--NOSPAM--comcast.net> wrote in
                        message news:Oxk7cbR%23 DHA.2704@TK2MSF TNGP12.phx.gbl. ..[color=blue]
                        >
                        > "Matthew W. Jackson" <themuujAThotma ilDOTcom@NOSPAM .NOSPAM> wrote in
                        > message news:%232uAbgQ% 23DHA.2216@TK2M SFTNGP10.phx.gb l...[color=green][color=darkred]
                        >>> > (The yield new syntax could be made a bit cleaner with static
                        >>> > methods...even
                        >>> > cleaner if C# supported executing the yield statement outside the[/color]
                        >> iterator[color=darkred]
                        >>> > method itself---which if I understand correctly it won't.)
                        >>>
                        >>> What do you mean here? I am not entirely familiar with coroutines and[/color]
                        >> don't[color=darkred]
                        >>> think I've run across this concept.[/color]
                        >>
                        >> (btw, ooops--Forgot the updated iterator syntax in my examples...not that
                        >> it
                        >> matters much).
                        >>
                        >> Oh, I was just saying that rather than doing a bunch of "yield return new
                        >> MoveToCommand(p os);" it could be made to read better with a static method
                        >> that returns a command, such as "yield return MoveTo(pos);", and if the
                        >> yield could be fired in another method, then you could just simply to
                        >> "MoveTo(pos );"--saving two keywords and improving readability a bit
                        >> (although you will get no indication that execution will yield--so maybe
                        >> it's not such a good idea).
                        >>
                        >> But the yield statement (as I understand) has to be in the iterator
                        >> method,
                        >> in order to make the job of the compiler MUCH easier--since these do seem
                        >> to
                        >> be compiled IEnumerable classes and not true fibers or coroutines.
                        >>
                        >> This also means that, given a binary tree class, one can not use a
                        >> recursive
                        >> method to traverse the tree. The following
                        >> won't be legal:
                        >>
                        >> public IEnumerable InOrder {
                        >> get {
                        >> if(root != null) Iterate(root);
                        >> yield break;
                        >> }
                        >> }
                        >>
                        >> public void Iterate(Node node) {
                        >> if(node.Left != null) Iterate(left);
                        >> yield return node.Value;
                        >> if(node.Right != null) Iterate(right);
                        >> }
                        >>
                        >> If this were legal, then iterating even the most complicated of data
                        >> structures would be easy. However, since the "yield" cannot occur
                        >> outside
                        >> of your iterator method, it won't be as simple as that.
                        >>
                        >> Mind you, it will be easier to write with iterators in this case than it
                        >> was
                        >> with a separate Enumerator class, but not too much easier...You still
                        >> need
                        >> to use your own Stack to do the iteration efficiently. The only
                        >> difference
                        >> is the Stack is now a local variable and not a instance variable.
                        >>
                        >> I can't really think of a way to easily allow the iterator to be
                        >> recursive
                        >> without being build on top of fibers or coroutines. Maybe I'm missing
                        >> something here. Maybe the compiler could determine which routines
                        >> containing yield statemetns were called by an iterator and somehow figure
                        >> out how to build the pseudo-call-stack for you. It would also mean that
                        >> any
                        >> routine containing a yield could not be called by a non-iterator method.
                        >> In
                        >> the end, it seems like it'd be more complicated than it is worth
                        >> (especially
                        >> when you take security into account).
                        >>[/color]
                        >
                        > Actually, from what I can tell, yield *defines* the iterator method,
                        > making it entirely impossible to use it outside of the method you want as
                        > an iterator.
                        > Also, another issue I have is that the analysis of the flow to determine
                        > where yields could occur is simply rather complex, if you consider
                        > virtuals and other such things, it would be really tricky. A method may be
                        > to create something like a iterator property or definition, more or less
                        > literally designing a class but with the compiler still generating the
                        > state machine and simply filling in pieces(enter, exit, etc), or even
                        > simply grouping associated methods into one scope, using a defined entry
                        > point. The downside of hte latter approach is you couldn't have reusable
                        > code(unless complexities of iterator inheritance came into the
                        > picture...and I really don't think the feature is worth the complexity of
                        > inheritance.)[color=green][color=darkred]
                        >>> Using a quick scan across the mono code for iterators, it certaily
                        >>> appears
                        >>> to create a nested class that handles iteration, so a sort of
                        >>> psuedo-coroutines.[/color]
                        >>
                        >> I had forgot that Mono already has these features in it (at least
                        >> partially).
                        >>
                        >> I guess I should play around with my Mono install some more and see if my
                        >> idea for using iterators to simulate true coroutines in a simulation will
                        >> work well.
                        >>[color=darkred]
                        >>> A pure coroutine api would be nice, a fiber API is probably best left
                        >>> out(There is no guarentee that a managed Thread is actually a thread, it
                        >>> could be implemented as a fiber or a user thread(similar to fibers) in a
                        >>> given runtime.[/color]
                        >>
                        >> I forgot about that, too, but it makes sense, with Unix being fiber-based
                        >> and not thread-based[/color]
                        >
                        > Not to mention hosts, etc. I was reading in Chris Brumme's blog[1] today
                        > that the hosting system in whidbey should allow the option of using
                        > fibers, for things like SQL server and other high performance hosts.[color=green]
                        >>[color=darkred]
                        >>> I'm not sure, realistically, what IL can do as far as
                        >>> coroutines go, but the Mono generation uses standard return and the
                        >>> contained class for state. This method should work(its how anonymous[/color]
                        >> methods[color=darkred]
                        >>> work as well, the only thing I am really worried about is how would[/color]
                        >> security[color=darkred]
                        >>> work in full coroutines, if the stack isn't maintained.[/color]
                        >>
                        >> Yeap, I forgot this too. I tend to forget about code security when I
                        >> think
                        >> about features that IL should have implemented. Still, aren't there some
                        >> languages that can't be fully supported in IL because of it's lack of
                        >> coroutines? Or would all of those compilers have to do pseudo-coroutines
                        >> as
                        >> well? Then what about the previously mentioned problem of calling other
                        >> methods from the coroutine?
                        >>
                        >> Or do .NET versions of these languages have to be restricted in what they
                        >> support? Or maybe the compiler could make use of an unmanaged fiber API.
                        >> But this brings up security issues again.
                        >>
                        >> I guess this is similar to the problem of getting SmallTalk to run on IL.
                        >> I
                        >> guess some language features have to be left out.
                        >>[/color]
                        >
                        > Yes, there are features that won't make it, functional languages are
                        > especially hard hit by this(There is some research in the area, MS
                        > research had a project porting...ML I think to the framework, including
                        > some extra IL instructions, maybe that will make it into the system some
                        > day). On its surface(best I can tell anyway) IL was really designed for
                        > imperative, semi-OO languages, things like MI and a few other bits are
                        > left out, restricting even C++. When targetting alot of languages its very
                        > hard to abstract and still allow them all to run. Hopefully solutions will
                        > come, with or without IL enhancements.[color=green][color=darkred]
                        >>> The prolog for a routine would have to maintain security, complicating
                        >>> the language a bit(It wouldn't be particularly safe, IMHO, to change the
                        >>> security of a method already executing in part between calls, thats
                        >>> asking
                        >>> for obscure bugs).[/color]
                        >>
                        >> Right you are. I need to think about the problem some more.
                        >>
                        >> But for now I'm happy with the (proposed) implementation of iterators.
                        >> It
                        >> certainly makes it easier to provide multiple enumerators for a data type
                        >> (such as reverse enumerators, enumerators that only travel through a
                        >> subset
                        >> of the items, etc.).
                        >>[/color]
                        >
                        > Agreed[color=green]
                        >> Back to my example:
                        >> After thinking about it, perhaps a better way to implement the problem in
                        >> my
                        >> example is as follows: (The bot-manager class would be in charge of
                        >> checking the Action property after each MoveNext call.)
                        >>
                        >> class Bot : Entity {
                        >>
                        >> private IAction action;
                        >> private int health;
                        >> // etc.
                        >>
                        >> public IAction Action {
                        >> get { return action; }
                        >> }
                        >>
                        >> private void Attack(Entity entity) {
                        >> action = new AttackAction(en tity);
                        >> }
                        >>
                        >> private void MoveTo(Point location) {
                        >> action = new MoveToAction(lo cation);
                        >> }
                        >>
                        >> private void WanderAimlessly () {
                        >> action = new WanderAimlessly Action();
                        >> }
                        >>
                        >> // bool return value is a dummy, I suppose (I need to think about
                        >> whether a value is really needed)
                        >> // I don't suppose IEnumerable<Voi d> is possible .. ???
                        >> public IEnumerable<boo l> Update {
                        >> get {
                        >> while(alive) {
                        >> if(health < 10) {
                        >> Entity healthPickup =
                        >> World.FindNeare stHealthPickup( this.Location);
                        >> MoveTo(healthPi ckup.Location);
                        >> yield return true;
                        >> }
                        >> else {
                        >> Entity[] enemies =
                        >> World.GetVisibl eEnemies(this.L ocation);
                        >> if(enemies.Leng th > 0) {
                        >> Attack(enemies[0]);
                        >> yield return true; // odd syntax, but it does the
                        >> job I guess
                        >> }
                        >> else {
                        >> WanderAimlessly ();
                        >> yield return true;
                        >> }
                        >> }
                        >> }
                        >> yield break;
                        >> }
                        >> }
                        >>
                        >> }
                        >>
                        >> This is still pretty clean, and abstracts away a lot of the state
                        >> management. It's a good example one of my favorite situations in
                        >> programming---lots of messy ground work in order to make the higher-level
                        >> code cleaner. I still wish the "yield return true" statement could be
                        >> better....like I said, if non-iterator private-methods could yield, then
                        >> that statement could go in MoveTo(), Attack(), and WanderAimlessly ();
                        >>
                        >> Maybe I just miss the pre-multitasking days of programming in DOS where
                        >> you
                        >> never had to worry about programming finite-state-machines all the time.
                        >> *sigh*. These "problems" are even worse in games, and although threads
                        >> can
                        >> help, they often open a whole new can of worms.
                        >>
                        >> Now time to go play with Mono a bit... Maybe I can improve my
                        >> implementation further. I'm curious to what the generated IEnumerable
                        >> class's source will look like if I put really complicated logic into the
                        >> iterator method.[/color]
                        >
                        > Hopefully iterators will supply a solution, it may not be as apparent but
                        > I agree it is far better than writing state machines(I hate state
                        > machines, especially wrt xml), and there are some interesting points. I
                        > wonder if it would be possible with some sneaky thread level tricks to pop
                        > and store the stack, in a manner similar to fibers but restoring it in the
                        > compiler...prob ably not but it may be a solution as well.
                        >
                        > Another option would be to add a requirement for CLR hosts that wish to
                        > support coroutines need to provide a way to create a user-controlable
                        > thread, be it a fiber or unix style user threads its irrelevent.
                        >
                        > And yet another option would be to research how user threads work and
                        > implement a small user-thread\fiber like library within the framework
                        > itself to handle the code. I don't know if its possible but it is a
                        > curiosity.[color=green]
                        >>
                        >>
                        >> --Matthew W. Jackson
                        >>
                        >>[/color]
                        >
                        >[/color]


                        Comment

                        • Jeffrey Tan[MSFT]

                          #13
                          RE: C# iterators and suspend/resume in Simula 67


                          Hi Jiri,

                          Does the community's reply make sense to you?

                          If you still have anything unclear, please feel free to follow up, we will
                          help you.

                          Best regards,
                          Jeffrey Tan
                          Microsoft Online Partner Support
                          Get Secure! - www.microsoft.com/security
                          This posting is provided "as is" with no warranties and confers no rights.

                          Comment

                          • Jiri Kripac

                            #14
                            Re: C# iterators and suspend/resume in Simula 67

                            Hi Jeffrey,

                            Thanks for monitoring this discussion. Actually, I posted this issue because
                            I hoped someone from Microsoft C# team could step in and elaborate on this
                            subject. I really think C# iterators are an afterthought and C# deserves a
                            more general and more elegant solution.

                            I also mentioned Simula 67 to point out that these concepts have already
                            been designed some 37 years ago, and have been done more cleanly than it is
                            currently done in C#.

                            Jiri



                            """Jeffrey Tan[MSFT]""" <v-jetan@online.mi crosoft.com> wrote in message
                            news:LkiUean%23 DHA.2808@cpmsft ngxa06.phx.gbl. ..[color=blue]
                            >
                            > Hi Jiri,
                            >
                            > Does the community's reply make sense to you?
                            >
                            > If you still have anything unclear, please feel free to follow up, we will
                            > help you.
                            >
                            > Best regards,
                            > Jeffrey Tan
                            > Microsoft Online Partner Support
                            > Get Secure! - www.microsoft.com/security
                            > This posting is provided "as is" with no warranties and confers no rights.
                            >[/color]


                            Comment

                            • Jeffrey Tan[MSFT]

                              #15
                              Re: C# iterators and suspend/resume in Simula 67


                              Hi Jiri,

                              Thanks very much for your feedback.

                              Yes, I see your concern, actually, I am monitoring this issue.

                              For your concern, I suggest you feedback it to our product team at:

                              or mail to: mswish@microsof t.com

                              Then, our product team will consider your suggestion for C#.

                              Thanks for your understanding.

                              Best regards,
                              Jeffrey Tan
                              Microsoft Online Partner Support
                              Get Secure! - www.microsoft.com/security
                              This posting is provided "as is" with no warranties and confers no rights.

                              Comment

                              Working...