Core1: Iterators


[This post is part of a series, “wish-list for future versions of VB“]

 


IDEA: Add Iterators to VB. But don’t do them like C#; instead do them as “anonymous iterators”, as described by Paul Vick: http://www.panopticoncentral.net/archive/2008/08/08/24155.aspx


    Function FromTo(low As Integer, high As Integer) As IEnumerable(Of Integer)


        If low > high Then Throw New ArgumentException(“low>high”)


 


        Return Iterator


                   If low <= high Then


                       Yield low


                   Else


                       Yield Each FromTo(low + 1, high)


                   End If


               End Iterator


    End Function


 


One feature of this is that you can do argument-validation before returning the iterator; C# users currently have to write two methods, an outer one which validates and an inner one which is the iterator.


Another feature is to use a “Return Each” construct, rather than having to return each one individually.


 


SCENARIO: Iterators are just generally useful. As we rewrite the VB compiler and IDE from C++ into VB, we find ourselves needing iterators all the time. They would make it easier to do LINQ and a whole load of tree-like data-structures.


 


At PDC09, Luca Bolognese’s talk “Future Directions for VB and C#” touched on Async (jump to the 40 minute mark). I’ll blog about async ideas in a week (“Power2: Async and Resumable Methods”). For now, it’s worth nothing that Async and Iterators are both examples of “delayed-execution iterative code blocks” and should probably both be implemented with exactly the same machinery under the hood.


Eric Lippert has blogged about the scope of variables in a For loop: I’ll also blog about that in a week (“Req1: put loop control variable inside loop”). For now, I’ll just say that we should probably fix the for-loop-scope along with iterators.


 


Provisional evaluation from VB team: This is a decent idea, one that we should consider against the other decent ideas.


 

Comments (4)

  1. Đonny says:

    1)

    Yes, in C# the delayed validation is pain. So, in VB you will just encapsulate two methods in one? Return Iterator delimiting validation/initialization part from result construction? The "Return Iterator" line confuses me a little.

    What about writing things like:

    Function GetSthFromDb() As IEnumerable(Of Sth)

       Using r = cmd.ExecureReader

           Return Iterator

              While r.Read

                  Return ReadItem(r)

              End While

           End Iterator???

           Code here???

       End Using

      Code here???

    End Function

    2)

    Make it possible to Return both T and IEnumerable(Of T) (as shown in your sample).

    a) Is that Each keyword necessary? (probably yes)

    b) Isn’t it confusing to have just Return, what about Yeld Return? One may think that Return exits function.

    c) Is object returned by iterator IDisposable?

    3)

    What about Exit Function  / Exit Iterator behavior?

    4)

    What about something like

    Function GetSthFromDb() As IEnumerable(Of Sth)

       …

       Return Iterator

           …

           While r.Read()

              GetSthFromDb.Add(getItem(r))

              -or-

              GetSthFromDb.Addrange(GetSthFromDb)

              -or-

              GetSthFromDb += getItem(r)

           End While

       End Iterator???

    End Function

    5)

    Anyway I think iterators should me No. 1 for VB11. And making it better in C# – I’ll love it!

  2. Joacim says:

    I think the syntax is a bit confusing.

    1. You have 2 End Function in that code, should the first one be End Iterator?

    2. The Return Each is also confusing, what would Each mean in this context?

    3. The whole If statement is also confusing, if the Return statement inside the Iterator works simular to yield return in C# then why is the Return Each in the Else clause? Wouldn’t that only be executed if low>high, in which case an exception is thrown?

  3. Meta-Knight says:

    I’m truly disappointed that this feature wasn’t included in VB10. With LINQ and deferred execution iterators are really useful and right now creating iterators in VB is a pain. I would have expected this to be a priority for VB10, considering that C# already has the Yield statement since 2.0!!

    Also as Joacim and Donny pointed out there are problems in your example, you should fix that 😉

  4. Richard says:

    I think this is a good idea, though I wonder if it should be End Return rather than End Iterator.  After all, Do While and Do Until are followed by End Do, not End While and End Until, and For Each is followed by Next, not End Each.  It seems to be the first word of the combination that determines what comes at the end.