On Thu, 30 Jan 2014 13:58:55 -0500, Cooler <kul...@hotbox.ru> wrote:

The D principle - "The program compile and runs as expected, or not compile at all".

This is a fantasy. The compiler cannot know what you expect.
The language is needed to express your intentions to the compiler.

Anything that the compiler cannot enforce is just documentation. Does it matter whether the documentation is in a comment or part of the signature?
Why we need "const" keyword, while we can just put "I promise do not change it" in the documentation?

const is only useful in cases where references are involved. In this case, you want to make the *copied* data constant, in hopes that you then can't accidentally stop referencing the original.

In another example, there is little to be gained from a signature such as:

void foo(const int x);

What does this say about foo? Nothing. I can pass in a mutable, const, or immutable int, because a copy is made. It doesn't provide any more guarantees to the caller than:

void foo(int x);

Likewise, your proposed "int[] const" would not guarantee anything extra to the caller beyond "int[]", because both are copies put onto the stack. The function has no access to the original values.

Arrays in D are hard to understand. They don't behave like arrays in most other languages. But they foster a different mindset I think, that results in some of the fastest code on the planet. But one has to understand the semantics of syntax if they want to properly use the language. For functions which append/extend and then write data to the prior piece (the only non-deterministic case), special care has to be taken to explain this to the caller. I would think a mechanism to attempt detecting this and flagging it would be a worthy lint tool feature. But not a language or compiler feature. There is just simply no way to say "that is always bad" or that you know what the intentions of the author are.

The other case you specified, when the author re-assigns a slice and expects it to be a memcpy or to re-bind the calling parameter, the result is deterministically the wrong result, and the coder will notice it right away (and hopefully correct their understanding). I don't think we need a language feature for that, just documentation (which I think we have).

Let me also suggest you use scope statements to verify at runtime that the case you intend to prevent doesn't actually happen:

void foo(int[] x)
{
   const origx = x;
   scope(exit) assert(origx.ptr == x.ptr);
   ...
}

While not perfect, and not static, it should at least avoid subtle bugs (and can be turned off in release mode).

-Steve

Reply via email to