June 20, 2020
On Saturday, 20 June 2020 at 12:42:01 UTC, Stanislav Blinov wrote:
> On Saturday, 20 June 2020 at 10:43:41 UTC, Paul Backus wrote:
>
>> Also, switch from `void popFront()` to `typeof(this) rest`, so that we can have `const` and `immutable` ranges.
>
> *Switch* is probably too restrictive. For a given range a `popFront` may be more efficient than a `range = range.rest`. Making `rest` a valid range primitive though, and using where appropriate - that'd be awesome.

Yes, that may be a valid concern, I have thought about this as well.

The main issue is for some kinds of iterables, like alias sequences, we have no choice but to use an immutable-friendly API like rest/dropOne or concat (not append). A couple of years ago I was able to write proof-of-concept library that had accumulate, map, and filter implementations that worked with both ranges and template parameter sequences, based on immutable-friendly functions like this

See:

https://github.com/PetarKirov/rxd/blob/v0.0.3/source/rxd/xf/xform.d

Some of the technics that I had developed allowed me to implement UFCS-enabled alternatives to std.meta that accept a polymorphic lambda parameter for mapping/filtering/etc.:

https://gist.github.com/PetarKirov/a808c94857de84858accfb094c19bf77

June 20, 2020
On Saturday, 20 June 2020 at 12:30:43 UTC, Stanislav Blinov wrote:
> On Saturday, 20 June 2020 at 11:20:13 UTC, Petar Kirov [ZombineDev] wrote:
>
>> As far as I know, back when the ranges API was worked on postblit ctors didn't work reliably, so .save() was the only option.
>
> Funny that, at the moment it's the copy ctors that aren't working reliably (e.g. they're not working at all with arrays). :)

You mean that array.dup doesn't work if the element type uses copy constructors? I haven't checked so I guess it's a problem indeed, though this shouldn't affect the ranges themselves (i.e. array slices).

>> If it had worked, we could require that non-forward ranges are non-copyable.
>
> I can imagine this would be quite some work to adapt all of Phobos to *that*. I mean, things like
>
> auto rem = makeSomeInputRange.find!pred;
> auto flt = makeSomeInputRange.filter!pred;
>
> Those would not compile. They could be made to compile by `move`ing the argument for the return. But then you still won't be able to pass those results around, unless via a refRange or `move`.

Yeah, I know. Though input-only range are odd in general. I think they can only work well either if the code moves them around, or if they use reference semantics (classes or refRange).
June 20, 2020
On Saturday, 20 June 2020 at 12:42:01 UTC, Stanislav Blinov wrote:
> On Saturday, 20 June 2020 at 10:43:41 UTC, Paul Backus wrote:
>
>> Also, switch from `void popFront()` to `typeof(this) rest`, so that we can have `const` and `immutable` ranges.
>
> *Switch* is probably too restrictive. For a given range a `popFront` may be more efficient than a `range = range.rest`. Making `rest` a valid range primitive though, and using where appropriate - that'd be awesome.

For non-forward ranges, there's no promise that the original range (or any copies of it) will remain valid after calling `rest`, so you can always implement `rest` like this:

    auto rest() {
        this.popFront;
        return this;
    }
June 20, 2020
On Saturday, 20 June 2020 at 12:30:43 UTC, Stanislav Blinov wrote:
>> If it had worked, we could require that non-forward ranges are non-copyable.
>
> I can imagine this would be quite some work to adapt all of Phobos to *that*. I mean, things like
>
> auto rem = makeSomeInputRange.find!pred;
> auto flt = makeSomeInputRange.filter!pred;
>
> Those would not compile. They could be made to compile by `move`ing the argument for the return. But then you still won't be able to pass those results around, unless via a refRange or `move`.

https://github.com/WalterBright/DIPs/blob/13NNN-WGB.md/DIPs/13NNN-WGB.md
June 20, 2020
On Saturday, 20 June 2020 at 13:01:33 UTC, Petar Kirov [ZombineDev] wrote:

> You mean that array.dup doesn't work if the element type uses copy constructors? I haven't checked so I guess it's a problem indeed, though this shouldn't affect the ranges themselves (i.e. array slices).

Yes, Razvan Nitu is working on a fix for .dup already. But there's lots more. The ~= also doesn't call copy ctor. Nor does copying of slices and static arrays, i.e.

S[10] arr;
auto brr = arr; // no copy ctors called
arr[0 .. 2] = arr[2 .. 4]; // no copy ctors called

While .dup/.idup are a druntime-only fix, the rest requires fixes in the compiler.

It may be of small concern to ranges themselves (barring ranges-of-ranges), but a concern nonetheless.

> Yeah, I know. Though input-only range are odd in general. I think they can only work well either if the code moves them around, or if they use reference semantics (classes or refRange).

But if they *do* use reference semantics, they need be copyable (see e.g. std.stdio.ByLineImpl). Requiring them to become classes I'd say would be too harsh. That said, I agree that most of them would be a consume-and-throw-away (i.e. temporaries). But there's always an odd case where you'd want to consume them in staggered steps.
June 20, 2020
On Saturday, 20 June 2020 at 13:07:41 UTC, Paul Backus wrote:
> On Saturday, 20 June 2020 at 12:42:01 UTC, Stanislav Blinov wrote:
>> On Saturday, 20 June 2020 at 10:43:41 UTC, Paul Backus wrote:
>>
>>> Also, switch from `void popFront()` to `typeof(this) rest`, so that we can have `const` and `immutable` ranges.
>>
>> *Switch* is probably too restrictive. For a given range a `popFront` may be more efficient than a `range = range.rest`. Making `rest` a valid range primitive though, and using where appropriate - that'd be awesome.
>
> For non-forward ranges, there's no promise that the original range (or any copies of it) will remain valid after calling `rest`, so you can always implement `rest` like this:
>
>     auto rest() {
>         this.popFront;
>         return this;
>     }

For sure. I'm just pointing out that *switching* to `rest` isn't a likely way to go. I.e. that would've implied dropping the use of popFront altogether :) *Adopting* `rest` - yes, +100%.
June 20, 2020
On Saturday, 20 June 2020 at 13:09:54 UTC, Paul Backus wrote:

> https://github.com/WalterBright/DIPs/blob/13NNN-WGB.md/DIPs/13NNN-WGB.md

I'm well aware, that one is a much needed enhancement. But it's a long ways away, and would have to be adapted to through quite a process of its own.
June 20, 2020
On Saturday, 20 June 2020 at 13:29:43 UTC, Stanislav Blinov wrote:
> On Saturday, 20 June 2020 at 13:07:41 UTC, Paul Backus wrote:
>> On Saturday, 20 June 2020 at 12:42:01 UTC, Stanislav Blinov wrote:
>>> On Saturday, 20 June 2020 at 10:43:41 UTC, Paul Backus wrote:
>>>
>>>> Also, switch from `void popFront()` to `typeof(this) rest`, so that we can have `const` and `immutable` ranges.
>>>
>>> *Switch* is probably too restrictive. For a given range a `popFront` may be more efficient than a `range = range.rest`. Making `rest` a valid range primitive though, and using where appropriate - that'd be awesome.
>>
>> For non-forward ranges, there's no promise that the original range (or any copies of it) will remain valid after calling `rest`, so you can always implement `rest` like this:
>>
>>     auto rest() {
>>         this.popFront;
>>         return this;
>>     }
>
> For sure. I'm just pointing out that *switching* to `rest` isn't a likely way to go. I.e. that would've implied dropping the use of popFront altogether :) *Adopting* `rest` - yes, +100%.

By "switching", I just mean that `std.v2.range.isInputRange` would only check for `rest`, not `popFront`, and that new code would be free to only implement `rest`. Naturally, we would also provide free-function versions of `rest` and `popFront` for compatibility between the two APIs.
June 20, 2020
On 6/20/20 12:34 AM, H. S. Teoh wrote:
> On Fri, Jun 19, 2020 at 09:14:30PM -0400, Andrei Alexandrescu via Digitalmars-d wrote:
> [...]
>> One good goal for std.v2020 would be to forego autodecoding
>> throughout.
> [...]
> 
> Another could be to fix up the range API -- i.e, reconsider the ugliness
> that is .save, now that D has copy ctors.

Awesome. So we have a lil list already.

June 20, 2020
On Saturday, 20 June 2020 at 12:26:55 UTC, Petar Kirov [ZombineDev] wrote:
> [snip]
>
> typeof(this) is only possible for member function based implementations. Otherwise the implementation for arrays would be:
>
> inout(T)[] rest(T)(input(T)[] array) { return array[1 .. $]; }
>
> https://run.dlang.io/gist/run-dlang/7a4e5872ee26c083b916303fe36ac43b?compiler=dmd

Gotcha, thanks.