std.range.put vs R.put: Best practices?
Jon Degenhardt via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Mon Aug 21 02:07:23 PDT 2017
On Monday, 21 August 2017 at 05:58:01 UTC, Jonathan M Davis wrote:
> On Monday, August 21, 2017 02:34:23 Mike Parker via
> Digitalmars-d-learn wrote:
>> 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?
>>
>> 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.
>
> To add to that, the free function put handles putting different
> character types to a range of characters (IIRC, it also handles
> putting entire strings as well), whereas a particular
> implementation of put probably doesn't. In principle, a
> specific range type could do everything that the free function
> does, but it's highly unlikely that it will.
>
> In general, it's really just better to use the free function
> put, and arguably, we should have used a different function
> name for the output ranges themselves with the idea that the
> free function would always be the one called, and it would call
> the special function that the output ranges defined.
> Unfortunately, however, that's not how it works. In general,
> IMHO, output ranges really weren't thought out well enough.
> It's more like they were added as a countepart to input ranges
> because Andrei felt like they needed to be there rather than
> having them be fully fleshed out on their own. The result is a
> basic idea that's very powerful but that suffers in the details
> and probably needs at least a minor redesign (e.g. the output
> API has no concept of an output range that's full).
>
> In any case, I'd just suggest that you never use put with UFCS.
> Unfortunately, if you're using UFCS enough, it becomes habit to
> just call the function as if it were a member function, which
> is then a problem when using output ranges, but we're kind of
> stuck at this point. On the bright side, it's really only
> likely to cause issues in generic code where the member
> function might work with your tests but not everything that's
> passed to it. In other cases, if what you're doing doesn't work
> with the member function, then the code won't compile, and
> you'll know to switch to using the free function.
>
Mike, Jonathan - Thanks for the detailed responses!
Yes, by habit I use UFCS, there is where potential for the wrong
call comes from. I agree also that output ranges are very
powerful in concept, but the details are not fully fleshed out at
this point. A few enhancements could make it much more compelling.
--Jon
More information about the Digitalmars-d-learn
mailing list