On 08/04/2016 08:22 PM, Mark J Twain wrote:
The problem is that you have fixated on the *array* and not the general
principle. The Array was an example.

I'm having trouble understanding what you're getting at, so I'm trying to get it from the example you gave. If there's merit in your idea, then surely you can give a example where it provides benefit over the immutable keyword.

Get Array out of your mind and
think of them as general structures. It could be a queue.

Ok.

D has no built
in queue, then what?

You can still have an immutable queue, or a queue of immutable elements. Just like with arrays.

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?

No.

I assure you there is.

Please show.

The immutable keyword
only prevents data manipulation, it does not change the interface.

I'm still not sure what that means. An immutable object does not have mutating operations in its interface. A mutable object does. So the interfaces are different.

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.

Not true. Since Enqueue isn't marked const or immutable, it can't be called on an immutable object. The compiler rejects the call itself. It doesn't reject the mutation that happens inside Enqueue, because that's perfectly fine in a non-const, non-immutable method.

In code:

----
struct Queue
{
    void Enqeue(int dummy) {}
}

void main()
{
    Queue m;
    m.Enqeue(1);
    immutable Queue i;
i.Enqeue(2); /* Error: mutable method test.Queue.Enqeue is not callable using a immutable object */
}
----

We can cast away immutability and end up defeating the purpose and end
up with run-time problems.

You can break everything with casts, yes.

q2.Enqueue(x);  // Compile time error, Enqueue doesn't exist in
ImmutableQueue.

It doesn't exist for an immutable Queue, either.

cannot cast away immutable.

You can still cast from ImmutableQueue to MutableQueue.

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.

Sorry, but I still don't see what ImmutableWhatever does that `immutable Whatever` can't do. As far as I see, your example about having better error locations is wrong.

Reply via email to