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