Thread overview | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
September 10, 2007 Const sucks | ||||
---|---|---|---|---|
| ||||
Const, final, invariant, head const, tail const, it's grown into a monster. It tries to cover all the bases, but in doing so is simply not understandable. Andrei and Bartosz have spent some time together going back to square one with what are we trying to achieve with const, and came up with another proposal. What we are trying to achieve: a) utility for functional programming b) better modularity by self-documenting interfaces better c) be able to treat reference types as if they were value types (i.e. strings should behave to the user like value types, even though they are references) The insights they came up with were: 1) final (i.e. 'head const') is not necessary for a, b or c. final is a local thing, and not strictly necessary. 2) tail const can be handled in other ways, read on So, what we are left with is: o no more final o const and invariant now mean "fully const" and "fully invariant", where fully means "head and tail combined": const int x = 0; // x is constant const int* p = &x; // neither p nor *p can be changed const(int*) p = &x; // neither p nor *p can be changed const(int)* p = &x; // p can change, *p cannot be changed o const and invariant are transitive. There is no way to specify a (pointer to)(const pointer to)(mutable int). o tail invariant for an array or pointer type can be done using the existing syntax: invariant(char)[] s; // string, i.e. an array of invariant chars const(T)* p; // pointer to tail const T o tail const of a struct would have to be done by making the struct a template: struct S(T) { T member; } S!(int) // tail mutable S!(const(int)) // tail const o one can construct a template to generically produce tail const or tail invariant versions of a type. o it will be illegal to attempt to change the key value of a foreach loop, but the compiler will not be able to diagnose all attempts to do so o static const/invariant means the initializer is evaluated at compile time. non-static const/invariant means it is evaluated at run time. o no initializer means it is assigned in the corresponding constructor. o const/invariant declarations will always allocate memory (so their addresses can be taken) o So, we still need a method to declare a constant that will not consume memory. We'll co-opt the future macro syntax for that: macro x = 3; macro s = "hello"; |
September 10, 2007 Re: Const sucks | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Walter Bright wrote: > o tail const of a struct would have to be done by making the struct a template: > > struct S(T) { T member; } > S!(int) // tail mutable > S!(const(int)) // tail const How is this going to work for a more complex struct? struct Bar { int a; } class Baz { int a; } struct Foo { int a; float b; char[] c; Bar d; Baz e; } > o one can construct a template to generically produce tail const or tail invariant versions of a type. Including classes? I saw no mention of how tail-const will be applied to classes, will they be handled in the same way as structs? In general is this correct for a class reference: class Baz { int a; } const Baz b; //neither b nor b.a can be changed Regan |
September 10, 2007 Re: Const sucks | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | Wow! Well, I'm happy! :-) I think I'll wait for the documentation before I comment further, except to mention again this suggestions which I've made elsewhere... No casting away const except by special syntax. const(int)*p; auto q = (int *) p; // Error - p is const |
September 10, 2007 Re: Const sucks | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Walter Bright wrote: > > So, what we are left with is: > > o no more final By this you meant that "final" in 2.0 would work exactly as in 1.0, correct? > o const and invariant now mean "fully const" and "fully invariant", where fully means "head and tail combined": > > const int x = 0; // x is constant > const int* p = &x; // neither p nor *p can be changed > const(int*) p = &x; // neither p nor *p can be changed > const(int)* p = &x; // p can change, *p cannot be changed So the presence of parenthesis would be simply to limit the extent of the type to which "const" applies? As an aside, I'm still not terribly fond of 'invariant', but that's a cosmetic issue which could easily be resolved later. > o const and invariant are transitive. There is no way to specify a (pointer to)(const pointer to)(mutable int). Sounds great to me. > o tail invariant for an array or pointer type can be done using the existing syntax: > > invariant(char)[] s; // string, i.e. an array of invariant chars > const(T)* p; // pointer to tail const T > > o tail const of a struct would have to be done by making the struct a template: > > struct S(T) { T member; } > S!(int) // tail mutable > S!(const(int)) // tail const > > o one can construct a template to generically produce tail const or tail invariant versions of a type. Could you please explain this further? Why would templates be needed in the above two points? For the rest, this design sounds a lot more comprehensible than the old one, and still seems to address all the situations where I would use const. Sean |
September 10, 2007 Re: Const sucks | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Mon, 10 Sep 2007 12:15:09 -0700, Walter Bright wrote: > Const, final, invariant, head const, tail const, it's grown into a monster. It tries to cover all the bases, but in doing so is simply not understandable. Agreed! > Andrei and Bartosz have spent some time together going back to square one with what are we trying to achieve with const, and came up with another proposal. > > What we are trying to achieve: > > a) utility for functional programming > b) better modularity by self-documenting interfaces better > c) be able to treat reference types as if they were value types (i.e. > strings should behave to the user like value types, even though they are > references) Ok, nice to see this documented. > The insights they came up with were: > > 1) final (i.e. 'head const') is not necessary for a, b or c. final is a local thing, and not strictly necessary. > > 2) tail const can be handled in other ways, read on > > So, what we are left with is: > > o no more final Not a problem for me as I never used it. > o const and invariant now mean "fully const" and "fully invariant", where fully means "head and tail combined": Remind me again what the difference between 'const' and 'invariant' is. > const int x = 0; // x is constant > const int* p = &x; // neither p nor *p can be changed > const(int*) p = &x; // neither p nor *p can be changed > const(int)* p = &x; // p can change, *p cannot be changed What do these below mean ... const int (* p) const int *(p) const int (*) p > o tail const of a struct would have to be done by making the struct a template: > > struct S(T) { T member; } > S!(int) // tail mutable > S!(const(int)) // tail const But most structs contain multiple members, and usually of different types. -- Derek Parnell Melbourne, Australia skype: derek.j.parnell |
September 10, 2007 Re: Const sucks | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Oh wait! I do have one comment, or question, or whatever.
> const int* p = &x; // neither p nor *p can be changed const(int*) p = &x; // neither p nor *p can be changed
Two ways of writing the same thing. I don't understand the need for the bracketless version. Could we not just insist that the brackets must always be there? Or does the lack of brackets actually mean something? (if it does, it's back to being confusing again).
|
September 10, 2007 Re: Const sucks | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Oh wait! I do have one comment, or question, or whatever.
> const int* p = &x; // neither p nor *p can be changed const(int*) p = &x; // neither p nor *p can be changed
Two ways of writing the same thing. I don't understand the need for the bracketless version. Could we not just insist that the brackets must always be there? Or does the lack of brackets actually mean something? (if it does, it's back to being confusing again).
|
September 10, 2007 Re: Const sucks | ||||
---|---|---|---|---|
| ||||
Posted in reply to Janice Caron | Janice Caron wrote:
> Oh wait! I do have one comment, or question, or whatever.
>
>> const int* p = &x; // neither p nor *p can be changed
>> const(int*) p = &x; // neither p nor *p can be changed
>
> Two ways of writing the same thing. I don't understand the need for
> the bracketless version. Could we not just insist that the brackets
> must always be there? Or does the lack of brackets actually mean
> something? (if it does, it's back to being confusing again).
I thought the same thing. I suspect the brackets will remain optional, but I reckon "good style" would require them. For clarity if nothing else.
Regan
|
September 10, 2007 Re: Const sucks | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | > What do these below mean ...
>
> const int (* p)
> const int *(p)
> const int (*) p
I believe I can answer that. They are all syntax errors.
The stuff inside the brackets needs to be a valid type expression.
|
September 10, 2007 Re: Const sucks | ||||
---|---|---|---|---|
| ||||
Posted in reply to Janice Caron | Janice Caron wrote:
> Oh wait! I do have one comment, or question, or whatever.
>
>> const int* p = &x; // neither p nor *p can be changed
>> const(int*) p = &x; // neither p nor *p can be changed
>
> Two ways of writing the same thing. I don't understand the need for
> the bracketless version. Could we not just insist that the brackets
> must always be there? Or does the lack of brackets actually mean
> something? (if it does, it's back to being confusing again).
I'd rather have the bracketless version to save typing in the case when I want to have the whole thing be const (which is the most common case, I believe).
Thanks,
Nathan Reed
|
Copyright © 1999-2021 by the D Language Foundation