View mode: basic / threaded / horizontal-split · Log in · Help
May 02, 2012
Transforming a range back to the original type?
Is there a general function for transforming a range back to the 
original type? If not, would it be possible to create one?

-- 
/Jacob Carlborg
May 02, 2012
Re: Transforming a range back to the original type?
On 05/02/2012 05:01 PM, Jacob Carlborg wrote:
> Is there a general function for transforming a range back to the
> original type? If not, would it be possible to create one?
>

I believe std.array's array function does what you want.
-Matt
May 02, 2012
Re: Transforming a range back to the original type?
On Wednesday, May 02, 2012 23:01:21 Jacob Carlborg wrote:
> Is there a general function for transforming a range back to the
> original type? If not, would it be possible to create one?

You mean that if you have something like

auto range = getRangeFromSomewhere();
auto newRange = find(filter!func(range), value);

you want to transform newRange back to the same type as range?

I don't believe that that's possible in the general case. For example, take

Array!int a = getArrayFromSomewhere(0;
auto range = a[];
auto newRange = find(filter!"a < 7"(range), 2);

The type of a[] is specific to Array!int, cannot be created externally from it, 
and is tightly coupled with the container. What if the container held the 
values [1, 7, 2, 9, 42, 0, -2, 4]? newRange would end up having [2 , 0, -2 , 
4], which doesn't correspond to any range of elements in the Array. So, how 
could you convert newRange to the same type as range? The best that you could 
do as far as I can tell would be to create a new Array!int, put those elements 
in it, and slice the container.

So, I don't see how you could really take an arbitrary range and convert it 
back to its original type. With a very specific set of types, you might be able 
to (e.g. take([1, 2, 4, 9], 3) could be converted back to int[] easily 
enough), but with all of the wrapping that goes on with ranges, even 
determining what type of range is being wrapped by another can't be done 
generically AFAIK, let alone getting the whole chain down to the original 
range, let alone somehow converting the wrapped range back to that type.

Take remove in std.container, for example. It will only take the container's 
range type or the result of take on the container's range type - and it had to 
special case take. And removing a range from a container would be classic 
example of where you need the original range type rather than a wrapper.

- Jonathan M Davis
May 02, 2012
Re: Transforming a range back to the original type?
Jacob Carlborg:
> Is there a general function for transforming a range back to 
> the original type? If not, would it be possible to create one?

The newly redesigned containers in Scala language are often able 
to do this, but this has required the use of a very advanced 
static type system, that is currently not in D (maybe there are 
ways to implement it with D templates, but it will require work 
to implement).
Currently there is array.array() that turns the range into a 
dynamic array.

Probably some types/data structures will have a way to turn a 
lazy range into one of them.

Bye,
bearophile
May 03, 2012
Re: Transforming a range back to the original type?
On Wed, 02 May 2012 23:01:21 +0200, Jacob Carlborg <doob@me.com> wrote:

> Is there a general function for transforming a range back to the  
> original type? If not, would it be possible to create one?

In addition to std.array.array, as others have pointed out,
there is also std.range.InputRangeObject.
May 03, 2012
Re: Transforming a range back to the original type?
On 2012-05-02 23:07, Matt Soucy wrote:
> On 05/02/2012 05:01 PM, Jacob Carlborg wrote:
>> Is there a general function for transforming a range back to the
>> original type? If not, would it be possible to create one?
>>
>
> I believe std.array's array function does what you want.
> -Matt

I was thinking of a generic function that works for all types of 
collections and not arrays.

-- 
/Jacob Carlborg
May 03, 2012
Re: Transforming a range back to the original type?
On 2012-05-02 23:40, Jonathan M Davis wrote:
> On Wednesday, May 02, 2012 23:01:21 Jacob Carlborg wrote:
>> Is there a general function for transforming a range back to the
>> original type? If not, would it be possible to create one?
>
> You mean that if you have something like
>
> auto range = getRangeFromSomewhere();
> auto newRange = find(filter!func(range), value);
>
> you want to transform newRange back to the same type as range?

No, I want to transform newRange back to a collection, the same type as 
the original collection. I was thinking something like this:

Collection c = new Collection();
c = c.filter!(x => x < 3).toCollection();

-- 
/Jacob Carlborg
May 03, 2012
Re: Transforming a range back to the original type?
On 2012-05-03 09:43, Simen Kjaeraas wrote:

> In addition to std.array.array, as others have pointed out,
> there is also std.range.InputRangeObject.

I'm not sure if I understand what InputRangeObject does. But I don't 
think it does what I want.

-- 
/Jacob Carlborg
May 03, 2012
Re: Transforming a range back to the original type?
On Thu, 03 May 2012 13:17:40 +0200, Jacob Carlborg <doob@me.com> wrote:

> On 2012-05-03 09:43, Simen Kjaeraas wrote:
>
>> In addition to std.array.array, as others have pointed out,
>> there is also std.range.InputRangeObject.
>
> I'm not sure if I understand what InputRangeObject does. But I don't  
> think it does what I want.

It basically wraps a range in a class interface. This allows you to use
InputRangeObject!T instead of T[]. I've never used it, so I'm not sure
what it does or how it does it.
May 03, 2012
Re: Transforming a range back to the original type?
On 02/05/2012 22:01, Jacob Carlborg wrote:
> Is there a general function for transforming a range back to the original type? If not,
> would it be possible to create one?

To sum it up, it can't be done in the general case.  The range API doesn't know or care 
about the underlying data structure.  That's half the point of it.  The underlying data 
structure might not even exist.  An example is a range used as a file stream, a random 
number generator or to lazily generate a mathematical sequence.

Moreover, what would you want such a function to return if the range is:
- a file stream with a cache
- an array wrapper to loop infinitely through it?
- a concatenation of ranges that may be of different types?

Moreover, even if there were some "range with an underlying container" classification, it 
would be an extra burden on the writer of the range wrapper to implement this.

If you want to generate a range that views a container in a certain way, and then 
construct a container of the original type (or indeed any type) from that range, then 
create the container and then use a foreach loop on the range (or a .save of it, if you 
want to keep the range afterwards) to put the data into the container.

Stewart.
« First   ‹ Prev
1 2 3 4
Top | Discussion index | About this forum | D home