On 1/19/23 10:11 PM, Ruby The Roobster wrote:
Take this example:
```d
import std;
void main()
{
auto c = "a|b|c|d|e".splitter('|');
c.writeln;
string[] e = ["a", "b", "c", "d", "e"];
assert(c.equal(e));
typeof(c).stringof.writeln;
}
```
The program prints:
["a", "b", "c", "d", "e"]
Result
What is the purpose of this 'Result' type? To serve as a generic
range? Because, it seems to only cause problems. For example, you
cannot assign or cast the result type into a range, even when the type
has the same inherent function:
```d
string[] c = "a|b|c|d|e".splitter('|'); // fails
string[] d = cast(string[])"a|b|c|d|e".splitter('|'); // also fails
```
The `Result` type is an internal type that provides a lazily-evaluated
range of the original string. That is, no array is allocated, and the
actual searching of the `|` character isn't done until you start
fetching each element.
It returns windows into the *original* string, and builds each window
one element at a time (via slicing).
So when you say "cast to a range", you are incorrectly stating the type
`string[]` as a "range", when you are trying to cast to an array of
strings. The `Result` type *is* a range, it's a range of strings. But it
is not an array. If you want an array, you can use the `split` function,
which allocates an array to hold all the slices.
And if you need to perform a set operation?
```d
c[] ~= "lolno"; // fails, as [] isn't defined for Result.
```
Right, because a `Result` is not an array. Appending is an array
operation, not a range operation.
Then what is the point of this type, if not to just make things
difficult? It cannot be casted, and vector operations cannot be
performed, and it seems to just serve as an unnecessary generalization.
The point is to be a range over the original input, evaluated lazily.
Using this building block, you can create an array, or use some other
algorithm, or whatever you want. All without allocating more space to
hold an array.
-Steve