June 26, 2013 Re: mutable constant? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Wednesday, 26 June 2013 at 15:48:42 UTC, Jonathan M Davis wrote:
> It doesn't break anything. It just shows the need for pure.
Really? In the following simplified code I see mutation of an immutable variable, which should not be possible, of course. That is breaking the type system, no? What am I missing?
import std.stdio;
int* point;
struct TplPoint {
int _point;
this(int x) {
_point = x;
point = &_point;
}
}
void main() {
immutable TplPoint my = TplPoint(42);
writeln(my._point); // 42
*point = 13; // uh-oh
writeln(my._point); // 13 !!!
}
|
June 27, 2013 Re: mutable constant? | ||||
---|---|---|---|---|
| ||||
Posted in reply to anonymous | On Thursday, June 27, 2013 01:45:22 anonymous wrote:
> On Wednesday, 26 June 2013 at 15:48:42 UTC, Jonathan M Davis
>
> wrote:
> > It doesn't break anything. It just shows the need for pure.
>
> Really? In the following simplified code I see mutation of an immutable variable, which should not be possible, of course. That is breaking the type system, no? What am I missing?
>
> import std.stdio;
> int* point;
> struct TplPoint {
> int _point;
> this(int x) {
> _point = x;
> point = &_point;
> }
> }
> void main() {
> immutable TplPoint my = TplPoint(42);
> writeln(my._point); // 42
> *point = 13; // uh-oh
> writeln(my._point); // 13 !!!
> }
It looks to me like your code is fundamentally different from the OP's example rather than being a simplification of the original code. In the OP's example, the variable being mutated is a module-level variable, so the immutability of the object is irrelevant when its member function is called (since it's not the object itself which is being mutated). It also has nothing to do with construction.
Your example, on the other hand, is showing a bug with regards to constructing immutable objects in that the object doesn't actually become immutable until it's fully constructed, and the compiler isn't catching something which then violates the impending immutability. I _think_ that that bug has already been reported, but I can't find it at the moment. But regardless, your example is quite different from the OP's example.
- Jonathan M Davis
|
June 27, 2013 Re: mutable constant? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Thursday, 27 June 2013 at 00:53:48 UTC, Jonathan M Davis wrote:
> It looks to me like your code is fundamentally different from the OP's example
> rather than being a simplification of the original code. In the OP's example,
> the variable being mutated is a module-level variable, so the immutability of
> the object is irrelevant when its member function is called (since it's not
> the object itself which is being mutated). It also has nothing to do with
> construction.
>
> Your example, on the other hand, is showing a bug with regards to constructing
> immutable objects in that the object doesn't actually become immutable until
> it's fully constructed, and the compiler isn't catching something which then
> violates the impending immutability.
I don't see the fundamental difference. In both versions:
- An immutable struct instance is constructed.
mine: immutable TplPoint my = TplPoint(42);
OP: const TplPoint!float my = TplPoint!float(42, 23);
Note that this does not set my._point to Point(42, 23).
- The constructor stores a mutable pointer to its contents in module scope.
mine: point = &_point;
OP: points ~= &this._point;
- Via that mutable pointer the data is altered.
mine: *point = 13;
OP: a bit more convoluted, TplPoint.ptr does the nasty work, but it could just as well be in main: points[someid].x = somevalue;
=> Immutability broken.
|
June 27, 2013 Re: mutable constant? | ||||
---|---|---|---|---|
| ||||
Posted in reply to anonymous | On Thursday, June 27, 2013 03:31:01 anonymous wrote:
> On Thursday, 27 June 2013 at 00:53:48 UTC, Jonathan M Davis wrote:
> > It looks to me like your code is fundamentally different from
> > the OP's example
> > rather than being a simplification of the original code. In the
> > OP's example,
> > the variable being mutated is a module-level variable, so the
> > immutability of
> > the object is irrelevant when its member function is called
> > (since it's not
> > the object itself which is being mutated). It also has nothing
> > to do with
> > construction.
> >
> > Your example, on the other hand, is showing a bug with regards
> > to constructing
> > immutable objects in that the object doesn't actually become
> > immutable until
> > it's fully constructed, and the compiler isn't catching
> > something which then
> > violates the impending immutability.
>
> I don't see the fundamental difference. In both versions:
>
> - An immutable struct instance is constructed.
> mine: immutable TplPoint my = TplPoint(42);
> OP: const TplPoint!float my = TplPoint!float(42, 23);
> Note that this does not set my._point to Point(42, 23).
>
> - The constructor stores a mutable pointer to its contents in
> module scope.
> mine: point = &_point;
> OP: points ~= &this._point;
>
> - Via that mutable pointer the data is altered.
> mine: *point = 13;
> OP: a bit more convoluted, TplPoint.ptr does the nasty work, but
> it could just as well be in main: points[someid].x = somevalue;
>
> => Immutability broken.
You're right. I didn't read over the OP's example carefully enough. The mutation is being done to a module-level variable in an inout function, which is completely legit. I thought that what the OP thought was wrong was mutating a module-level variable in a non-mutable function (and that's perfectly fine as long as it's not pure). What I missed (and you didn't) was the fact that that module-level variable was pointing to the contents of the object which was const. And that mutable pointer _is_ being obtained via the constructor just like in your example. And that is most definitely a compiler bug - the same one that your example shows.
- Jonathan M Davis
|
June 27, 2013 Re: mutable constant? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | > You're right. I didn't read over the OP's example carefully enough. The
> mutation is being done to a module-level variable in an inout function, which
> is completely legit. I thought that what the OP thought was wrong was mutating
> a module-level variable in a non-mutable function (and that's perfectly fine as
> long as it's not pure). What I missed (and you didn't) was the fact that that
> module-level variable was pointing to the contents of the object which was
> const. And that mutable pointer _is_ being obtained via the constructor just
> like in your example. And that is most definitely a compiler bug - the same one
> that your example shows.
>
> - Jonathan M Davis
That was exactly my question.
|
Copyright © 1999-2021 by the D Language Foundation