December 07, 2007 Re: const again | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | Sean Kelly wrote:
> Oops, one last thing. Does the transitivity mean it would be impossible to have a const array of references to mutable data?
Yes.
|
December 07, 2007 Re: const again | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | Derek Parnell wrote: > On Thu, 06 Dec 2007 13:33:46 -0800, Walter Bright wrote: > >> As a result of all the const comments here, and some serious semantic problems discovered (dang it's hard to think of everything in advance), it seems there needs to be another tweak of the const behavior. > > I'm glad you're flexible ;-) My overriding concern with const is to have a useful, correct, and workable system! > >> So, we're going to try a new, simpler regime: >> const T x; >> is semantically identical to: >> const(T) x; >> and the type of x is const(T). > > Which means for reference types, 'x' is modifiable but what it references > is not modifiable. No, it means whatever part of the type is inside the () is not modifiable. > And for non-reference types, 'x' is not modifiable. So > in some cases 'x' can be changed but in some cases it can't. Is that going > to be a problem? > > const int x; // Can't change 'x' > const int[] y; // Can change 'y' but not y[n] With these, neither x, y, nor y[n] are mutable. > const C[] a; a is a const array of const C. > const (C)[] a; a is an array of const C. > const (C[]) a; a is a const array of const C. > const ((C)[]) a; a is a const array of const C. |
December 07, 2007 Re: const again | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Walter Bright wrote:
> Christopher Wright wrote:
>>> I've given up on tail const in any of its forms. The new regime has no tail const, no head const, it's just const, and fully transitive const at that.
>>
>> So if I have:
>> const(Foo)* t;
>> the pointer is const and points to a const Foo?
>
> No, it is a mutable pointer to a const Foo. A const pointer to a const Foo would be:
> const(Foo*) t;
>
>> Will that fail?
>
> Yes, because T[] will be the same thing as const(Foo)[]. Hiding it behind an alias and a template won't change that <g>.
So why do arrays take their const status from their elements when pointers don't?
|
December 07, 2007 Re: const again | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ary Borenszweig | On Thu, 06 Dec 2007 18:45:38 -0300, Ary Borenszweig wrote: >> Ary Borenszweig wrote: >>> Why not >>> >>> macro x = 3; > There a good use right there for that keyword. I agree. And I would still like to be able to group such definition together such as ... macro { x = 3; y = "qwerty"; z = 61.74; } -- Derek (skype: derek.j.parnell) Melbourne, Australia 7/12/2007 11:22:25 AM |
December 07, 2007 Re: const again | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | "Walter Bright" wrote > Janice Caron wrote: >> I understand the problem. Have you considered the possible solution which has been suggested on this group - a special syntax for classes having mutable refs to constant data? Under that suggestion, the above code would become: >> >> class C { } >> const(C)&[] a; >> a[3] = new C(); // OK >> >> It's the ampersand that makes it OK. It tells you that the reference is not constified. >> >> I think that would work, in exactly the same way that >> >> struct S { } >> struct(S)*[] a; >> a[3] = new S(); // OK >> >> works. > > There are a couple problems with it, the worst of which is its impact on > generic code: > const(T)[] > Would you put the & there or not? What would & mean if one wrote: > struct S { C c; } > const(S)&[] a; > ? What happens if you have this? const(T)*[] If T is a struct, then it's fine, but if it's a class, then what? To me the situation is just as bad. This whole problem stems from the fact that a struct declaration is a value type and a class declaration is a reference type, but they look the same. You are never going to have a consistent syntax for generic const code because you don't have a consistent syntax for normal declarations. I see one good solution. A pointer/reference declarator that acts the same for both structs and classes. class C {} struct S {} C x; // a reference to a class S x; // a struct C& x; // a reference to a class (identical to C x) S& x; // a reference to a struct (identical to S * x) S& x = new S; // heap allocated struct C& x = new C; // heap allocated class const(C) x; // a const reference to a const C const C x; // identical to const(C) const(C)& x; // a mutable reference to a const C const(C)[] x; // an array of const references to const C instances const(C)&[] x; // an array of mutable references to const C instances const(S) x; // a const S. Cannot set x or x.member const S x; // identical to const(S) const(S)[] x; // an array of const S types const(S)*[] x; // an array of mutable references to const S types const(S)&[] x; // an array of mutable references to const S types (identical to const(S)*[]) you need generic tail-const code? use const(T)& you need generic fully-const code? use const(T) or use something else instead of &, I don't care. It just seems like this notion that I can now have tail-const structs, but not tail-const classes is just as bad, if not worse, than the original problem. > One principle we try to adhere to is that it should make sense to be able to wrap any type with a struct, and have it be possible for that struct to behave as if it were that member type. const (X)* m; Please tell me how you will replace m with a 'smart' pointer type that is mutable, but the pointer contents are not. Without using a template. Because using a Template, I can do it with my regime also :) > And finally, this suggests that & means "tail-const". Tail-const has that severe problem that there is no such thing as a tail-const member function (i.e. a member function that can modify the fields of the object, but not anything those fields refer to). Huh? I thought tail-const was that you could change the reference but not the members? i.e. const(S)* x, I can change x but not x.member? -Steve |
December 07, 2007 Re: const again | ||||
---|---|---|---|---|
| ||||
Posted in reply to BCS | BCS wrote: > totally random though: I'm designing a program and ran across a place where I want to say "this pointer shall never be dereferenced, it shall only be used as an identity" the idea being that I want to be sure that the code has no dependencies on anything under it. It would be used somthing like a key in a hash table but where the test is "same thing" not "equal things". What should this be implemented as? Does this have any place in the const system? Is there an existing clean solution? Since the point of a pointer is to dereference, perhaps a pointer is the wrong thing. Perhaps it should be a struct. --------------------------------------------- Doolittle: "Bomb, what is your purpose?" Bomb #20: "To explode, of course" -- Dark Star |
December 07, 2007 Re: const again | ||||
---|---|---|---|---|
| ||||
Posted in reply to sambeau | sambeau wrote:
> Rather than re-using enum (and confusing me) why not use 'define' eg:-
>
> define x = 3;
> define long y = 4;
'define' has been proposed before. I'd prefer to stay away from it because of the negative connotations of C's preprocessor.
|
December 07, 2007 Re: const again | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | Steven Schveighoffer wrote: > What happens if you have this? > const(T)*[] Array of pointers to constant T. > If T is a struct, then it's fine, but if it's a class, then what? To me the situation is just as bad. It is perfectly consistent. I don't see why it is bad. > This whole problem stems from the fact that a struct declaration is a value type and a class declaration is a reference type, but they look the same. You are never going to have a consistent syntax for generic const code because you don't have a consistent syntax for normal declarations. Having distinctly different value and reference aggregates is, in my opinion, a good thing. > const (X)* m; > > Please tell me how you will replace m with a 'smart' pointer type that is mutable, but the pointer contents are not. That's the way it works now. You can modify m, but not X. >> And finally, this suggests that & means "tail-const". Tail-const has that severe problem that there is no such thing as a tail-const member function (i.e. a member function that can modify the fields of the object, but not anything those fields refer to). > > Huh? I thought tail-const was that you could change the reference but not the members? Yes, that's exactly what tail-const is. |
December 07, 2007 Re: const again | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ary Borenszweig | Ary Borenszweig wrote:
> Why not
>
> macro x = 3;
> ?
It's been suggested several times. It doesn't make much aesthetic sense to do things like:
macro int x = 3;
|
December 07, 2007 Re: const again | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Thu, 06 Dec 2007 16:57:20 -0800, Walter Bright wrote: > Ary Borenszweig wrote: >> Why not >> >> macro x = 3; >> ? > It's been suggested several times. I definitely think that overloading 'enum' to declare definitions is quite a lot worse than overloading 'macro' or 'alias'. > It doesn't make much aesthetic sense to do things like: > > macro int x = 3; It doesn't?!? On what authority have you made that assertion? I makes perfectly good aesthetic sense to me, more so than 'enum'. enum defname = "upload.log"; is NOT an enumeration as there is no numbers involved. macro defname = "upload.log"; looks more pleasing and grokable IMNSHO. And what do you say about the idea to group together such definitions? macro { a = 3; b = "qwerty"; c = 61.74; } rather than ... macro a = 3; macro b = "qwerty"; macro c = 61.74; -- Derek (skype: derek.j.parnell) Melbourne, Australia 7/12/2007 12:16:16 PM |
Copyright © 1999-2021 by the D Language Foundation