|Posted by H. S. Teoh|
in reply to Paul Backus
Posted in reply to Paul Backus
On Sat, Aug 06, 2022 at 03:11:28PM +0000, Paul Backus via Digitalmars-d wrote:
> On Friday, 5 August 2022 at 15:31:18 UTC, Steven Schveighoffer wrote:
> > As for working with arbitrary types, I don't see a problem with it. If you define ++ on your type or += 1, and it doesn't mean the same as every other type that defines that, then it's on you for not following the conventions. D is a language which uses the introspected abilities of things to define whether they are compatible.
> One of the problems with `iota` is that, because it was built up by accretion of special cases, it does *not* adhere to any kind of consistent structural interface.
> For example, this works:
> iota(BigInt(1), BigInt(10))
> ...but this does not:
> iota(BigInt(1), BigInt(10), BigInt(1))
> ...because nobody ever bothered to add a `(start, end, step)` overload
> for custom types.
Perhaps what we need is to sit down and come up with a consistent model for iota and implement that. A consistent API of what is expected of incoming types and how iota will behave in each case.
Here's a first stab at it. Let T be the incoming type (I'm leaning against separately parametrizing the start/end/increment types, I think that's just needlessly complex). Then:
0. T must at least support < and at least one of ++, +. If not, iota(T)
is not supported.
1. If T supports ++, then iota(start,end) will return at least an input
2. If `T + int` is valid, then iota(start,end) will return at least a
3. If `T + T` is valid, then iota(start,end,step) will return at least
an input range.
4. If `T + int*T` is valid, then iota(start,end,step) will return a
Leather is waterproof. Ever see a cow with an umbrella?