www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - What is the Status of __mutable ?

reply Vijay Nayar <madric gmail.com> writes:
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
next sibling parent Nicholas Wilson <iamthewilsonator hotmail.com> writes:
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
prev sibling next sibling parent reply Kagamin <spam here.lot> writes:
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
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
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
parent Kagamin <spam here.lot> writes:
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
prev sibling parent Neia Neutuladh <neia ikeran.org> writes:
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