The template parameter after a ! without parentheses is always 1 token, so it's never one of the first two interpretations.
Furthermore, the point is that often when writing generic code, you're not supposed to care what the `.d` means specifically. For example, an `InputRange` is defined to have `.front`, `.empty` and `.popFront` properties. Is `.empty` a member variable, function, or constant? Doesn't matter, as long as it results in a boolean.
This does require some getting used to. A common question from newcomers is how to explicitly spell out the type in a situation like this:
import std.algorithm;
void main()
{
auto x = [10, 20, 30].map!(x => x*2);
}
The answer is: you cannot! You know it's an `InputRange`, so you can access `.front`, `.empty`, `.popFront`, and pass it to range functions, but it's not a simple type like `int[]`.
While it's flexible, generic code is also complex. Many D standard library functions don't take a simple `string`, but a 'generic input range of a code unit'. (UTF-8, UTF-16, UTF-32). The resulting template machinery that this spawns is not pleasant to work with, so I understand your concern.
In my own D code, I often use regular arrays, foreach loops and if-statements instead of ranges, map and filter etc.
> Notice that the github links are to line numbers. Line numbers are ephemeral, I don't know a way around that.
If you go to your link, under the button with 3 dots there's a "copy permalink option" that creates a link to the specific commit you're looking at, ensuring the line number doesn't get out of date. Example:
The template parameter after a ! without parentheses is always 1 token, so it's never one of the first two interpretations.
Furthermore, the point is that often when writing generic code, you're not supposed to care what the `.d` means specifically. For example, an `InputRange` is defined to have `.front`, `.empty` and `.popFront` properties. Is `.empty` a member variable, function, or constant? Doesn't matter, as long as it results in a boolean.
This does require some getting used to. A common question from newcomers is how to explicitly spell out the type in a situation like this:
The answer is: you cannot! You know it's an `InputRange`, so you can access `.front`, `.empty`, `.popFront`, and pass it to range functions, but it's not a simple type like `int[]`.
While it's flexible, generic code is also complex. Many D standard library functions don't take a simple `string`, but a 'generic input range of a code unit'. (UTF-8, UTF-16, UTF-32). The resulting template machinery that this spawns is not pleasant to work with, so I understand your concern.
In my own D code, I often use regular arrays, foreach loops and if-statements instead of ranges, map and filter etc.