Hacker News new | ask | show | jobs
by dkorpel 1662 days ago
> b!(c.d)(a)

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.

2 comments

Andrei and I have come to the conclusion that many of the library functions are overly generalized.
The trick is, most newcomers aren't just bothered by auto and would like the explicit type here. What they want to do is actually pass that output into another method. And in that method they need to know the type. I mean, you could accept input range in the method, but then you are losing some typing information.