On Sunday, 20 August 2017 at 18:08:27 UTC, Jon Degenhardt wrote:
Documentation for std.range.put
(https://dlang.org/phobos/std_range_primitives.html#.put) has
the intriguing line:
put should not be used "UFCS-style", e.g. r.put(e). Doing this
may call R.put directly, by-passing any transformation feature
provided by Range.put. put(r, e) is prefered.
This raises the question of whether std.range.put is always
preferred over calling an output range's 'put' method, or if
there are times when calling an output range's 'put' method
directly is preferred. Also, it seems an easy oversight to
unintentionally call the wrong one.
Does anyone have recommendations or best practice suggestions
for which form to use and when?
--Jon
It's recommended to always use the utility function in std.range
unless you are working with an output range that has a well known
put implementation. The issue is that put can be implemented to
take any number or type of arguments, but as long as it has an
implementation with one parameter of the range's element type,
then the utility function will do the right thing internally
whether you pass multiple elements, a single element, an array...
It's particularly useful in generic code where most ranges are
used. But again, if you are working with a specific range type
then you can do as you like. Also, when the output range is a
dynamic array, UFCS with the utility function is fine.
As for mitigating the risk of calling the wrong one, when you do
so you'll either get a compile-time error because of a parameter
mismatch or it will do the right thing. If there's another likely
outcome, I'm unaware of it.