March 16, 2007
Walter Bright wrote:
> Benji Smith wrote:
> 
>> Bingo. It's like trying to describe something as "impossible impossible". If the first usage of the word didn't really convey impossibility, then you were using the wrong word to begin with.
> 
> 
> Reminds me of the old assembler program:
> 
>     foo:
>         MOV EAX, 3
>         CALL BAR
>         HALT        ; stop the program
>         HALT        ; if skidding

LOL
March 16, 2007
Andrei Alexandrescu (See Website For Email) wrote:
> Benji Smith wrote:
>> Aha. In that case, what would you think of the declaration:
>>
>>   super const int MY_CONSTANT = 6;
>>
>> Since a value type doesn't have any pointers, it wouldn't make any sense to apply super-constness to it, right? Should that be a compiler error?
> 
> This should be a compiler error.
> 
> Andrei

Cool. That's what I'd expect.

Maybe rather than "super const", you could use "ref const" or "const*" or something that directly indicates that this form of constantness applies to the pointers rather than the values. If you use "ref" as a replacement for "inout", then the "ref" keyword would get some re-use.

Actually, though, I kind of like the idea of "const*"

  // Create a constant pointer from a mutable pointer
  const* int* myPointer = pMutableInt;

  // Or maybe like this:
  *const int* myPointer = pMutableInt;

What do you think of that? At least the asterisk provides a better clue to the functionality of the construct than an exclamation point would.

--benji
March 16, 2007
Sean Kelly wrote:
> Walter Bright wrote:
>> Benji Smith wrote:
>>> I should also add that, in my opinion, any design where "const" means something other than "value resolved at compile time and immutable at runtime" would be a mistake.
>>
>> I hear you. I've always disliked C++'s mutable const.
>>
>> The most important thing at this stage is not the keyword, however, but getting the design right. Andrei, myself and Bartosz have been to hell and back several times over this over the last few months, and have filled about two notebooks with scribblings. It's a difficult problem.
> 
> I very much agree.  But with little information about how these new flavors of const will work, it seems we're mostly stuck debating how they will look :-)  I'd welcome discussing the former issue, but I suspect that anything which is said here will have already been discussed between you three.
> 
>> There are 3 distinct, and very different, flavors of constant:
>>
>> 1) rebinding of a value to a name
>> 2) a read-only view of a data structure
>> 3) a value that never changes
> 
> It seems like #1 is only useful for reference types, which currently means pointers and class handles.

#1 is essential for expressing numeric constants.

> Further, I don't think I've ever found a need for this particular class of immutability in C++.  How often does it really matter whether someone can reassign a pointer?

Very important. Often you want to bind a pointer to something and make sure nothing can change that.

> As for the other two, it seems like #3 is a storage class

No, because the value may embed pointers that you want to pass to functions. Sorry for sounding dismissive, but we've been all of these dead alleys for so long, it's all green codes: I can see the damn Matrix now. Blonde, brunette, const, final...

> while #2 is an attribute on the variable itself.  So #3 implies #2.

No. #3 implies #2. If a value is super const, then it can be seen as const. Essentially "const" loses a little of the precision that "super const" has.

> I haven't given this much thought, but is it truly necessary to have two separate keywords for #2 and #3?

It's not! That's what I tried to do all along...

> Is this to aid the compiler in optimizing, or is there a perceived value here from a user perspective?

It will be absolutely essential for the well-definedness of functional-style threads.

> Please don't get me wrong, I very much appreciate the desire for a comprehensive solution, but at the same time I wonder whether the struggle to integrate three fairly diverse concepts might be part of the reason why this all seems so complicated.  Are they all truly necessary? 

I'd think so.

>  And is it necessary to distinguish all three by separate keywords?

It's not necessary :o).


Andrei
March 16, 2007
eao197 wrote:
> No, at first there must be 'D with macros' (like 'C with classes') and only then -- D++ :))

D will get macros - but they won't be text processing macros, they'll be abstract syntax tree (AST) processing macros.

C++ programmers often try to use text macros to do syntax tree manipulation, but the result usually looks like one tried to use a belt buckle to drive screws.
March 16, 2007
Frits van Bommel wrote:
> kris wrote:
>> How about this? Using existing keywords, with a rename of "const":
>>
>> 1) final       - rebinding of a value to a name
> [moved '2)']
>> 3) constant    - a value that never changes
> 
> These two are fine by me.
> 
>  > 2) invariant   - a read-only view of a data structure
> 
> No. Just No.
> For one thing, the data structure can vary :) : anyone with a mutable reference can change the value from under your nose, so "does not vary" simply isn't applicable here.
> But more importantly, invariant has a very clear and defined meaning in computer science. It should not be overloaded like this.

