digitalmars.D - What is the Status of __mutable ?
- Vijay Nayar (18/18) Dec 20 2018 During the DConf of 2018, there was a talk about possibly
- Nicholas Wilson (13/31) Dec 20 2018 There is an implementation laying about in the PR queue:
- Kagamin (32/32) Dec 20 2018 How about this?
- Steven Schveighoffer (3/39) Dec 20 2018 The biggest issue is that immutable is implicitly shared.
- Kagamin (31/32) Dec 20 2018 struct __mutable(T)
- Neia Neutuladh (3/6) Dec 20 2018 More importantly, immutable is the same as shared immutable right now.
During the DConf of 2018, there was a talk about possibly introducing __mutable into the D Language, which has utility in allowing synchronization objects like locks, reference counts, and lazy initialization to be used for objects that are otherwise const or immutable. It was also stated that reference counts are already being maintained by the "monitor", which I know little about other than that it's built into the language and that user code does not have the same privileges. However, the __mutable feature could open up problems in terms of the compiler's ability to optimize generated code and knowing which CPU L1/L2 caches are valid or not. What is the current status of this work? Have there been any significant or unexpected hurdles that have come up? Any major accomplishments? The most significant reason for my question is my own ignorance of the normal communication channels in use. Apologies for the spam if this information has already been shared elsewhere, but a link to that information would be appreciated.
Dec 20 2018
On Thursday, 20 December 2018 at 10:47:18 UTC, Vijay Nayar wrote:During the DConf of 2018, there was a talk about possibly introducing __mutable into the D Language, which has utility in allowing synchronization objects like locks, reference counts, and lazy initialization to be used for objects that are otherwise const or immutable. It was also stated that reference counts are already being maintained by the "monitor", which I know little about other than that it's built into the language and that user code does not have the same privileges. However, the __mutable feature could open up problems in terms of the compiler's ability to optimize generated code and knowing which CPU L1/L2 caches are valid or not. What is the current status of this work? Have there been any significant or unexpected hurdles that have come up? Any major accomplishments? The most significant reason for my question is my own ignorance of the normal communication channels in use. Apologies for the spam if this information has already been shared elsewhere, but a link to that information would be appreciated.There is an implementation laying about in the PR queue: https://github.com/dlang/dmd/pull/8315 IIRC the motivating examples for __mutable were: * Monitor for immutable classes * Refcount fields for RC objects * References to allocators in immutable containers Immutable monitors can use a singleton mutex. For RC objects I'd rather see opHeadMutable implemented (const T!B <-> T!(const B) ). I'm not convinced of the utility of immutable containers (not to be confused with containers with immutable elements which are useful), see also opHeadMutable.
Dec 20 2018
How about this? struct __mutable(T) { private size_t _ref; this(T val){ _ref=cast(size_t)val; } T unwrap() const { return cast(T)_ref; } } struct A { __mutable!(int*) rc; this(int) immutable { rc=new int; } int inc() immutable { return ++*rc.unwrap; } } int main() { immutable A b=0; assert(b.inc==1); assert(b.inc==2); return 0; } I think it doesn't violate type system (formally): the mutable location is never seen as immutable, so immutability is not casted away, but it's not rebindable.
Dec 20 2018
On 12/20/18 10:10 AM, Kagamin wrote:How about this? struct __mutable(T) { private size_t _ref; this(T val){ _ref=cast(size_t)val; } T unwrap() const { return cast(T)_ref; } } struct A { __mutable!(int*) rc; this(int) immutable { rc=new int; } int inc() immutable { return ++*rc.unwrap; } } int main() { immutable A b=0; assert(b.inc==1); assert(b.inc==2); return 0; } I think it doesn't violate type system (formally): the mutable location is never seen as immutable, so immutability is not casted away, but it's not rebindable.The biggest issue is that immutable is implicitly shared. -Steve
Dec 20 2018
On Thursday, 20 December 2018 at 15:19:39 UTC, Steven Schveighoffer wrote:The biggest issue is that immutable is implicitly shared.struct __mutable(T) { private size_t _ref; this(shared T val){ _ref=cast(size_t)val; } shared(T) unwrap() const { return cast(shared T)_ref; } } struct A { __mutable!(int*) rc; this(int) immutable { rc=new shared int; } int inc() immutable { import core.atomic; return atomicOp!"+="(*rc.unwrap,1); } } int main() { immutable A b=0; assert(b.inc==1); assert(b.inc==2); return 0; }
Dec 20 2018
On Thu, 20 Dec 2018 10:47:18 +0000, Vijay Nayar wrote:However, the __mutable feature could open up problems in terms of the compiler's ability to optimize generated code and knowing which CPU L1/L2 caches are valid or not.More importantly, immutable is the same as shared immutable right now. That would have to change.
Dec 20 2018