Thread overview | ||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
May 19, 2016 mutable keyword | ||||
---|---|---|---|---|
| ||||
Is there D equivalent of C++'s mutable keyword? Like the one that allows to modify a field of struct from constant method. Or some alternative solution? |
May 19, 2016 Re: mutable keyword | ||||
---|---|---|---|---|
| ||||
Posted in reply to ciechowoj | On Thursday, 19 May 2016 at 20:44:54 UTC, ciechowoj wrote: > Is there D equivalent of C++'s mutable keyword? Like the one that allows to modify a field of struct from constant method. Or some alternative solution? There isn't an equivalent of mutable keyword because D const differs from C++ const. D const has stronger guarantees (nothing reachable from const object will be mutable) so you'll use it less often compared to C++. There's a talk on usage of const in D and I think its author also wrote on the subject: https://www.youtube.com/watch?v=mPr2UspS0fE |
May 19, 2016 Re: mutable keyword | ||||
---|---|---|---|---|
| ||||
Posted in reply to ciechowoj | On Thursday, 19 May 2016 at 20:44:54 UTC, ciechowoj wrote:
> Is there D equivalent of C++'s mutable keyword? Like the one that allows to modify a field of struct from constant method. Or some alternative solution?
A little personal experience. I wrote a tool that had certain flags that did things turned on by default, and turning them off using other flags. This seemed the best choice at the time, but upon later reflection it's hard to remember details you'd not think about unless you wanted them active. Think about a simple action like 'get home', which you also have to 'turn sink off, don't change bedding, don't shave, don't walk dog' because otherwise you have to do all those when all you planned when getting home was taking a shower and going to bed. Remembering to add all the flags/changes/options for the utility quickly was becoming a pain, to which I reverted my options to only be on when called/intended them rather than thinking them on by default was the best option.
As for mutable. It's mutable unless you specify otherwise, and the whole object as a whole can be immutable/const; Don't complicate the rules so "it's const (except when it's not)" logic, either make it intentionally const/immutable or don't.
|
May 19, 2016 Re: mutable keyword | ||||
---|---|---|---|---|
| ||||
Posted in reply to ciechowoj | On Thursday, May 19, 2016 20:44:54 ciechowoj via Digitalmars-d-learn wrote:
> Is there D equivalent of C++'s mutable keyword? Like the one that allows to modify a field of struct from constant method. Or some alternative solution?
No. D's const and immutable provide no backdoors. Rather, they provide strong guarantees. So, if a variable is const, then it cannot be mutated (even internally) except via a mutable reference to the same data. This has the upside that you can rely on a const object not mutating on you unless you're also messing around with mutable referencs to the same data, but it has the downside that you can't do things like caching or lazy initialization, and you can't have portions of a const object be treated as mutable. You can cast away const, but it's undefined behavior if you mutate afterwards (and could result in subtle bugs depending on what optimizations the compiler does). So, it's not going to provide a backdoor around const's strong guarantees about mutation.
The result is that if you need something like C++'s mutable, you can't use D's const. You're stuck using mutable values and are forced to avoid const.
Now, if your functions aren't pure, you can put state outside of the object itself and have a const member function access and mutate that external state, but that's not exactly great for encapsulation, and then you can't use that function in pure code. But it's the closest thing to a backdoor from const that exists in D, because const is set up so that it's actually const and not just const until the implementation decides to mutate it anyway. Whether that's better or worse than C++'s const depends on what you're trying to do, but the reality of the matter is that D's const is ultimately very different from C++'s const because of how restrictive it is. You get better guarantees but can't use it anywhere near as much precisely because of the restrictions that are required to provide those guarantees.
- Jonathan M Davis
|
May 20, 2016 Re: mutable keyword | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Thursday, 19 May 2016 at 23:21:14 UTC, Jonathan M Davis wrote:
> On Thursday, May 19, 2016 20:44:54 ciechowoj via Digitalmars-d-learn wrote:
>> Is there D equivalent of C++'s mutable keyword? Like the one that allows to modify a field of struct from constant method. Or some alternative solution?
>
> No. D's const and immutable provide no backdoors.
But you can cheat:
----
int* _id;
struct A
{
int id = 0;
this(int id)
{
this.id = id;
_id = &this.id;
}
void change() const
{
(*_id)++;
}
}
void main() {
import std.stdio;
A a = A(42);
a.change();
writeln(a.id);
}
----
|
May 20, 2016 Re: mutable keyword | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On Friday, 20 May 2016 at 17:28:55 UTC, Namespace wrote:
> But you can cheat:
You can just cast const away:
struct A {
int id = 0;
this(int id) {
this.id = id;
}
void change() const {
(cast() id)++;
}
}
void main() {
import std.stdio;
A a = A(42);
a.change();
writeln(a.id);
}
|
May 20, 2016 Re: mutable keyword | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Applegame | On 05/20/2016 08:23 PM, Jack Applegame wrote:
> You can just cast const away:
> struct A {
> int id = 0;
>
> this(int id) {
> this.id = id;
> }
>
> void change() const {
> (cast() id)++;
> }
> }
That's not a valid D program, though.
|
May 20, 2016 Re: mutable keyword | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Thursday, 19 May 2016 at 23:21:14 UTC, Jonathan M Davis wrote:
> On Thursday, May 19, 2016 20:44:54 ciechowoj via Digitalmars-d-learn wrote:
>> Is there D equivalent of C++'s mutable keyword? Like the one that allows to modify a field of struct from constant method. Or some alternative solution?
>
> Now, if your functions aren't pure, you can put state outside of the object itself and have a const member function access and mutate that external state, but that's not exactly great for encapsulation, and then you can't use that function in pure code. But it's the closest thing to a backdoor from const that exists in D, because const is set up so that it's actually const and not just const until the implementation decides to mutate it anyway. Whether that's better or worse than C++'s const depends on what you're trying to do, but the reality of the matter is that D's const is ultimately very different from C++'s const because of how restrictive it is. You get better guarantees but can't use it anywhere near as much precisely because of the restrictions that are required to provide those guarantees.
>
> - Jonathan M Davis
Thanks for explanation. It makes implementing things like shared_ptr somewhat troublesome when they are supposed to work in const environment. Isn't there a way to escape a pure environment (like trusted for safe)? Or/and would modifying an external state from pure function be an undefined behavior?
|
May 20, 2016 Re: mutable keyword | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Applegame | On Friday, 20 May 2016 at 18:23:26 UTC, Jack Applegame wrote:
> On Friday, 20 May 2016 at 17:28:55 UTC, Namespace wrote:
>> But you can cheat:
> You can just cast const away:
> struct A {
> int id = 0;
>
> this(int id) {
> this.id = id;
> }
>
> void change() const {
> (cast() id)++;
> }
> }
>
> void main() {
> import std.stdio;
>
> A a = A(42);
> a.change();
>
> writeln(a.id);
> }
Is it valid code (I'm asking about undefined behavior)?
|
May 20, 2016 Re: mutable keyword | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On 05/20/2016 10:28 AM, Namespace wrote: > On Thursday, 19 May 2016 at 23:21:14 UTC, Jonathan M Davis wrote: >> On Thursday, May 19, 2016 20:44:54 ciechowoj via Digitalmars-d-learn >> wrote: >>> Is there D equivalent of C++'s mutable keyword? Like the one that >>> allows to modify a field of struct from constant method. Or some >>> alternative solution? >> >> No. D's const and immutable provide no backdoors. > > But you can cheat: > ---- > int* _id; > > struct A > { > int id = 0; > > this(int id) > { > this.id = id; > _id = &this.id; Point taken but considering that D structs are freely movable value types, I don't think that's a valid D program. The spec does ban self-referencing structs but I think it also bans the code above in spirit. :) > } > > void change() const > { > (*_id)++; > } > } > > void main() { > import std.stdio; > > A a = A(42); > a.change(); > > writeln(a.id); > } > ---- Ali |
Copyright © 1999-2021 by the D Language Foundation