June 24, 2007
Kristian Kilpi wrote:
> 
> What if we drop out the 'invariant' keyword, and simply define that aliasing
> is illegal (by default) and result in undefined behaviour?

That would pretty much invalidate the use of slicing, which is one of the most powerful features of the language.


Sean
June 24, 2007
On Sun, 24 Jun 2007 19:03:37 +0300, Sean Kelly <sean@f4.ca> wrote:

> Kristian Kilpi wrote:
>>  What if we drop out the 'invariant' keyword, and simply define that aliasing
>> is illegal (by default) and result in undefined behaviour?
>
> That would pretty much invalidate the use of slicing, which is one of the most powerful features of the language.
>
>
> Sean

On Sun, 24 Jun 2007 19:03:37 +0300, Sean Kelly <sean@f4.ca> wrote:
> Kristian Kilpi wrote:
>>  What if we drop out the 'invariant' keyword, and simply define that aliasing
>> is illegal (by default) and result in undefined behaviour?
>
> That would pretty much invalidate the use of slicing, which is one of the most powerful features of the language.
>
>
> Sean

You mean that a programmer has been slicing arrays around so much that (s)he cannot
know (be sure) if two arrays/slices overlap? ;)

But, if the slices do overlap, and one of them is modified, wouldn't that
(very likely) be a bug anyway (that is, when you do that 'by accident')?
-> The same aliasing problem?

For instance, 'memcpy()' does not work correctly if the destination and source overlap.
You have to use 'memmove()'.

(Constant aliasing would be ok of course. E.g. "void f(const int *a, const int *b);  f(&v, &v);")
June 24, 2007
Kristian Kilpi wrote:
> What I would want is a way to tell the compiler that the data will not be changed
> *during the execution* of a function.

scope invariant.
"invariant" means the data referenced won't be changed, "scope" means the reference will be invalid after the function exits (and thus the "invariantness" no longer needs to be guaranteed from that point on since any access to the data is an error anyway).
June 25, 2007
Reiner Pope wrote:
> As storage classes, const and invariant both mean "compile-time constant" -- their initializers must be evaluatable at compile time, and their data need not be stored in memory.

the docs aren't very clear about that, but it's not fully correct when you think about function parameters. the "initializers" of function parameters are the arguments to the call, which need not be evaluatable at compile time.

> void main() {
>    int a = 10;
>    int* p = &a; // here's our mutable view
>    const int* cp = &a; // here's our const-as-storage-class
> }
>
> At the moment, this doesn't compile, because &a is not evaluatable at compile time

it compiles when you change it to

int f(const int* cp) {
    return *cp+3;
}

void main() {
    int a = 10;
    int* p = &a;
    a = f(&a);
}

and it's also clear how *p can change here.

> [1] Although the data pointed to by const-as-storage-class *is* invariant, the type system doesn't believe it. The following doesn't compile (correctly so, according to the specs)
> 
>     const char[] a = "abc";
>     invariant char[] b = a;
> 
> but how can the data in 'a' possibly change?

again - if it is a parameter.

besides holes and overlap in the final/const/invariant keyword's definition ranges, what is nice about D's const-system, is that while in some situations A means the same as B, A always means A and B always means B - unlike const in C++.
June 25, 2007
Jascha Wetzel wrote:
> Reiner Pope wrote:
>> As storage classes, const and invariant both mean "compile-time constant" -- their initializers must be evaluatable at compile time, and their data need not be stored in memory.
> 
> the docs aren't very clear about that, but it's not fully correct when you think about function parameters. the "initializers" of function parameters are the arguments to the call, which need not be evaluatable at compile time.


That part of the documentation actually bugged me.

One of the really nice features of pre-2.0 D was the option to delay initialization of const variables to the constructor... either a class constructor or static this(){}.
June 26, 2007
OF wrote:
> Walter Bright Wrote:
> 
>> BLS wrote:
>>> I am afraid you will not like this idea, but not afraid enough. <g>
>>>
>>> Why not using a single keyword "const_" adding a number 1, 2, 3 to represent :
>>> invariant, final, readonlyview.
>>> the higher the number the higher (the stronger) the const.
>>> means : const_3 == invariant;
>>> At least a mental help, IMO; somehow borrowed from Modula 2 processes.
>> You're right, I don't like the idea <g>.
> 
> I'm curious. Was 'readonly'

readonly is a synonym for const, so no improvement there.


> or 'readonlyview' considered as an alternative for 'const'? I kind of like the sound of 'readonly', and it doesn't make you think of C++ 'const'... but maybe that's bad.

readonlyview is too long.
June 26, 2007
Walter Bright wrote:
> OF wrote:
>> Walter Bright Wrote:
>>
>>> BLS wrote:
>>>> I am afraid you will not like this idea, but not afraid enough. <g>
>>>>
>>>> Why not using a single keyword "const_" adding a number 1, 2, 3 to represent :
>>>> invariant, final, readonlyview.
>>>> the higher the number the higher (the stronger) the const.
>>>> means : const_3 == invariant;
>>>> At least a mental help, IMO; somehow borrowed from Modula 2 processes.
>>> You're right, I don't like the idea <g>.
>>
>> I'm curious. Was 'readonly'
> 
> readonly is a synonym for const, so no improvement there.
> 
> 
>> or 'readonlyview' considered as an alternative for 'const'? I kind of like the sound of 'readonly', and it doesn't make you think of C++ 'const'... but maybe that's bad.
> 
> readonlyview is too long.

But its only 3 characters longer than 'invariant'... ;)  Still, it is a little unwieldy aside from that.  I'm not too keen on keywords that are, linguistically, more than one word.  (I know, that sounds silly from one of the same people who begged for 'foreach' ages ago, but that's a keyword with enough history on it to be easily recognizable.  I might have preferred 'each' if it wasn't a common variable name.)

-- Chris Nicholson-Sauls
June 26, 2007
Sean Kelly wrote:
> Yeah, I don't care if the compiler does it now, only that the potential is there.  After all, this discussion is about the design, not the implementation.

There's quite a bit of unrealized potential for better code right now.

> Thanks for explaining things.  I'm coming to understand the reasoning behind the design you've chosen.

Only time will tell if we screwed it up or not, but there is reasoning behind it <g>.
June 26, 2007
eao197 wrote:
> Adding 'pure' modificator to D can lead, IMHO, to the following alternatives:
> 1) nobody would use 'pure' at top level of modules/libraries/frameworks, because any top-level function/method would use some 'impure' function inside, or
> 2) it is necessary to introduce some constructs into language to define 'logical pureness' -- function will be marked as pure, but can use impure calls inside. Like 'mutable' keyword in C++ used for 'logical constantness'.

I think you're probably right.
June 26, 2007
Walter Bright wrote:
> readonly is a synonym for const, so no improvement there.

I think readonly is a much better mnemonic than const, especially considering that const is often explained in terms of being a read-only view.  Yes, invariant can be described in terms of read-only too, but const vs invariant look *exactly* the same to me, whereas readonly doesn't.

-Jeff