www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - "chain" vs "~"

reply pascal111 <judas.the.messiah.111 gmail.com> writes:
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;
'''
Aug 06 2022
next sibling parent FeepingCreature <feepingcreature gmail.com> writes:
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.
Aug 06 2022
prev sibling next sibling parent reply Emanuele Torre <torreemanuele6 gmail.com> writes:
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: ```D 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 ```
Aug 06 2022
next sibling parent pascal111 <judas.the.messiah.111 gmail.com> writes:
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 "~".
Aug 07 2022
prev sibling parent reply pascal111 <judas.the.messiah.111 gmail.com> writes:
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
Aug 07 2022
parent reply frame <frame86 live.com> writes:
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 "~".
Aug 08 2022
parent pascal111 <judas.the.messiah.111 gmail.com> writes:
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
Aug 08 2022
prev sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
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
Aug 08 2022
parent pascal111 <judas.the.messiah.111 gmail.com> writes:
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!
Aug 08 2022