June 04
On Wed, Jun 04, 2025 at 12:00:57PM -0700, Ali Çehreli via Digitalmars-d-learn wrote:
> On 6/4/25 4:10 AM, Monkyyy wrote:
> > On Wednesday, 4 June 2025 at 02:11:18 UTC, H. S. Teoh wrote:
> >> . But in general, containers should NOT be conflated with ranges. That only leads to wrong design.
> >>
> >> range should NOT mutate the container.  It should be regarded as something separate from the container.
> >
> > Not "general". It's a safety vs speed tradeoff. Immutable whatever's data structure do just make allot of copies or allot of pointer overhead and indirection.

What has this got to do with immutable?  I never said the container should be immutable, only that range over its contents should not mutate it.


T

-- 
Being forced to write comments actually improves code, because it is easier to fix a crock than to explain it. -- G. Steele
June 04
On Wednesday, 4 June 2025 at 19:00:57 UTC, Ali Çehreli wrote:
> On 6/4/25 4:10 AM, Monkyyy wrote:
> > On Wednesday, 4 June 2025 at 02:11:18 UTC, H. S. Teoh wrote:
> >> . But in general, containers should NOT be conflated with
> ranges. That
> >> only leads to wrong design.
> >>
> >> range should NOT mutate the container.  It should be
> regarded as
> >> something separate from the container.
> >
> > Not "general". It's a safety vs speed tradeoff. Immutable
> whatever's
> > data structure do just make allot of copies or allot of
> pointer overhead
> > and indirection.
>
> I don't understand. Like H. S. Teoh said, a range over a container should not alter the container. I'm not aware of any data structure where that's not the case.
>
> If a container has a way of accessing the elements (which it definitely has to because otherwise it's not really a container), then a light-weight range can be specified over the elements.
>
> Ali

Iota should mutate the underlining data and does. Unjustifiably slices are in the weird limbo, the autodecoding's popFront is raw mutation. I think the some of the rng primitives also just mutate. Nullable is a range for some God-Forsaken reason, it would have to mutate data.

And thats just whats in phoboes rn, not even stuff Id write(op said he had a set and was worried about the speed).

The purist "view of data" came after, and stuff like sorting *absolutely shouldnt* be held to it.

Trade offs. 80% of datastructures and 90% of algorthims should be functional-y; but dont go full purist.

June 04
On 6/4/25 12:53 PM, monkyyy wrote:

> Iota should mutate the underlining data and does.

There is no underlying data for some ranges like iota because they are generators. Yes, it's a complication that D uses the term "range" for generators as well.

> Unjustifiably slices
> are in the weird limbo,

My mental model of slices differ from many old-timer D people here. There is no limbo in my mental model: Slices are always a lightweight interface (i.e. the range) to contained elements.

What is missing in D language is that there is always a container of elements that the slice provides access to. The fact that the container (the array) not having a name causes the confusion. People necessarily say "add an element to the slice". That is not accurate in my mental model: The element is always added to the container, the slice is just an interface to it.

Yes, it's weird that an element accessor is capable of adding elements to the unnamed array. I accept my mental model despite this weirdness.

> the autodecoding's popFront is raw mutation.

As the following example shows, there is no mutation to the contained elements though. Only the slice (the range) changes:

import std.range : popFront;

void main() {
    auto slice1 = [ 1, 10, 42 ];

    auto slice2 = slice1;
    slice2.popFront();

    assert(slice1 == [ 1, 10, 42 ]);    // <-- No mutation
}

> I
> think the some of the rng primitives also just mutate. Nullable is a
> range for some God-Forsaken reason, it would have to mutate data.

I wasn't aware of that. I wonder whether someone thought it would improve generality? But that topic is beside the point here, which was the separation of containers and ranges.

Ali

June 04
On Wednesday, 4 June 2025 at 20:34:30 UTC, Ali Çehreli wrote:
> generators
>
> My mental model of slices differ
> > I
> > think the some of the rng primitives also just mutate.
> Nullable is a
> > range for some God-Forsaken reason, it would have to mutate
> data.
>
> I wasn't aware of that. I wonder whether someone thought it would improve generality? But that topic is beside the point here, which was the separation of containers and ranges.
>
> Ali

Nullable is a 1 or 0 length container which did not need to have a [] called on it; and I dont really want to hear you call it a generator.

Your already making an exception for the "ranges are views of data"; its just not surviving contact with all counter examples.
June 04

On Tuesday, 3 June 2025 at 16:03:15 UTC, Andy Valencia wrote:

>

I have a situation where chain()'ing them together would be convenient, but InputRange requires front() and popFront().

As an exercise in chaining opApply based containers, I tried:

// Chain across containers; their type is T and what they hold is type B
class Chain(T,B) {
    private T[] members;
    this(T...)(T args) {
        foreach(m; args) {
            this.members ~= *m;
        }
    }
    int
    opApply(int delegate(ref B) ops) const {
        int res = 0;
        foreach(m; this.members) {
            foreach(val; m) {
                res = ops(val);
                if (res) {
                    break;
                }
            }
        }
        return res;
    }
}

I'm a little iffy on the walk of the args and the *m deref. But it tests out OK in practice. Using one looks like:

    import tiny.set : Set;
    alias SetInt = Set!int;

    auto s1 = new SetInt();
    s1.add(1);
    s1.add(2);
    s1.add(3);
    auto s2 = new SetInt();
    s2.add(4);
    s2.add(5);
    s2.add(6);
    auto s3 = new SetInt();
    foreach(x; new Chain!(SetInt,int)(s1, s2)) {
        s3.add(x);
    }

Andy

1 2
Next ›   Last »