What are the advantages of next-iterator over this-iterator?

I don’t work too often with Java/C# iterators directly but when I do I always wonder what was the reason to design iterators in “next” fashion.

In order to start you have to move iterator, in order to check if there is some data you have to check if there is next element.

More appealing concept for me is this-iterator — it “starts” from the beginning, and you can check this state, let’s say isValid. So the loop over entire collection would look like this:

while (iter.isValid())
{
  println(iter.current());
  iter.next();
}

As you here in order to check if there is next element, you go there, and then you check if the state is valid.

YMMV but anyway — is there any advantage of next-iterator (as in Java/C#) over this-iterator?

Note: this is conceptual question, about the design of the language.

3

I think an advantage of C#/.NET’s MoveNext() model over Java’s hasNext() model is that the former implies that some work may be done. The hasNext() method implies a simple state check. But what if you are iterating a lazy stream, and you have to go out to a database to determine whether there are any results? In that case, the first call to hasNext() may be a long blocking operation. The naming of the hasNext() method can be very misleading as to what’s actually going on.

For a real world example, this design issue bit me when implementing Microsoft’s Reactive Extensions (Rx) APIs in Java. Specifically, for the iterator created by IObservable.asIterable() to function properly, the hasNext() method would have to block and wait for the next item/error/completion notification to arrive. That’s hardly intuitive: the name implies a simple state check. Contrast that to the C# design, where MoveNext() would have to block, which is not an altogether unexpected result when you are dealing with a lazily evaluated stream.

My point is this: the “next-iterator” model is preferable to the “this-iterator” model because the “this-iterator” model is often a lie: you may be required to pre-fetch the next element in order to check the state of the iterator. A design which communicates that possibility clearly is preferable, in my opinion. Yes, Java’s naming conventions do follow the “next” model, but the behavioral implications are similar to those of the “this-iterator” model.


Clarification: Perhaps contrasting Java and C# was a poor choice, because Java’s model is deceptive. I consider the most important distinction in the models presented by the OP to be that the “this-iterator” model decouples the “is valid” logic from the “retrieve current/next element” logic, while an ideal “next-iterator” implementation combines these operations. I feel it is appropriate to combine them because, in some cases, determining whether the iterator’s state is valid requires prefetching the next element, so that possibility should be made as explicit as possible.

I do not see a significant design difference between:

while (i.isValid()) { // do we have an element?  (implied as fast, non-blocking)
    doSomething(i.current()); // retrieve the element (may be slow!)
    i.next();
}
// ...and:
while (i.hasNext()) { // do we have an element?  (implied as fast, non-blocking)
    doSomething(i.next()); // retrieve the element (may be slow!)
}

But I do see a meaningful difference here:

while (i.hasNext()) { // do we have an element?  (implied as fast, non-blocking)
    doSomething(i.next()); // retrieve the element (may be slow!)
}
// ...and:
while (i.moveNext()) { // fetch the next element if it exists (may be slow!)
    doSomething(i.current()); // get the element  (implied as fast, non-blocking)
}

In both the isValid() and hasNext() examples, the operation that is implied to be a fast and non-blocking state check may in fact be a slow, blocking operation. In the moveNext() example, most of the work is being done in the method you’d expect, regardless of whether you are dealing with an eagerly or lazily evaluated stream.

6

If there is some computation that needs to be done to compute each value having to get the next value before ever asking for the first value allows you to defer the processing of that first value beyond the construction of the iterator.

For example, the iterator could represent a query that has not yet been executed yet. When the first item is requested, the database is queried for the results. Using your proposed design, that computation would either need to be done upon construction of the iterator (which makes it harder to defer execution) or when calling IsValid, in which case it’s really a misnomer, as calling IsValid would actually be getting the next value.

8

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa

What are the advantages of next-iterator over this-iterator?

I don’t work too often with Java/C# iterators directly but when I do I always wonder what was the reason to design iterators in “next” fashion.

In order to start you have to move iterator, in order to check if there is some data you have to check if there is next element.

More appealing concept for me is this-iterator — it “starts” from the beginning, and you can check this state, let’s say isValid. So the loop over entire collection would look like this:

while (iter.isValid())
{
  println(iter.current());
  iter.next();
}

As you here in order to check if there is next element, you go there, and then you check if the state is valid.

YMMV but anyway — is there any advantage of next-iterator (as in Java/C#) over this-iterator?

Note: this is conceptual question, about the design of the language.

3

I think an advantage of C#/.NET’s MoveNext() model over Java’s hasNext() model is that the former implies that some work may be done. The hasNext() method implies a simple state check. But what if you are iterating a lazy stream, and you have to go out to a database to determine whether there are any results? In that case, the first call to hasNext() may be a long blocking operation. The naming of the hasNext() method can be very misleading as to what’s actually going on.

For a real world example, this design issue bit me when implementing Microsoft’s Reactive Extensions (Rx) APIs in Java. Specifically, for the iterator created by IObservable.asIterable() to function properly, the hasNext() method would have to block and wait for the next item/error/completion notification to arrive. That’s hardly intuitive: the name implies a simple state check. Contrast that to the C# design, where MoveNext() would have to block, which is not an altogether unexpected result when you are dealing with a lazily evaluated stream.

My point is this: the “next-iterator” model is preferable to the “this-iterator” model because the “this-iterator” model is often a lie: you may be required to pre-fetch the next element in order to check the state of the iterator. A design which communicates that possibility clearly is preferable, in my opinion. Yes, Java’s naming conventions do follow the “next” model, but the behavioral implications are similar to those of the “this-iterator” model.


Clarification: Perhaps contrasting Java and C# was a poor choice, because Java’s model is deceptive. I consider the most important distinction in the models presented by the OP to be that the “this-iterator” model decouples the “is valid” logic from the “retrieve current/next element” logic, while an ideal “next-iterator” implementation combines these operations. I feel it is appropriate to combine them because, in some cases, determining whether the iterator’s state is valid requires prefetching the next element, so that possibility should be made as explicit as possible.

I do not see a significant design difference between:

while (i.isValid()) { // do we have an element?  (implied as fast, non-blocking)
    doSomething(i.current()); // retrieve the element (may be slow!)
    i.next();
}
// ...and:
while (i.hasNext()) { // do we have an element?  (implied as fast, non-blocking)
    doSomething(i.next()); // retrieve the element (may be slow!)
}

But I do see a meaningful difference here:

while (i.hasNext()) { // do we have an element?  (implied as fast, non-blocking)
    doSomething(i.next()); // retrieve the element (may be slow!)
}
// ...and:
while (i.moveNext()) { // fetch the next element if it exists (may be slow!)
    doSomething(i.current()); // get the element  (implied as fast, non-blocking)
}

In both the isValid() and hasNext() examples, the operation that is implied to be a fast and non-blocking state check may in fact be a slow, blocking operation. In the moveNext() example, most of the work is being done in the method you’d expect, regardless of whether you are dealing with an eagerly or lazily evaluated stream.

6

If there is some computation that needs to be done to compute each value having to get the next value before ever asking for the first value allows you to defer the processing of that first value beyond the construction of the iterator.

For example, the iterator could represent a query that has not yet been executed yet. When the first item is requested, the database is queried for the results. Using your proposed design, that computation would either need to be done upon construction of the iterator (which makes it harder to defer execution) or when calling IsValid, in which case it’s really a misnomer, as calling IsValid would actually be getting the next value.

8

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật