Thread overview
"chain" vs "~"
Aug 07, 2022
pascal111
Aug 07, 2022
FeepingCreature
Aug 07, 2022
Emanuele Torre
Aug 07, 2022
pascal111
Aug 08, 2022
pascal111
Aug 08, 2022
frame
Aug 08, 2022
pascal111
Aug 08, 2022
Ali Çehreli
Aug 08, 2022
pascal111
August 07, 2022
Why we use "chain" while we have "~":

'''D
int[] x=[1,2,3];
int[] y=[4,5,6];

auto z=chain(x,y);
auto j=x~y;
'''
August 07, 2022

On Sunday, 7 August 2022 at 01:22:18 UTC, pascal111 wrote:

>

Why we use "chain" while we have "~":

'''D
int[] x=[1,2,3];
int[] y=[4,5,6];

auto z=chain(x,y);
auto j=x~y;
'''

Chain doesn't allocate any memory. This can be useful occasionally.

August 07, 2022

On Sunday, 7 August 2022 at 01:22:18 UTC, pascal111 wrote:

>

Why we use "chain" while we have "~":

'''D
int[] x=[1,2,3];
int[] y=[4,5,6];

auto z=chain(x,y);
auto j=x~y;
'''

They are quite different:

  • chain gives you "range" (iterator) that starts from the first element of x and ends at the last element of y (like e.g. zip in other languages).
  • ~ creates a new int[] with elements from x and the elements from y.

If you use z[2] = 10;, you will change x[2] as well, since z is just an iterator of which the third element is the value stored in x[2]; if you use z[4] = 11;, you will change y[1]; if you change y[0], z[3] will also change; etc. (n.b. if you replace x and y with other arrays, then this doesn't apply because then x and y use different memory.)

z is just a range you can use to access the memory of those [1,2,3] and [4,5,6] arrays, not a new array.

Here is some example code to show the differences:

void main()
{
    import std.range : chain;
    import std.stdio : writefln;

    int[] x = [ 1, 2, 3 ];
    int[] y = [ 4, 5, 6 ];

    auto z = chain(x, y);
    auto j = x ~ y;

    writefln("x: %(%s %)", x);
    writefln("y: %(%s %)", y);
    writefln("z: %(%s %)", z);
    writefln("j: %(%s %)", j);

    writefln("----y[1]=10;---");
    y[1] = 10;

    writefln("x: %(%s %)", x);
    writefln("y: %(%s %)", y);
    writefln("z: %(%s %)", z);
    writefln("j: %(%s %)", j);

    writefln("----z[2]=9;----");
    z[2] = 9;

    writefln("x: %(%s %)", x);
    writefln("y: %(%s %)", y);
    writefln("z: %(%s %)", z);
    writefln("j: %(%s %)", j);

    writefln("----j[2]=8;----");
    j[2] = 8;

    writefln("x: %(%s %)", x);
    writefln("y: %(%s %)", y);
    writefln("z: %(%s %)", z);
    writefln("j: %(%s %)", j);
}

output:

x: 1 2 3
y: 4 5 6
z: 1 2 3 4 5 6
j: 1 2 3 4 5 6
----y[1]=10;---
x: 1 2 3
y: 4 10 6
z: 1 2 3 4 10 6
j: 1 2 3 4 5 6
----z[2]=9;----
x: 1 2 9
y: 4 10 6
z: 1 2 9 4 10 6
j: 1 2 3 4 5 6
----j[2]=8;----
x: 1 2 9
y: 4 10 6
z: 1 2 9 4 10 6
j: 1 2 8 4 5 6
August 07, 2022

On Sunday, 7 August 2022 at 03:55:50 UTC, Emanuele Torre wrote:

>

On Sunday, 7 August 2022 at 01:22:18 UTC, pascal111 wrote:

>

[...]

They are quite different:

  • chain gives you "range" (iterator) that starts from the first element of x and ends at the last element of y (like e.g. zip in other languages).
  • ~ creates a new int[] with elements from x and the elements from y.

[...]

I was wondering why they in D repeating ways for the same function, but I know now I'm wrong, "chain" isn't like "~".

August 08, 2022

On Sunday, 7 August 2022 at 03:55:50 UTC, Emanuele Torre wrote:

>

On Sunday, 7 August 2022 at 01:22:18 UTC, pascal111 wrote:

>

[...]

They are quite different:

  • chain gives you "range" (iterator) that starts from the first element of x and ends at the last element of y (like e.g. zip in other languages).
  • ~ creates a new int[] with elements from x and the elements from y.

[...]

In next program, I used "insertInPlace", not "~" nor "chain", should I use "~" or it's the same as "insertInPlace"?

https://github.com/pascal111-fra/D/blob/main/coco.d

August 08, 2022

On Monday, 8 August 2022 at 01:05:40 UTC, pascal111 wrote:

>

In next program, I used "insertInPlace", not "~" nor "chain", should I use "~" or it's the same as "insertInPlace"?

https://github.com/pascal111-fra/D/blob/main/coco.d

As you may noticed, insertInPlace has another purpose than just appending data. And it will create a new range (to call itself again), moves memory and places the item there, so it's rather inefficient than just appending a single item via "~".

August 08, 2022
On 8/6/22 18:22, pascal111 wrote:
> Why we use "chain" while we have "~":
>
> '''D
> int[] x=[1,2,3];
> int[] y=[4,5,6];
>
> auto z=chain(x,y);
> auto j=x~y;
> '''

To add to what has already mentioned,

- chain can be used on ranges that are of different element types

- as usual, some of the ranges may be generators

- although obscure, one may sort in-place over multiple ranges (requires RandomAccessRange.)

This program shows the first two points:

import std; // Apologies for terseness

void main() {
  auto ints = [ 10, 3, 7 ];
  auto squares = iota(10).map!squared.take(5);
  auto doubles = [ 1.5, -2.5 ];
  auto c = chain(ints, squares, doubles);

  // Different types but CommonType is 'double' here:
  static assert(is(ElementType!(typeof(c)) == double));

  // Prints [10, 3, 7, 0, 1, 4, 9, 16, 1.5, -2.5]
  writeln(c);
}

auto squared(T)(T value) {
  return value * value;
}

And this one shows how one can sort in-place multiple arrays:

import std; // Ditto

void main() {
  auto a = [ 10, 3, 7 ];
  auto b = [ 15, -25 ];

  auto c = chain(a, b);
  sort(c);

  writeln(a);  // Prints [-25, 3, 7]
  writeln(b);  // Prints [10, 15]
}

Ali

August 08, 2022
On Monday, 8 August 2022 at 13:26:49 UTC, frame wrote:
> On Monday, 8 August 2022 at 01:05:40 UTC, pascal111 wrote:
>
>> In next program, I used "insertInPlace", not "~" nor "chain", should I use "~" or it's the same as "insertInPlace"?
>>
>> https://github.com/pascal111-fra/D/blob/main/coco.d
>
> As you may noticed, `insertInPlace` has another purpose than just appending data. And it will create a new range (to call itself again), moves memory and places the item there, so it's rather inefficient than just appending a single item via "~".

I applied "~" in next program:

https://github.com/pascal111-fra/D/blob/main/proj06.d
August 08, 2022
On Monday, 8 August 2022 at 18:49:26 UTC, Ali Çehreli wrote:
> On 8/6/22 18:22, pascal111 wrote:
> > [...]
>
> To add to what has already mentioned,
>
> - chain can be used on ranges that are of different element types
>
> [...]

Thanks for explanation!