www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Weird const behavior

reply =?UTF-8?B?U2ltw7NuIE9yb8Oxbw==?= <sron611 gmail.com> writes:
I have the following piece of code:


``````````````````````

/+ dub.sdl:
     name: day2
+/
import std.algorithm.iteration : group;
import std.stdio;

void main() {
     const auto a = group("simon");
     auto b = group("simon");
     writeln(a == b);
     writeln();
     writeln(a);
     writeln();
     writeln(b);
}
``````````````````````

When I run it, it gives me this output:

``````````````````````
true

const(Group!("a == b", string))("imon", Tuple!(dchar, uint)('s', 
1))

[Tuple!(dchar, uint)('s', 1), Tuple!(dchar, uint)('i', 1), 
Tuple!(dchar, uint)('m', 1), Tuple!(dchar, uint)('o', 1), 
Tuple!(dchar, uint)('n', 1)]
``````````````````````

The only difference (code-wise) is the `const` keyword. I've 
tried with both `ldc` and `dmd` with same result. Why is the 
output different when the variable is `const`?
Dec 19 2018
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Thursday, 20 December 2018 at 01:37:59 UTC, Simón Oroño wrote:
 The only difference (code-wise) is the `const` keyword. I've 
 tried with both `ldc` and `dmd` with same result. Why is the 
 output different when the variable is `const`?
A const range cannot be iterated by a generic template (without additional work, at least), so writeln just sees it as a blob instead of something it can loop over.
Dec 19 2018
parent reply Marko <marko gmail.com> writes:
On Thursday, 20 December 2018 at 02:05:53 UTC, Adam D. Ruppe 
wrote:
 On Thursday, 20 December 2018 at 01:37:59 UTC, Simón Oroño 
 wrote:
 The only difference (code-wise) is the `const` keyword. I've 
 tried with both `ldc` and `dmd` with same result. Why is the 
 output different when the variable is `const`?
A const range cannot be iterated by a generic template (without additional work, at least), so writeln just sees it as a blob instead of something it can loop over.
I'm not the OP but I'd like to understand this: When he is comparing "a == b" it returns true, but then it diverges on the usability. So a == b compares just values without types? But is this right? I mean if they are equal shouldn't they have the same behavior? Marko.
Dec 20 2018
next sibling parent reply Andrea Fontana <nospam example.org> writes:
On Thursday, 20 December 2018 at 14:49:10 UTC, Marko wrote:
 But is this right? I mean if they are equal shouldn't they have 
 the same behavior?
I don't think so: float a = 1.0; long b = 1; writeln(a == b); writeln(a/2 == b/2);
Dec 20 2018
parent Marko <marko gmail.com> writes:
On Thursday, 20 December 2018 at 15:15:42 UTC, Andrea Fontana 
wrote:
 On Thursday, 20 December 2018 at 14:49:10 UTC, Marko wrote:
 But is this right? I mean if they are equal shouldn't they 
 have the same behavior?
I don't think so: float a = 1.0; long b = 1; writeln(a == b); writeln(a/2 == b/2);
Of course you can play around: uint positive_one = 1; short minus_one = -1; uint max_int = 4294967295; writeln(minus_one > positive_one); // true writeln(minus_one == max_int); // true Because promotion and implicit casting. But like I said this is sometimes confusion, and on the OP example it's worth. Marko.
Dec 20 2018
prev sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 12/20/18 9:49 AM, Marko wrote:
 On Thursday, 20 December 2018 at 02:05:53 UTC, Adam D. Ruppe wrote:
 On Thursday, 20 December 2018 at 01:37:59 UTC, Simón Oroño wrote:
 The only difference (code-wise) is the `const` keyword. I've tried 
 with both `ldc` and `dmd` with same result. Why is the output 
 different when the variable is `const`?
A const range cannot be iterated by a generic template (without additional work, at least), so writeln just sees it as a blob instead of something it can loop over.
I'm not the OP but I'd like to understand this: When he is comparing "a == b" it returns true, but then it diverges on the usability. So a == b compares just values without types? But is this right? I mean if they are equal shouldn't they have the same behavior? Marko.
It's really how opEquals is marked. opEquals for structs (without a specific implementation), is marked as a combination of comparing all the fields, whatever they are marked. Any basic types are comparable whether they are const or not. So most likely the range struct's opEquals is marked const. However, popFront is likely not const. In some rare cases it can be (i.e. an infinite range of a single value). If the range cannot be operated, isInputRange returns false. -Steve
Dec 20 2018
parent Marko <marko gmail.com> writes:
On Thursday, 20 December 2018 at 15:17:31 UTC, Steven 
Schveighoffer wrote:
 It's really how opEquals is marked.

 opEquals for structs (without a specific implementation), is 
 marked as a combination of comparing all the fields, whatever 
 they are marked. Any basic types are comparable whether they 
 are const or not. So most likely the range struct's opEquals is 
 marked const.

 However, popFront is likely not const. In some rare cases it 
 can be (i.e. an infinite range of a single value). If the range 
 cannot be operated, isInputRange returns false.

 -Steve
I know about promotion / implicit casting, but I always find this is a but awkward when comparing objects or structs it's equal but acts differently. But I'm may be the minority. :) Marko.
Dec 20 2018