www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Inconsistent chain (implicitly converts to int)

reply Salih Dincer <salihdb hotmail.com> writes:
Hi everyone,

Technically r1 and r2 are different types of range. Isn't it 
inconsistent to chain both? If not, why is the char type 
converted to int?

```d
import std.stdio,
        std.range;

void main() {
   auto r1 = N!size_t(10, 1, 1);
   auto r2 = N!real(15, .5, 10);

   r1.chain(r2).writeln;
   // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10.5, 11, 11.5, 12, 12.5, 
13, 13.5, 14, 14.5]

   auto a = [97, 98, 99];
   auto b = ['d', 'e', 'f'];

   a.chain(b).writeln;
   // [97, 98, 99, 100, 101, 102]
}

struct N(T)
{
   T last, step, first;
   bool empty() => first >= last;
   T front() => first;
   auto popFront() => first += step;
}
void main() {
   auto r1 = N!size_t(10, 1, 1);
   auto r2 = N!real(15, .5, 10);

   r1.chain(r2).writeln;
   // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10.5, 11, 11.5, 12, 12.5, 
13, 13.5, 14, 14.5]

   auto a = [97, 98, 99];
   auto b = ['d', 'e', 'f'];

   a.chain(b).writeln;
   // [97, 98, 99, 100, 101, 102]
}

struct N(T)
{
   T last, step, first;
   bool empty() => first >= last;
   T front() => first;
   auto popFront() => first += step;
}
```

SDB 79
Apr 05
parent reply "H. S. Teoh" <hsteoh qfbox.info> writes:
On Fri, Apr 05, 2024 at 03:18:09PM +0000, Salih Dincer via Digitalmars-d-learn
wrote:
 Hi everyone,
 
 Technically r1 and r2 are different types of range. Isn't it
 inconsistent to chain both? If not, why is the char type converted to
 int?
[...] It's not inconsistent if there exists a common type that both range element types implicit convert to. The real problem is the implicit conversion of char to int, which I have been against for a long time. Walter, however, disagrees. T -- What's worse than raining cats and dogs? Hailing taxis!
Apr 05
next sibling parent reply rkompass <rkompass gmx.de> writes:
On Friday, 5 April 2024 at 16:05:20 UTC, H. S. Teoh wrote:
 On Fri, Apr 05, 2024 at 03:18:09PM +0000, Salih Dincer via 
 Digitalmars-d-learn wrote:
 Hi everyone,
 
 Technically r1 and r2 are different types of range. Isn't it 
 inconsistent to chain both? If not, why is the char type 
 converted to int?
[...] It's not inconsistent if there exists a common type that both range element types implicit convert to.
In the first example the int's are converted to doubles (also common type). But they appear as int's because writeln does not write a trailing .0.
Apr 05
parent reply Salih Dincer <salihdb hotmail.com> writes:
On Friday, 5 April 2024 at 21:16:42 UTC, rkompass wrote:
 In the first example the int's are converted to doubles (also 
 common type).
 But they appear as int's because writeln does not write a 
 trailing .0.
But it doesn't work as you say! I even tried it on an older version and got the same result. SDB 79
Apr 05
parent reply rkompass <rkompass gmx.de> writes:
On Friday, 5 April 2024 at 21:26:10 UTC, Salih Dincer wrote:
 On Friday, 5 April 2024 at 21:16:42 UTC, rkompass wrote:
 In the first example the int's are converted to doubles (also 
 common type).
 But they appear as int's because writeln does not write a 
 trailing .0.
But it doesn't work as you say! I even tried it on an older version and got the same result. SDB 79
I checked: ```d import std.stdio, std.range, std.algorithm; struct N(T) { T last, step, first; bool empty() => first >= last; T front() => first; auto popFront() => first += step; } void main() { auto r1 = N!size_t(10, 1, 1); auto r2 = N!real(15, .5, 10); // r1.chain(r2).writeln; // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10.5, 11, 11.5, 12, 12.5, 13, 13.5, 14, 14.5] r1.chain(r2).map!(x => typeid(x)).writeln; // [real, real, . . . , real] } ``` and it seems to work as I said.
Apr 06
parent Salih Dincer <salihdb hotmail.com> writes:
On Saturday, 6 April 2024 at 09:21:34 UTC, rkompass wrote:
 I checked:

 ```d
 import std.stdio,
        std.range,
        std.algorithm;

 struct N(T)
 {
   T last, step, first;
   bool empty() => first >= last;
   T front() => first;
   auto popFront() => first += step;
 }

 void main() {
   auto r1 = N!size_t(10, 1, 1);
   auto r2 = N!real(15, .5, 10);
 ```
 and it seems to work as I said.
Thank you for checking again, but it is important to be solution oriented. How about Tuple? Yes, it might be wise to use a tuple in this case: ```d //... auto tuple = a.zip(b); tuple.writeln; // [Tuple!(int, dchar)(97, 'd'), Tuple!(int, dchar)(98, 'e'), Tuple!(int, dchar)(99, 'f')] tuple.map!(num => num[0].to!dchar).write; tuple.map!"a[1]".writeln; // abcdef } ``` SDB 79
Apr 06
prev sibling parent Salih Dincer <salihdb hotmail.com> writes:
On Friday, 5 April 2024 at 16:05:20 UTC, H. S. Teoh wrote:
 On Fri, Apr 05, 2024 at 03:18:09PM +0000, Salih Dincer via 
 Digitalmars-d-learn wrote:
 Hi everyone,
 
 Technically r1 and r2 are different types of range. Isn't it 
 inconsistent to chain both? If not, why is the char type 
 converted to int?
[...] It's not inconsistent if there exists a common type that both range element types implicit convert to. The real problem is the implicit conversion of char to int, which I have been against for a long time. Walter, however, disagrees. T
```d auto a = [97, 98, 99]; auto b = ['d', 'e', 'f']; a.chain(b).map!(chr => chr.to!char).writeln; // abcdef ``` Nice, there is a solution that requires memory allocation, but it still makes you think! However, they can fix this in Phobos3 because now we have this too: https://dlang.org/changelog/2.108.0.html#range_predicate_element PS. I think I unintentionally made a chain by repeating the source code above, sorry :) SDB 79
Apr 05