Random thought, but treating step as a template argument would allow for some more interesting changes to the iterations, though I can't think of any particular syntax that would look good. And if you did add such a thing, then other operators would want it as well.
Interesting, though I feel like operator syntax really shines when either 1) It's significantly shorter/simpler than the equivalent function calls.
2) It appeals to domain-specific intuitions.
In terms of (1) and (2), I think better spellings for these might be
int[] foo = a ..!"a += 10" b;
import std.array: array; import std.range: iota; int[] foo = array(iota(a, b, 10)); // Or something with recurrence, in the general case.
bool equals = dbl1 ==."abs(a - b) < 0.01" dbl2
import std.math: abs; struct Approximation(A) { A a; alias a this; bool opEquals(B)(B b) const { return abs(a - b) < 0.01; } } auto approximate(A)(A a) { return Approximation!A(a); } bool equals = approximate(a) == b;