Maybe this is too much, but one thought that crossed my mind is that it might be nice to have different Iter types for iterators with a known and unknown length. The APIs for both could be mostly the same, but with some nicities for iterators with known lengths:
steps_between would not be necessary, and add_try might be replaced with plus or next. That's a bunch of stuff I'm currently adding on my types to unlock range-syntax, but I'd love to keep off the types if given the choice.U64, no need to wrap it in a Try.Maybe there's some more opportunities like that. It does feel like at the moment the Iter API for iterators with known lengths is held back a bit by it also needing to support unknown-length iterators.
Oh, other approach: if inclusive_range and exclusive_range were defined on the types themselves rather than on .iter() then every type could bring its own implementation.
yeah maybe that's the way to go :wait_one_second:
this use case didn't occur to me, but it makes sense!
I just realized there's another problem with the current API with Date and Time types: It requires adding a method add_try : Date, Date -> Try(Date, [Overflow]), and similar for Time. Which doesn't make sense, because what would it even mean to add two dates or times?
yeah I think changing to explicit range methods is the way to go - I can make a PR for that today
I'm also gonna swap the names to be range_*
in general I've been trying to have the naming convention where function variations go at the end of the name, so that autocomplete lines them up as you type e.g.
addadd_tryadd_wrapas opposed to like:
addtry_addwrapping_addQuestion: Is the range syntax x..<y supposed to be able to create a descending series? Suppose I type 8..<4, should this:
8,7,6,5?I guess I should have tried that first. Current behavior for numbers is to return an empty iterator. I guess I'll implement the same behavior for Date and Time then.
actually maybe the right answer is to do this like we do with from_numeral and have it return a Try
and since it's a literal, we evaluate it at compile time and give you a compile-time error if the range doesn't make sense
I guess that doesn't make sense if you're using variables though :thinking:
yeah I think empty iterator is probably the best option
Wouldn't it be neat if descending ranges worked too? Or does that create problems elsewhere?
I don't think it does. What do other languages do?
Rust, Zig, and Ruby don't seem to have it, not sure why though.
interesting - do they just return empty ranges?
For ruby (tested) and rust (read online), yes. In zig a descending range results in a compile error (though not a clear one, it complains about not being able to store a negative number in a usize, I presume it's attempting to store the range length).
The new range API works beautifully!
For those interested: I ended up using it for the Date, Month, and Weekday types. For Time I don't imagine iterating over all the seconds between two times is generally what someone should want, so for it I have a dedicated iter method taking as an argument the amount of seconds between two times someone wants.
Jasper Woudenberg has marked this topic as resolved.
To me, this feels a bit off. For data that is inherently circular, like Weekday, isn't it important that I can specify how many loops I want my range to cover? As in Tuesday..<Thursday feels like a novelty without a usecase to me, since it can never cover more than a single loop, where the actual usecase would be more like today + 20.days or today + 3.weeks. And on descending ranges, I think having the syntax be the same for both ascending and descending ranges feels a bit dangerous. Wouldn't it be ambiguous in this case: 1U8..0U8? As in, does this create a descending range of one element, or does it produce an ascending range of 255 elements due to overflow?
It feels to me like the range syntax should be a short cut that you reach for only for ascending ranges with clear bounds, and anything else is better relegated to a more expressive API, rather than trying to make the magic syntax fit all those uses.
Good points Kasper. Tuesday..<Thursday could also imply weekly. I think you're right: a more expressive API would probably be best here.
I think there's some reasonable uses for ranges on weekdays and months, like Mo..=Fr for the workweek for instance, or Jan..<Apr for Q1.
I do agree the range syntax is limited. The date/time library I work on also offers .iter() for obtaining an iterator that keeps looping forever, which can then be modified using the Iter methods to obtain the thing you want.
That said, I think range syntax is limited generally, outside circular structures too. For instance, for Date I implemented range syntax to yield every day between two dates, but a user of the library might instead want to step through 7 days at a time to get every Monday. That usecase is covered by a different method. I think that just demonstrates range syntax is a nice convenience for constructing some simple iterators.
I don't feel strongly about descending ranges. I don't remember missing them much in other languages. It was only in the context of working with dates that I started wondering why a range of dates into the future would be legal but one going into the past would not be. I don't think the question occurred to me before for integers.
Last updated: Jul 23 2026 at 13:15 UTC