Transforming a range back to the original type?

Jakob Ovrum jakobovrum at gmail.com
Fri May 4 09:32:39 PDT 2012


On Friday, 4 May 2012 at 15:47:31 UTC, Steven Schveighoffer wrote:
> Yes, a struct can do reference semantics, but it makes little 
> sense to fight the type system and shoehorn it into reference 
> semantics, when classes are reference types by default.

It makes sense when you want something like reference counting.

> I think the use case is, instead of defining some 
> transformation function X as a member of a container, you:
>
> 1. define X as a function that accepts a range and returns a 
> range
> 2. define a way to obtain a range of all elements from a 
> container
> 3. define a way to construct a new container from a range.
>
> Then you only have to define X once, instead of on every 
> container type.  And you can specialize some containers for X 
> because of UFCS.  See Jacob's example.

After a quick look over the thread again, I still don't see any 
real examples of use cases from Jacob (I admit I could still be 
missing it... somewhere...).

Here's one scenario I came up with just now, anyway:

T transmogrify(T)(T input) if(isInputRange!T)
{
     auto transformed = map!foo(input);
     return makeContainer!T(transformed);
}

So basically, a templated function which, for some reason, wants 
to return the same type it receives. I still can't think of a 
real example similar to the above toy example, though. If the 
input just has to be an input range, isn't the output fine as an 
input range too? Isn't it better to leave the decision to the 
caller (whichever function on the way up the stack has the 
concrete types) of whether to do the expensive reconstruction 
operation? The code smells, is all I can say.

So, I think the question is still whether such a function is 
appropriate for the standard library.


> Most definitely.  I think any D-based container that can't be 
> constructed from a range of values isn't worth implementing.

I agree, and I think the most natural way to implement this 
abstract interface would be using the constructor, but Jacob 
mentioned functions like toList() etc. earlier in the thread. 
Using the constructor is more idiomatic if Phobos is any example, 
but I suppose there could be reasons for not using it.

(Obviously, array() only exists because there is no choice, 
slices being in-built).

> Yes, I realized this after posting, but figured the point would 
> get across ;)  I sometimes miss being able to do this in my 
> real code, the omission of parentheses for template 
> instantiation is an awesome feature!

It's always sad to see code failing to leverage it; often pops up 
with string tokens. It does make templates heaps less 
intimidating, and I applaud Andrei (sorry if this attribution is 
wrong!) for it :)



More information about the Digitalmars-d-learn mailing list