May 04, 2012
On 2012-05-04 18:32, Jakob Ovrum wrote:

> 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...).

I can't recall I ever had a use case where I wanted to do some operation on a collection and then transforming it to another type of collection. I just want to perform the operation, then get back a collection of the same type:

int[] a = [3, 4, 5, 6 ,7];
a = a.filter!(x => x < 6);

Since that's not possible with the way ranges are designed I was thinking if it at least would be possible to have a generic interface to get the a collection (of the same type) out of the range.

-- 
/Jacob Carlborg
May 04, 2012
On 2012-05-04 19:15, Jonathan M Davis wrote:
> On Friday, May 04, 2012 13:46:33 Jacob Carlborg wrote:
>> I give up. Apparently you don't think it's useful.
>
> If you can come up with an example/reason why it would actually be useful,
> then great. But I don't see why it would ever matter what the original
> container type really was.
>
> You need the original range type in cases like std.container's remove
> function, but then the range must _be_ the original range type from that exact
> container in order to work, and there's no way that you could turn a wrapped
> range into the proper range for that, since you'd have to create a new
> container, and then the resultant range would be for the wrong container. And
> that's the only situation that I can think of where it really matters what the
> original container type was. If you want to construct a new container out of a
> range, then great, but since it's a new container, I don't see how it matters
> what the original container was unless you intend to assign the result to the
> new container or somesuch, in which case, you would already have access to the
> type, because you'd have a variable to assign to.
>
> - Jonathan M Davis

I have no problem if there's a new collection. I'm saying of the same _type_, not the same _collection_. As I've said in other posts in this thread, I mostly just want to assign the result of a range operation back to the original variable. Preferably I would like to not have to call any extra functions or constructors but that's not how ranges work.

-- 
/Jacob Carlborg
May 04, 2012
On Friday, 4 May 2012 at 19:17:13 UTC, Steven Schveighoffer wrote:
> This one:
>
> Collection c = new Collection();
> c = c.filter!(x => x < 3).toCollection();
>
> filter isn't a property of c, it's a range-producing function.  So I only have to define filter once, as a range accepting, range producing function.  And any container type, as long as it can produce a range, can use this as a pseudo method (via UFCS) to make a filtered copy of itself.
>
> -Steve

That's not a real example, that's pretty much the same example I provided below the part you quoted.
May 04, 2012
On Fri, 04 May 2012 16:05:25 -0400, Jakob Ovrum <jakobovrum@gmail.com> wrote:

> On Friday, 4 May 2012 at 19:17:13 UTC, Steven Schveighoffer wrote:
>> This one:
>>
>> Collection c = new Collection();
>> c = c.filter!(x => x < 3).toCollection();
>>
>> filter isn't a property of c, it's a range-producing function.  So I only have to define filter once, as a range accepting, range producing function.  And any container type, as long as it can produce a range, can use this as a pseudo method (via UFCS) to make a filtered copy of itself.
>>
>> -Steve
>
> That's not a real example, that's pretty much the same example I provided below the part you quoted.

First, what would you consider a real example?

Second, there's an important piece of the use case that your sample lacks -- Jacob is rebinding the result back to the original item.

So for example, I could see code like this:

void displayResults(Container c)
{
  if(maxvalue)
     c = c.filter!(x => x < maxvalue).makeContainer!Container();

  // proceed to display elements from c
}

-Steve
May 04, 2012
On 2012-05-04 22:05, Jakob Ovrum wrote:
> On Friday, 4 May 2012 at 19:17:13 UTC, Steven Schveighoffer wrote:
>> This one:
>>
>> Collection c = new Collection();
>> c = c.filter!(x => x < 3).toCollection();
>>
>> filter isn't a property of c, it's a range-producing function. So I
>> only have to define filter once, as a range accepting, range producing
>> function. And any container type, as long as it can produce a range,
>> can use this as a pseudo method (via UFCS) to make a filtered copy of
>> itself.
>>
>> -Steve
>
> That's not a real example, that's pretty much the same example I
> provided below the part you quoted.

Real world example:

https://github.com/jacob-carlborg/dstep/blob/master/dstep/translator/Type.d#L52

I was going to use "until" at row 59, but I couldn't figure out how to transform the range back to a string.

-- 
/Jacob Carlborg
May 04, 2012
On Friday, May 04, 2012 16:37:23 Steven Schveighoffer wrote:
> On Fri, 04 May 2012 16:05:25 -0400, Jakob Ovrum <jakobovrum@gmail.com>
> 
> wrote:
> > On Friday, 4 May 2012 at 19:17:13 UTC, Steven Schveighoffer wrote:
> >> This one:
> >> 
> >> Collection c = new Collection();
> >> c = c.filter!(x => x < 3).toCollection();
> >> 
> >> filter isn't a property of c, it's a range-producing function. So I only have to define filter once, as a range accepting, range producing function. And any container type, as long as it can produce a range, can use this as a pseudo method (via UFCS) to make a filtered copy of itself.
> >> 
> >> -Steve
> > 
> > That's not a real example, that's pretty much the same example I provided below the part you quoted.
> 
> First, what would you consider a real example?
> 
> Second, there's an important piece of the use case that your sample lacks -- Jacob is rebinding the result back to the original item.
> 
> So for example, I could see code like this:
> 
> void displayResults(Container c)
> {
> if(maxvalue)
> c = c.filter!(x => x < maxvalue).makeContainer!Container();
> 
> // proceed to display elements from c
> }

std.container has make, which should do essentially that. And since you have the original container, you know what its type is, so there's no need to query the range for the original container type. Something like this should work:

c = make!Container(filter!(x => x < maxvalue)(c));

If it doesn't, then make and/or the container needs to be improved so that it does.

- Jonathan M Davis
May 04, 2012
On Friday, May 04, 2012 21:24:05 Jacob Carlborg wrote:
> I have no problem if there's a new collection. I'm saying of the same _type_, not the same _collection_. As I've said in other posts in this thread, I mostly just want to assign the result of a range operation back to the original variable.

Well, if you have a variable to assign to, then you know the type already. You don't need to query the range. You just need a way to create an instance of that container from the range. If it's an array, then use std.array.array. If it's a string, you can use std.conv.to (so that you get a string rather than a dstring). If it's standard a container, then std.container.make should do the trick. If it's another type, then as long as the type's constructor takes a range, you can just use the constructor. In general, it should just be one function call.

> Preferably I would like to not have to
> call any extra functions or constructors but that's not how ranges work.

A filter function which returned the same container type as it was passed would be doing something pretty similar to creating a range with the elements that match the predicate and creating a container from that. It might be more efficient depending on exactly how it was done and what the compiler's able to optimize, but it would be far less flexible. Ranges serve as building blocks, allowing us to chain functions in way that would be _really_ ineffecient with containers (using just one function might end up being more efficient, but if every such function in a chain is creating a new container, it would get very inefficient very quickly). Ranges end up being far more powerful. Yes, you then have to worry about putting the range in a container if you really want a container, but it should only take one function call, so I would think that the flexibility that ranges buy you would be well worth that small annoyance.

- Jonathan M Davis
1 2 3 4
Next ›   Last »