any news on const/invariant?

Bruce Adams tortoise_74 at yeah.who.co.uk
Thu Nov 29 16:47:26 PST 2007


On Thu, 29 Nov 2007 01:48:02 -0000, Walter Bright  
<newshound1 at digitalmars.com> wrote:

> Oskar Linde wrote:
>> Walter Bright wrote:
>>
>>> Because those alternatives all look terrible. And frankly, how could  
>>> anyone be confused about what:
>>>     const x = 3;
>>> means? I can't understand throwing that out to improve clarity?
>>  Honestly, I am confused about what that means. If I define an integer  
>> constant x, don't I want a pointer to that constant to be  
>> invariant(int)*? Doesn't that mean that constants should rather be  
>> defined as:
>>  invariant x = 3;
>>  Or am I wrong? What am I missing here?
>
> For a basic type, the meaning of const and invariant overlap. The  
> difference between them is when you have pointers or other references.  
> For simple integers, you can use const or invariant.
>
>> I am to tired right now to reiterate my full thoughts on the keywords  
>> (and I am sure you are all very thankful for that :) ), but it still  
>> feels like the keywords are reversed:
>>  invariant === constant
>>     const === read only
>
> We went around this for a while. There is no word that unambiguously  
> means "read only view" while another word meaning unambiguously "will  
> never change". So, since C++ uses const to mean "read only view", it  
> seemed best to leave that as it was.
>
> readonly, constant, invariant, immutable, are all synonyms.

I still like my idea of compile time contracts / type contracts.

Taking the thought experiment a bit too far...

Give a type T with several interfaces you could define a contract which  
says
that only certain interfaces of T can be used by the function.

const T is like a (compile time) contract permitting only the use of the  
read only interface.
invariant T is like a (compile time) contract that asserts X' == X as a  
pre-condition.
i.e. the value of X will not change for the duration of the function.  
Practically, this is
still X is not writeable anywhere it can be used when the function is  
called (i.e. it is invariant).

If you had some way to specify constracts like this at compile time you  
could build
head constness, tail constenss, invariantness and various other -nesses as  
library code.

What you are doing with const and invariant is limiting the contracts  
possible to (ideally) the
most useful subset of those possible and adding syntactic sugar to let you  
apply them to a declaration
easily.

Another way to view this is that the contracts specialise the types they  
apply to.

This is stretching inheritance a bit as constT needs to be a T i.e. public  
inheritance / isa
but needs to violate its normal interface in a way more suitable to  
private inheritance / is implemented in terms of

class T
{
    int foo();
    int bar() const;
}

const T  =

class constT: private T
{
    int bar() const = T::bar;
}

or:

class constT: public T
{
    int bar() const = T::bar;
private:
    override int foo() = compile_time_error("illegal attempt to invoke  
non-const method");
}


You could almost have const(T) as a (particularly evil) template now.

Perhaps this will inspire other options?

Regards,

Bruce.


PS You could always invent words rov and wnc - wince ;)



More information about the Digitalmars-d mailing list