On 5/15/21 4:25 AM, Chris Piker wrote:

> But, loops are bad.

I agree with Adam here. Although most of my recent code gravitates towards long range expressions, I use 'foreach' (even 'for') when I think it makes code more readable.

> Is there some obvious trick or way of looking at the problem that I'm
> missing?

The following are idioms that I use:


* The range is part of the type:

struct MyType(R) {
  R myRange;
}


* If the type is too complicated as in your examples:

struct MyType(R) {
  R myRange;
}

auto makeMyType(X, Y)(/* ... */) {
  auto myArg = foo!X.bar!Y.etc;
  return MyType!(typeof(myArg))(myArg);
}


* If my type can't be templated:

struct MyType {
  alias MyRange = typeof(makeMyArg());
  MyRange myRange;
}

// For the alias to work above, all parameters of this
// function must have default values so that the typeof
// expression is as convenient as above.
auto makeMyArg(X, Y)(X x = X.init, Y y = Y.init) {
  // Then, you can put some condition checks here if
  // X.init and Y.init are invalid values for your
  // program.
  return foo!X.bar!Y.etc;
}

I think that's all really.

And yes, sometimes there are confusing error messages but the compiler is always right. :)

Ali

Reply via email to