Much of the terminological problem is that it's hard to express const's imprecision (as opposed to super const's precision) tersely.

One of my ideas was using "const" for truly set in stone, and using "const?" to mean that the object may or may not have originated as const. But code with question marks everywhere would look odd.


Andrei
March 16, 2007
Andrei Alexandrescu (See Website For Email) wrote:
> This makes const gratuitously incompatible to C++'s const, and (worse) also adds a keyword that's its equivalent. I don't think this can fly.

There's some experience with that: the alias and typedef declarations. But that experience makes me wary of doing it in a much bigger way.
March 16, 2007
Andrei Alexandrescu (See Website For Email) wrote:
> We're doomed either way. We don't want to confuse C++ programmers. Two levels of strength of const are more descriptive than a new keyword that half of the people will think it's the other way.

True. If we have readonly and const, I expect endless confusion about which is which.
March 16, 2007
Derek Parnell wrote:
> Given ...
> 
>    int[int**][]*[char[]][3][17][3,17]* x;
> 
> and I want to make the 'x' immutable and the 'char[]' immutable, how does
> one write the declaration? Where does one place the 'final'/'const'/'super
> const' and where do the parenthesis go?

final int[int**][]*[ const(char[]) ][3][17][3,17]* x;
March 16, 2007
Walter Bright wrote:
> Andrei Alexandrescu (See Website For Email) wrote:
>> We're doomed either way. We don't want to confuse C++ programmers. Two levels of strength of const are more descriptive than a new keyword that half of the people will think it's the other way.
> 
> True. If we have readonly and const, I expect endless confusion about which is which.

Not to mention if you also have 'readsometimes'. Nobody'll EVER figure that one out :)

--benji
March 16, 2007
Andrei Alexandrescu (See Website For Email) wrote:
> Sean Kelly wrote:
>> Walter Bright wrote:
>>> Benji Smith wrote:
>>>> I should also add that, in my opinion, any design where "const" means something other than "value resolved at compile time and immutable at runtime" would be a mistake.
>>>
>>> I hear you. I've always disliked C++'s mutable const.
>>>
>>> The most important thing at this stage is not the keyword, however, but getting the design right. Andrei, myself and Bartosz have been to hell and back several times over this over the last few months, and have filled about two notebooks with scribblings. It's a difficult problem.
>>
>> I very much agree.  But with little information about how these new flavors of const will work, it seems we're mostly stuck debating how they will look :-)  I'd welcome discussing the former issue, but I suspect that anything which is said here will have already been discussed between you three.
>>
>>> There are 3 distinct, and very different, flavors of constant:
>>>
>>> 1) rebinding of a value to a name
>>> 2) a read-only view of a data structure
>>> 3) a value that never changes
>>
>> It seems like #1 is only useful for reference types, which currently means pointers and class handles.
> 
> #1 is essential for expressing numeric constants.

Could you please provide an example?

>> Further, I don't think I've ever found a need for this particular class of immutability in C++.  How often does it really matter whether someone can reassign a pointer?
> 
> Very important. Often you want to bind a pointer to something and make sure nothing can change that.

Perhaps this should be rewritten as "often one wants to..."  I just said that I have never felt a need for this :-)  Of the times where I've used this feature in C/C++, I think every single time has been simply out of diligence rather than because there was any risk of the pointer actually being reassigned.  A pertinent point to me is that D uses pass-by-value so the chance of a reference being silently reassigned "somewhere in the program" is typically almost nil.  About the only place where this is a real risk is with global variables, and since free functions support the property syntax, the programmer has a ready option to prevent such a reassignment from happening.  Besides, free globals are bad programming style anyway.

>> As for the other two, it seems like #3 is a storage class
> 
> No, because the value may embed pointers that you want to pass to functions. Sorry for sounding dismissive, but we've been all of these dead alleys for so long, it's all green codes: I can see the damn Matrix now. Blonde, brunette, const, final...

That's fine.  You may have been down all these roads before, but I haven't.  I'm mostly asking to gain a better understanding of some of the background.

>> while #2 is an attribute on the variable itself.  So #3 implies #2.
> 
> No. #3 implies #2. If a value is super const, then it can be seen as const. Essentially "const" loses a little of the precision that "super const" has.

I'm confused.  I said "so #3 imples #2" and you replied "no, #3 implies #2."  What does the "no" signify?

>> I haven't given this much thought, but is it truly necessary to have two separate keywords for #2 and #3?
> 
> It's not! That's what I tried to do all along...

(see below)

>> Is this to aid the compiler in optimizing, or is there a perceived value here from a user perspective?
> 
> It will be absolutely essential for the well-definedness of functional-style threads.

Okay, that's what I figured, though this seems to contradict what you said above.  So in essence, "super const" is actually necessary in some situations to indicate to the programmer that the data he is manipulating is truly immutable.  I almost feel like this feature should exist separately from the type mechanism, so there was a way to test for this instead.

>>  And is it necessary to distinguish all three by separate keywords?
> 
> It's not necessary :o).

So it sounds like it truly isn't necessary to separately distinguish #2 and #3 via type qualifiers.  Is this correct?  I can appreciate the need for both, but I very much do not want all of this to become a confusing mess when applied to actual code.


Sean
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19