D safety! New Feature?

Mark J Twain via Digitalmars-d digitalmars-d at puremagic.com
Thu Aug 4 11:22:52 PDT 2016


On Thursday, 4 August 2016 at 13:08:11 UTC, ag0aep6g wrote:
> On 08/03/2016 09:33 PM, Mark J Twain wrote:
>> The built in array is mutable and exposes the same interface 
>> for the
>> immutable copy. The only difference is that the immutable copy 
>> is marked
>> immutable.
>
> I don't understand. An immutable array does not let you 
> overwrite elements. A mutable array does. So they have 
> different interfaces, don't they?
>
>> My method changes the interface. An "immutable" type has an 
>> immutable
>> interface while a mutable type has a mutable interface.
>>
>> For simple types, and value types, there is obviously no 
>> advantage...
>> their interfaces are essentially empty/DNE.
>
> Can you show some example code where there is an advantage over 
> built-in arrays?
>
> [...]
>>> As far as I see, "marking for reuse" is practically the same 
>>> as
>>> freeing here. If Data were static, there could be a 
>>> difference.
>>>
>>> For built-in arrays, you can mark an array for reuse by 
>>> setting the
>>> length to 0 and calling assumeSafeAppend, like so:
>>
>> No again. Data in the example above is a local variable that 
>> allocates
>> memory that would generally be free'ed at the end of the 
>> function call.
>> Hence every call to foo results in a malloc/free pair for 
>> Data.  By
>> reusing the memory, if possible, one can potentially skip the
>> malloc/free.  Therefore instead of potentially thrashing the 
>> memory
>> pool, after a few runs of foo, Data would generally not 
>> allocate.
>>
> [...]
>> Your assumeSafeAppend works while the object is in existence. 
>> This thing
>> works between the existence of the object.
>
> The allocator (e.g. the GC) is free to reuse memory it obtained 
> from the operating system. So repeatedly allocating and freeing 
> the same amount of memory can already be faster than one might 
> think.
>
> Of course, the compiler is also free to reuse stuff, if it's 
> guaranteed that no reference escapes the function. I don't 
> expect dmd to do stuff like this. ldc or gdc might.
>
> What do Mutable/ImmutableArray enable beyond this? What do they 
> do that built-in arrays don't? Again, example code would help 
> doofuses like me make sense of this.

The problem is that you have fixated on the *array* and not the 
general principle. The Array was an example. Get Array out of 
your mind and think of them as general structures. It could be a 
queue. D has no built in queue, then what? What if it is a 
widget, then what? Immutable Widget vs Mutable Widget.

Marking a widget immutable is not the same as having an 
ImmutableWidget. Can you see the difference? I assure you there 
is. The immutable keyword only prevents data manipulation, it 
does not change the interface. For simple primitives, there is 
not much difference, but for larger complex types, the immutable 
keyword doesn't cut it.

immutable Queue!int q1;
ImmutableQueue!int q2;

q1.Enqueue(x);  // Compile time error if no tricks, but the error 
is further up the line inside Enqueue, when it actually modifies 
the data. We can cast away immutability and end up defeating the 
purpose and end up with run-time problems.

q2.Enqueue(x);  // Compile time error, Enqueue doesn't exist in 
ImmutableQueue. cannot cast away immutable. At most we can 
convert q2 to a mutable class, which is a copy, then replace q2 
with the copy.

There are difference and the second case is better. The error 
reporting is more accurate and no casting can be done to bypass 
immutability. We essentially get all this stuff for free if we 
simply use templates to build the hierarchy and separate the 
template in to different parts(immutable, mutable, etc).

Now, an ImmutableQueue might not be hugely useful if we have no 
way to access the data, but it could provide [] access. Again, 
don't get bogged down in the specifics, I'm talking about general 
application here. The more complex the type and hierarchy the 
more useful such a method is and the less useful immutable 
keyword is.

The immutable keyword is a blind, it only does one thing. 
Building immutability in to the type system itself allows the 
programmer to make immutable smarter and control exactly what it 
does.











More information about the Digitalmars-d mailing list