dotnet / csharplang

The official repo for the design of the C# programming language
11.43k stars 1.02k forks source link

IEnumerable<In,Out> #1957

Closed NoamWhy closed 5 years ago

NoamWhy commented 5 years ago

Consider the following fictitious code:

void Main()
{
      Communicate_With_Client ( Order_Business_Logic () );
}

void Communicate_With_Client (IEnumerable<string, string> Business_Logic)
{
      var Input    = null as string;
      var Output   = Business_Logic().GetEnumbrator();

      while (Output.MoveNext (Input))
      {
            Console.WriteLine(Outputs.current);

           Input = Console.ReadLine();
      }
}

IEnumerable<string,string> Order_Business_Logic()
{
      //Perform some business logic
      //...

      //Ask a question, and get an answer
      var Input = yield return “What would you like to order?”;

      //Perform some business logic
      //...

      Input = yield return “What color are you interested in?”;

      //Perform some business logic
      //...

      Input = yield return “Your order has been placed, would you like to order additional items?”;

      //Perform some business logic
      //...

      yield break;
}

This code will, unfortunately, not compile for the following reasons:

  1. There is no such type as IEnumerable<In,Out>.
  2. MoveNext() does not accept any input.
  3. Yield return cannot be used in an assignment statement.

These limitations restrict the enumeration process to be one-directional, and make the implementation of such a back-and-forth discussion between client and server more difficult to implement.

Surely, one can think of many ways to feed back information into the enumeration function, but it would be way more elegant if the language could provide you with a gold standard way of implementation.

Thaina commented 5 years ago

Sometimes I want this feature, to iterate a dynamic IEnumerable function while also send the current state into that function

Suppose this is possible

foreach(var decision in NpcAIFunc())
{
    var currentCharacterState = LongLineOfDoingADecisionOfNpcAI(decision);

    continue currentCharacterState; // I came up with syntax continue _value to send a state to the last yield
}

IEnumerable<Decision,CharacterState> NpcAIFunc()
{
    var characterState = yield return isState0 ? decision0 : decision1;
    switch(characterState)
    {
        case : CharacterState.State0
            characterState = yield return decision2;
            break;
        case : CharacterState.State1
            characterState = yield return decision3;
            break;
        case : CharacterState.State3
            characterState = yield return decision4;
            break;
    }

    if(characterState != CharacterState.State0)
         yield return decision5; // doesn't care the response result

    yield return decision6; // doesn't care the response result and end the iteration
}

I don't remember much about situation I have expect this feature but it always about responding back and forth in the iteration, like doing Where or TakeWhile clause but expect a custom state