May 21, 2016 Re: mutable keyword | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Applegame | On Saturday, May 21, 2016 17:15:16 Jack Applegame via Digitalmars-d-learn wrote:
> On Friday, 20 May 2016 at 20:46:18 UTC, Jonathan M Davis wrote:
> > Casting away const and mutating is undefined behavior in D. No D program should ever do it.
>
> Really? Mutating immutable is UB too, but look at std.typecons.Rebindable.
Rebindable is in kind of a weird grey area. It involves a union, not casting, and it's only ever mutating the class reference, not the object itself. Certainly, if it mutated the object, it would be undefined behavior, but it's just mutating the reference - but then again, the type system itself doesn't really differentiate between the two. So, I suspect that what it comes down to is that Rebindable is doing something that you really shouldn't, but because it's using a union rather than a cast, and it's so limited in what it's mutating, its behavior is effectively defined in the sense that the compiler has no leeway, but's probably still technically undefined. I don't know what Walter would say though. Certainly, if casting were involved, it would be undefined behavior without question, and it's not the sort of thing that you should be doing in your own code.
So, Rebindable may actually be breaking the rules, but it's so useful that we really have no other choice as long as there isn't a solution in the actual language, and it's so limited in how it goes about it, that there's really no way that it won't work even if it's not technically valid.
Personally, I think that what Rebindable has to do internally to work is the biggest strike against it, but I doubt that it's enough to convince Walter that we need a proper in-language solution given how much of a horrid pain it supposedly is to sort it out in the compiler.
- Jonathan M Davis
|
May 22, 2016 Re: mutable keyword | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Applegame | On 05/21/2016 07:15 PM, Jack Applegame wrote: > Really? Mutating immutable is UB too, but look at std.typecons.Rebindable. Rebindable uses a union of a mutable and an immutable variant of the type. No access to the mutable union member is provided, and it's never dereferenced by Rebindable. Assignment is done through the mutable member. So the immutable member is never overwritten explicitly, but its value does change, of course. It's supposedly not a problem that the immutable member changes, as long as nobody looks. That is, as long as nobody obtains a reference to it. Copies of the immutable member are truly immutable. For this to work, the compiler must recognize that an immutable union member isn't actually immutable when the union has mutable members as well. I don't know if this is specified anywhere, or if it's perfectly sound then. And Rebindable does give out a reference, actually. That's unacceptable, as far as I can see. Filed an issue: https://issues.dlang.org/show_bug.cgi?id=16054 |
May 22, 2016 Re: mutable keyword | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Saturday, 21 May 2016 at 21:49:23 UTC, Jonathan M Davis wrote:
> Rebindable is in kind of a weird grey area. It involves a union, not casting, and it's only ever mutating the class reference, not the object itself. Certainly, if it mutated the object, it would be undefined behavior, but it's just mutating the reference - but then again, the type system itself doesn't really differentiate between the two. So, I suspect that what it comes down to is that Rebindable is doing something that you really shouldn't, but because it's using a union rather than a cast, and it's so limited in what it's mutating, its behavior is effectively defined in the sense that the compiler has no leeway, but's probably still technically undefined. I don't know what Walter would say though. Certainly, if casting were involved, it would be undefined behavior without question, and it's not the sort of thing that you should be doing in your own code.
>
> [...]
I agree. But I think we need something that allows *logical* const and immutable.
Strict binding constness to physical memory constancy is not always necessary and sometimes even harmful.
|
May 22, 2016 Re: mutable keyword | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Applegame | On Sunday, 22 May 2016 at 09:42:54 UTC, Jack Applegame wrote: > I agree. But I think we need something that allows *logical* const and immutable. > Strict binding constness to physical memory constancy is not always necessary and sometimes even harmful. http://wiki.dlang.org/DIP89 |
May 22, 2016 Re: mutable keyword | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Applegame | On Sunday, May 22, 2016 09:42:54 Jack Applegame via Digitalmars-d-learn wrote:
> On Saturday, 21 May 2016 at 21:49:23 UTC, Jonathan M Davis wrote:
> > Rebindable is in kind of a weird grey area. It involves a union, not casting, and it's only ever mutating the class reference, not the object itself. Certainly, if it mutated the object, it would be undefined behavior, but it's just mutating the reference - but then again, the type system itself doesn't really differentiate between the two. So, I suspect that what it comes down to is that Rebindable is doing something that you really shouldn't, but because it's using a union rather than a cast, and it's so limited in what it's mutating, its behavior is effectively defined in the sense that the compiler has no leeway, but's probably still technically undefined. I don't know what Walter would say though. Certainly, if casting were involved, it would be undefined behavior without question, and it's not the sort of thing that you should be doing in your own code.
> >
> > [...]
>
> I agree. But I think we need something that allows *logical*
> const and immutable.
> Strict binding constness to physical memory constancy is not
> always necessary and sometimes even harmful.
Actually doing logical const/immutable isn't really possible. Not even C++ does that. Rather, it provides backdoors that you can then use to implement a sort of logical const, but there is zero guarantee that that's actually what's happening. It's completely a matter of convention at that point. At best, it would be possible to indicate that a portion of a type is const or immutable while allowing certain parts of it to be mutable, in which case, there are zero constness guarantees about the part that's always mutable and no guarantees that the stuff that's mutable isn't part of the logical state of the object.
Given how const and immutable work in D, having any portion of them be treated as mutable, becomes highly problematic. It could theoretically be done by having to mark such variables with an attribute and mark such types with a similar attribute so that the compiler knows that the type in question is not really following the rules of const or immutable and thus doesn't make any assumptions about it like it would normally, but it risks getting rather complicated, and Walter is most definitely not in favor of such an idea. He is absolutely adamant that const is useless unless it's fully const with no backdoors whatsoever. So, I'd be very surprised if any kind of @mutable were added to the language. Certainly, you'd have to have a very strong technical reason to convince him otherwise, and odds are that he's just going to tell you to not use const, if it's not going to work for the type to be const.
- Jonathan M Davis
|
May 22, 2016 Re: mutable keyword | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz | There is a benefit in not allowing to get pointers to class members. It allows to have movable object instances and this give access to some faster GC algorithms like generational garbage collection which is in use in Java. As an old C++ programmer and newbee in D programming, the D constness and immutability concepts are confusing. They are so strong that I hardly see any use for them with objects. There would be a much wider use to be able to tell user that he may assume the object is constant from the interface point of view. This is a huge help in code readability and program validity checking. I had the impression that this is the principle used for the pure keyword. I would vote against the introduction of the mutable keyword as it exist in C++ because it is a half backed solution. First it tells the compiler that this variable is modifiable at any time by any method of the class. This is way I always felt uncomfortable using mutable. It punches a big hole in the constness protection. The other problem is with inheritance (I know it's old school, but ok). If a derived class needs to modify a member variable of a base class that wasn't declared mutable, you're stuck. That is why C++ introduced the const_cast. This is much better in that the hole in the constness protection is very limited, but the code is also less pleasant to read. How could be the D way to solve this ? My feeling is that it could be by introducing a mutate{...} block. All instructions in that block would be allowed to modify the const object. The developer intent would be clear, the code readable and the hole limited. The difference with the C++ model is that in C++ we switch off the constness flag of member variables for a persistent or short time, in D we would switch off constness control in a block of instructions. I didn't thought of all the implications yet. I only talked about const objects. I still need to find a use case for immutable objects /S |
May 23, 2016 Re: mutable keyword | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Sunday, 22 May 2016 at 13:08:19 UTC, Jonathan M Davis wrote:
> Given how const and immutable work in D, having any portion of them be treated as mutable, becomes highly problematic. It could theoretically be done by having to mark such variables with an attribute and mark such types with a similar attribute so that the compiler knows that the type in question is not really following the rules of const or immutable and thus doesn't make any assumptions about it like it would normally, but it risks getting rather complicated, and Walter is most definitely not in favor of such an idea. He is absolutely adamant that const is useless unless it's fully const with no backdoors whatsoever. So, I'd be very surprised if any kind of @mutable were added to the language. Certainly, you'd have to have a very strong technical reason to convince him otherwise, and odds are that he's just going to tell you to not use const, if it's not going to work for the type to be const.
Ha-ha. All this does not prevent immutable class to have mutable monitor. Why D so often violates its own rules?
|
May 23, 2016 Re: mutable keyword | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Applegame | On Monday, May 23, 2016 08:19:52 Jack Applegame via Digitalmars-d-learn wrote:
> On Sunday, 22 May 2016 at 13:08:19 UTC, Jonathan M Davis wrote:
> > Given how const and immutable work in D, having any portion of them be treated as mutable, becomes highly problematic. It could theoretically be done by having to mark such variables with an attribute and mark such types with a similar attribute so that the compiler knows that the type in question is not really following the rules of const or immutable and thus doesn't make any assumptions about it like it would normally, but it risks getting rather complicated, and Walter is most definitely not in favor of such an idea. He is absolutely adamant that const is useless unless it's fully const with no backdoors whatsoever. So, I'd be very surprised if any kind of @mutable were added to the language. Certainly, you'd have to have a very strong technical reason to convince him otherwise, and odds are that he's just going to tell you to not use const, if it's not going to work for the type to be const.
>
> Ha-ha. All this does not prevent immutable class to have mutable monitor. Why D so often violates its own rules?
I believe that the monitor predates immutable by a significant margin, and aside from compiler bugs, usually if there is any violation of rules going on it has to do with stuff that comes from D1 that wasn't necessarily adjusted appropriately as the language progressed, though sometimes folks do get things wrong, and it makes it into the compiler or std lib. But when that sort of thing happens, we try and fix it. I fully expect that the monitor mess will be fixed at some point. It just hasn't been high enough on the todo list for it to be fully sorted out yet. I don't know why you think that D violates its own rules frequently though. It's not perfect, but it usually does follow its own rules - and when it doesn't, we fix it (though not always as quickly as would be ideal).
- Jonathan M Davis
|
May 23, 2016 Re: mutable keyword | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Monday, 23 May 2016 at 11:05:34 UTC, Jonathan M Davis wrote:
> I don't know why you think that D violates its own rules frequently though. It's not perfect, but it usually does follow its own rules - and when it doesn't, we fix it (though not always as quickly as would be ideal).
The most PITA for me is lacking mutable references for immutable classes. I like immutability and hate Rebindable.
Also, how to embed reference counter into immutable class without violating immutability?
|
May 23, 2016 Re: mutable keyword | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Applegame | On Monday, May 23, 2016 14:08:43 Jack Applegame via Digitalmars-d-learn wrote: > On Monday, 23 May 2016 at 11:05:34 UTC, Jonathan M Davis wrote: > > I don't know why you think that D violates its own rules frequently though. It's not perfect, but it usually does follow its own rules - and when it doesn't, we fix it (though not always as quickly as would be ideal). > > The most PITA for me is lacking mutable references for immutable classes. I like immutability and hate Rebindable. Well, Rebindable is kind of ugly, but honestly, a built in modifier probably wouldn't look much better. e.g. tail_const(MyClass) obj; vs Rebindable!MyClass obj; The fact that you don't have a * to separate what the const applies to seems to kill any chance of making it short, and since it's fundamentally part of the design of D classes that they can't be used separately from their reference, I don't see that changing even if we get some kind of tail const built-in to the language for classes. > Also, how to embed reference counter into immutable class without violating immutability? You can't. It's fundamentally impossible as long as immutable is transitive. I believe that the proposed solution is to put the ref-count in the memory next to the object, or at least somewhere else where the memory-management stuff can find it. In the case of GC-allocated memory, that should be fairly straightforword, though I don't know how feasible it is to deal with it with non-GC-allocated memory without losing out on pure. Really, it's going to come down to how the ref-counting scheme that Walter is working on works. - Jonathan M Davis |
Copyright © 1999-2021 by the D Language Foundation