Stream: API design

Topic: ✔ Add dependency on `is.lt` for ..< and ..= operators


view this post on Zulip Jasper Woudenberg (Jul 11 2026 at 13:16):

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:

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.

view this post on Zulip Jasper Woudenberg (Jul 11 2026 at 13:29):

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.

view this post on Zulip Richard Feldman (Jul 11 2026 at 13:37):

yeah maybe that's the way to go :wait_one_second:

view this post on Zulip Richard Feldman (Jul 11 2026 at 13:37):

this use case didn't occur to me, but it makes sense!

view this post on Zulip Jasper Woudenberg (Jul 11 2026 at 13:49):

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?

view this post on Zulip Richard Feldman (Jul 11 2026 at 13:55):

yeah I think changing to explicit range methods is the way to go - I can make a PR for that today

view this post on Zulip Richard Feldman (Jul 11 2026 at 14:04):

I'm also gonna swap the names to be range_*

view this post on Zulip Richard Feldman (Jul 11 2026 at 14:10):

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.

view this post on Zulip Richard Feldman (Jul 11 2026 at 14:11):

as opposed to like:

view this post on Zulip Jasper Woudenberg (Jul 11 2026 at 14:25):

Question: Is the range syntax x..<y supposed to be able to create a descending series? Suppose I type 8..<4, should this:

view this post on Zulip Jasper Woudenberg (Jul 11 2026 at 14:27):

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.

view this post on Zulip Richard Feldman (Jul 11 2026 at 15:04):

actually maybe the right answer is to do this like we do with from_numeral and have it return a Try

view this post on Zulip Richard Feldman (Jul 11 2026 at 15:05):

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

view this post on Zulip Richard Feldman (Jul 11 2026 at 15:06):

I guess that doesn't make sense if you're using variables though :thinking:

view this post on Zulip Richard Feldman (Jul 11 2026 at 15:09):

yeah I think empty iterator is probably the best option

view this post on Zulip Jasper Woudenberg (Jul 11 2026 at 15:46):

Wouldn't it be neat if descending ranges worked too? Or does that create problems elsewhere?

view this post on Zulip Richard Feldman (Jul 11 2026 at 16:59):

I don't think it does. What do other languages do?

view this post on Zulip Jasper Woudenberg (Jul 11 2026 at 18:12):

Rust, Zig, and Ruby don't seem to have it, not sure why though.

view this post on Zulip Richard Feldman (Jul 11 2026 at 18:49):

interesting - do they just return empty ranges?

view this post on Zulip Jasper Woudenberg (Jul 11 2026 at 19:23):

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).

view this post on Zulip Jasper Woudenberg (Jul 12 2026 at 08:15):

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.

view this post on Zulip Notification Bot (Jul 12 2026 at 08:15):

Jasper Woudenberg has marked this topic as resolved.

view this post on Zulip Kasper Møller Andersen (Jul 12 2026 at 08:31):

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.

view this post on Zulip Aurélien Geron (Jul 12 2026 at 08:40):

Good points Kasper. Tuesday..<Thursday could also imply weekly. I think you're right: a more expressive API would probably be best here.

view this post on Zulip Jasper Woudenberg (Jul 12 2026 at 08:51):

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