digitalmars.D - Latest const expansion
- Regan Heath (45/45) Sep 11 2007 I'm interested in what people think of the idea(s) I had for expanding
- Alexander Panek (28/29) Sep 11 2007 It's a tad complicated, but makes sense. More sense - to me - than the
- Regan Heath (5/34) Sep 11 2007 Correct.
- Alexander Panek (3/6) Sep 11 2007 I liek.
- Regan Heath (4/42) Sep 11 2007 Slight correction; 'data' in this case is whatever the type of T is,
- Yigal Chripun (16/90) Sep 11 2007 Hello,
- Janice Caron (5/13) Sep 11 2007 head and tail are good variable names, so I'd rather they didn't
- Yigal Chripun (5/22) Sep 11 2007 agreed, no need to make tail/head reserved words.
- Bill Baxter (15/38) Sep 11 2007 I think tailconst is too long a word for something that will probably be...
- Jarrett Billingsley (3/5) Sep 11 2007 I was SO going to make that reference. Man my day is just RUINED.
- Mike Streatfield (3/10) Sep 12 2007 I was SO going to make that retort to that reference. Man my day is just...
- Jarrett Billingsley (3/5) Sep 12 2007 My brain literally just exploded.
- Bill Baxter (34/37) Sep 11 2007 I think this befuddles the nice clean idea of const(...) as a type
- 0ffh (6/11) Sep 11 2007 A couple of suggestions for T const, *T mutable:
- Janice Caron (13/16) Sep 11 2007 We've had the keyword final for some time in D2.0, specifically for
- Regan Heath (8/30) Sep 12 2007 Local to the body of a class, for example. Local to the global scope of...
- Bruno Medeiros (15/36) Sep 12 2007 That's pretty much a horrendous syntax, and I hope I'm not the only to
- Janice Caron (5/9) Sep 12 2007 That's what we had in D2.0. That's what we've just got rid of.
- Bill Baxter (12/24) Sep 13 2007 I think const(T) was going to mean the same thing as const T for simple
- Bruno Medeiros (11/20) Sep 13 2007 No, it's not what he have now in D2.0.
- Bruce Adams (4/48) Sep 12 2007 You sick puppy. If I hadn't seen your many other wonderful posts I'd ass...
- Bill Baxter (6/53) Sep 12 2007 Heh. Well I'd prefer the const*(T), const**(T) thing I posted
I'm interested in what people think of the idea(s) I had for expanding on Walter's latest const proposal and handling head/tail const on class references. Ideas originally posted as replies, here: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=58107 http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=58112 Also here: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=58114 http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=58115 In short, Where: head const - means the class reference itself cannot be modified tail const - means the class members cannot be modified Where T is a class: const(T) indicates both head/tail const const(*T) indicates tail const const(&T) indicates head const Eg. class A { int a; } const(A) a; //a cannot be modified, a.a cannot be modified const(*A) b; //a can be modified, a.a cannot be modified const(&A) c; //a cannot be modified, a.a can be modified The idea being that const(*T) means const("value of the type T") where the value of a class reference is the class instance itself. Likewise const(&T) means const("reference/pointer of the type T") indicating the reference is to be const. For template/meta-programming purposes the syntax "const(*T)" and "const(&T)" should be legal for T where T is a value type, i.e. struct, union, and primitives (excluding pointers) but will be identical in behaviour to "const(T)" For pointers and arrays the "const(*T)" (tail const) syntax is not required as we can say: const(T)[] const(T)* but perhaps for meta-programming purposes it should be legal, eg. const(*char[]) const(*char*) For pointers and arrays the "const(&T)" (head const) syntax is required as there is currently no way to get a const array reference to mutable data, so: const(&char[]) const(&char*) would specify a const array reference and const pointer respecitvely both to mutable 'char' data. Thoughts? Too complicated? :P Regan
Sep 11 2007
Regan Heath wrote:Thoughts? Too complicated? :PIt's a tad complicated, but makes sense. More sense - to me - than the former const/invariant/final and the upcoming const/invariant combinations. At least you summed it up in a way so I understand it. :) Yet, I have some questions: -- class A { int i; } const(*A) a; -- Do I understand correctly? The variable `a' - as in a reference to an instance of `class A' is mutable, but the instance `a' refers to is not? (read as: `class A { const { int i; ... } }', just for this instance reference) This also means, that you can reference to another instance with `a': -- a = b; -- Right? -- const(&A) a; -- This means, that the reference to the class instance is not mutable, yet the actual instance is? What exactly do `const(T)[]' and `const(T)*' imply? Immutable data, or immutable reference/pointer? .. I think that's it for now. So long, and thanks for the fish. Best regards, Alex
Sep 11 2007
Alexander Panek wrote:Regan Heath wrote:Correct.Thoughts? Too complicated? :PIt's a tad complicated, but makes sense. More sense - to me - than the former const/invariant/final and the upcoming const/invariant combinations. At least you summed it up in a way so I understand it. :) Yet, I have some questions: -- class A { int i; } const(*A) a; -- Do I understand correctly? The variable `a' - as in a reference to an instance of `class A' is mutable, but the instance `a' refers to is not? (read as: `class A { const { int i; ... } }', just for this instance reference) This also means, that you can reference to another instance with `a': -- a = b; -- Right?-- const(&A) a; -- This means, that the reference to the class instance is not mutable, yet the actual instance is?Correct.What exactly do `const(T)[]' and `const(T)*' imply? Immutable data, or immutable reference/pointer?Immutable data. Regan
Sep 11 2007
Regan Heath wrote:Correct. Correct. Immutable data.I liek. /me votes up.
Sep 11 2007
Regan Heath wrote:Alexander Panek wrote:Slight correction; 'data' in this case is whatever the type of T is, which could be a class reference or a pointer, of course. ReganRegan Heath wrote:Correct.Thoughts? Too complicated? :PIt's a tad complicated, but makes sense. More sense - to me - than the former const/invariant/final and the upcoming const/invariant combinations. At least you summed it up in a way so I understand it. :) Yet, I have some questions: -- class A { int i; } const(*A) a; -- Do I understand correctly? The variable `a' - as in a reference to an instance of `class A' is mutable, but the instance `a' refers to is not? (read as: `class A { const { int i; ... } }', just for this instance reference) This also means, that you can reference to another instance with `a': -- a = b; -- Right?-- const(&A) a; -- This means, that the reference to the class instance is not mutable, yet the actual instance is?Correct.What exactly do `const(T)[]' and `const(T)*' imply? Immutable data, or immutable reference/pointer?Immutable data.
Sep 11 2007
Regan Heath wrote:I'm interested in what people think of the idea(s) I had for expanding on Walter's latest const proposal and handling head/tail const on class references. Ideas originally posted as replies, here: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmar .D&article_id=58107 http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmar .D&article_id=58112 Also here: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmar .D&article_id=58114 http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmar .D&article_id=58115 In short, Where: head const - means the class reference itself cannot be modified tail const - means the class members cannot be modified Where T is a class: const(T) indicates both head/tail const const(*T) indicates tail const const(&T) indicates head const Eg. class A { int a; } const(A) a; //a cannot be modified, a.a cannot be modified const(*A) b; //a can be modified, a.a cannot be modified const(&A) c; //a cannot be modified, a.a can be modified The idea being that const(*T) means const("value of the type T") where the value of a class reference is the class instance itself. Likewise const(&T) means const("reference/pointer of the type T") indicating the reference is to be const. For template/meta-programming purposes the syntax "const(*T)" and "const(&T)" should be legal for T where T is a value type, i.e. struct, union, and primitives (excluding pointers) but will be identical in behaviour to "const(T)" For pointers and arrays the "const(*T)" (tail const) syntax is not required as we can say: const(T)[] const(T)* but perhaps for meta-programming purposes it should be legal, eg. const(*char[]) const(*char*) For pointers and arrays the "const(&T)" (head const) syntax is required as there is currently no way to get a const array reference to mutable data, so: const(&char[]) const(&char*) would specify a const array reference and const pointer respecitvely both to mutable 'char' data. Thoughts? Too complicated? :P ReganHello, I'm a new user of D. I've read about the const system and i agree with everyone who wants a head/tail const. however i disagree with the sytax proposed by various people as being unreadable. const(*char*) or const (&char**) is quite confusing in my opinion. my proposal is to simply use the terms tail/head, so the syntax will be [head|tail] const (T) | const T for example: head const (C) c; // c is const but c.x isn't tail const (C) c; // c is mutable but c.x is const const (C) c; // as before, both c and c.x are const head const C c; // Error tail const C c; // Error Yigal Chripun
Sep 11 2007
On 9/11/07, Yigal Chripun <yigal100 gmail.com> wrote:my proposal is to simply use the terms tail/head, so the syntax will be [head|tail] const (T) | const T for example: head const (C) c; // c is const but c.x isn't tail const (C) c; // c is mutable but c.x is const const (C) c; // as before, both c and c.x are const head const C c; // Error tail const C c; // Errorhead and tail are good variable names, so I'd rather they didn't become reserved words. But I've no problem with headconst and tailconst. Only ... would that mean we'd then also have to have a tailtailconst?
Sep 11 2007
Janice Caron wrote:On 9/11/07, Yigal Chripun <yigal100 gmail.com> wrote:agreed, no need to make tail/head reserved words. i thought 1 level of "tailness" is enough to cover 99% of cases... can you give a use case for "tailtailconst" that can't be resolved with a combination of the const parens and tailconst?my proposal is to simply use the terms tail/head, so the syntax will be [head|tail] const (T) | const T for example: head const (C) c; // c is const but c.x isn't tail const (C) c; // c is mutable but c.x is const const (C) c; // as before, both c and c.x are const head const C c; // Error tail const C c; // Errorhead and tail are good variable names, so I'd rather they didn't become reserved words. But I've no problem with headconst and tailconst. Only ... would that mean we'd then also have to have a tailtailconst?
Sep 11 2007
Yigal Chripun wrote:Janice Caron wrote:I think tailconst is too long a word for something that will probably be used pretty frequently. If you think of C++ the most commonly used const with pointer types is "const T* foo;" which means tail const. The equivalent with a D class would be come "tailconst T foo" and you'd have cases where "tailconst" appears 5 times in a function signature. tailconst Z some_func(tailconst A a, tailconst B b, tailconst C c, tailconst D d) { ... } Ick. How about shortening it to just "tconst"? And there could be ttconst, and tttconst as needed. Similarly "hconst". And still the const(T)* syntax can be a synonym for tconst(T*). Kinda reminiscent of cons, cdr, cddr, cdddr, from lisp, which really are basically serving the same purpose. --bbOn 9/11/07, Yigal Chripun <yigal100 gmail.com> wrote:agreed, no need to make tail/head reserved words. i thought 1 level of "tailness" is enough to cover 99% of cases... can you give a use case for "tailtailconst" that can't be resolved with a combination of the const parens and tailconst?my proposal is to simply use the terms tail/head, so the syntax will be [head|tail] const (T) | const T for example: head const (C) c; // c is const but c.x isn't tail const (C) c; // c is mutable but c.x is const const (C) c; // as before, both c and c.x are const head const C c; // Error tail const C c; // Errorhead and tail are good variable names, so I'd rather they didn't become reserved words. But I've no problem with headconst and tailconst. Only ... would that mean we'd then also have to have a tailtailconst?
Sep 11 2007
"Bill Baxter" <dnewsgroup billbaxter.com> wrote in message news:fc72rn$rjv$1 digitalmars.com...Kinda reminiscent of cons, cdr, cddr, cdddr, from lisp, which really are basically serving the same purpose.I was SO going to make that reference. Man my day is just RUINED.
Sep 11 2007
Jarrett Billingsley wrote:"Bill Baxter" <dnewsgroup billbaxter.com> wrote in message news:fc72rn$rjv$1 digitalmars.com...I was SO going to make that retort to that reference. Man my day is just META-RUINED.Kinda reminiscent of cons, cdr, cddr, cdddr, from lisp, which really are basically serving the same purpose.I was SO going to make that reference. Man my day is just RUINED.
Sep 12 2007
"Mike Streatfield" <dnewsgroup.c talyst.me.uk> wrote in message news:fc97mq$1jov$1 digitalmars.com...I was SO going to make that retort to that reference. Man my day is just META-RUINED.My brain literally just exploded.
Sep 12 2007
Regan Heath wrote:const(T) indicates both head/tail const const(*T) indicates tail const const(&T) indicates head constI think this befuddles the nice clean idea of const(...) as a type constructor that takes the type inside the parens and makes a new const-ified type out of it. But fortunately that cleanness can be reclaimed by thinking instead of a _family_ of type constructors, which do head/tail/full const of their argument. In short, just move the symbol out of the parens so the thing inside the parens remains a valid type. const(T) - type constructor making both head/tail const version of T const*(T) - type constructor making tail const version of T const**(T) - type constructor making tail-of-tail const version of T [..and now we're back to what I think was Janice's suggestion many many posts ago, which I liked then too.] I think this is quite logical. The const*() type constructor can be thought of as dereferencing the type in parens by one level and *then* applying the constness to the result, and then returning a reference to that type. For example const*(int*): dereference int* to get --> int apply const to get --> const(int) address-of to get --> const(int)* So in this case it's the same as const(int)*. But for a class, const*(C), it lets you do something that can't be done by peeling off the pointer. That's tail const. I'm not so sure I like using const&(T) to mean head const, though. It doesn't really seem right for some reason. Using the * for tail has an interpretation in terms of performing an actual dereference on an object, then applying full const. But const&() doesn't really have such an interpretation. You're not taking the address and then applying full const. So for that reason another keyword is preferable I think. Like 'final'. Or maybe headconst or 'hconst'. --bb
Sep 11 2007
Bill Baxter wrote:const(T) - type constructor making both head/tail const version of T const*(T) - type constructor making tail const version of T const**(T) - type constructor making tail-of-tail const version of T++vote;I'm not so sure I like using const&(T) to mean head const, though. It doesn't really seem right for some reason.A couple of suggestions for T const, *T mutable: 1) *const(T) - "reverse" of the suggested tail const syntax 2) mutable*(const(T)) - a bit keyboard intensive, but nicely obvious Regards, Frank
Sep 11 2007
On 9/11/07, Bill Baxter <dnewsgroup billbaxter.com> wrote:So for that reason another keyword is preferable I think. Like 'final'. Or maybe headconst or 'hconst'.We've had the keyword final for some time in D2.0, specifically for the purpose of head-constness, so if it's deemed that we need it, final would be as good a keyword as any. But do we need it? Is there a need for head const at all? Walter seems to have concluded that it's not needed. And every use case I can think of could be done by other means, so I think I agree. In every single circumstance I can think of, headconst(T) x; could simply be replaced by T x; and nothing would fall over. What is gained by the head-constness? It's totally local.
Sep 11 2007
Janice Caron wrote:On 9/11/07, Bill Baxter <dnewsgroup billbaxter.com> wrote:Local to the body of a class, for example. Local to the global scope of the program also. I think it's useful in that it provides a guarantee that a reference/pointer itself will never change, which is a boon for multithreaded work for example. Allowing reads using that reference/pointer without locking (in some cases). ReganSo for that reason another keyword is preferable I think. Like 'final'. Or maybe headconst or 'hconst'.We've had the keyword final for some time in D2.0, specifically for the purpose of head-constness, so if it's deemed that we need it, final would be as good a keyword as any. But do we need it? Is there a need for head const at all? Walter seems to have concluded that it's not needed. And every use case I can think of could be done by other means, so I think I agree. In every single circumstance I can think of, headconst(T) x; could simply be replaced by T x; and nothing would fall over. What is gained by the head-constness? It's totally local.
Sep 12 2007
Bill Baxter wrote:Regan Heath wrote:That's pretty much a horrendous syntax, and I hope I'm not the only to think that.const(T) indicates both head/tail const const(*T) indicates tail const const(&T) indicates head constI think this befuddles the nice clean idea of const(...) as a type constructor that takes the type inside the parens and makes a new const-ified type out of it. But fortunately that cleanness can be reclaimed by thinking instead of a _family_ of type constructors, which do head/tail/full const of their argument. In short, just move the symbol out of the parens so the thing inside the parens remains a valid type. const(T) - type constructor making both head/tail const version of T const*(T) - type constructor making tail const version of T const**(T) - type constructor making tail-of-tail const version of T [..and now we're back to what I think was Janice's suggestion many many posts ago, which I liked then too.]Yes, I like this better too. The '*'s are not mixed the 'T', which is better. But like I mentioned in Janice's thread, I think it would be even better to have this: final const(T) - head/tail const const(T) - tail const ... and tail-of-tail const would not be supported, at least not with a native syntax. I don't see much use for it, so let's keep it simple (but should there be a use, such a construct could be made with meta-programming anyway). -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Sep 12 2007
On 9/13/07, Bruno Medeiros <brunodomedeiros+spam com.gmail> wrote:I think it would be even better to have this: final const(T) - head/tail const const(T) - tail constThat's what we had in D2.0. That's what we've just got rid of. Almost nobody likes the notion that const(T) should mean something different from const T. That idea has already been rejected as being too confusing.
Sep 12 2007
Janice Caron wrote:On 9/13/07, Bruno Medeiros <brunodomedeiros+spam com.gmail> wrote:I think const(T) was going to mean the same thing as const T for simple value types, no? The thing that's confusing is that that it also means the same thing as just plain T for a simple value type. That and the fact that this const(T)* foo; // T's can't change pointer can. is not the same as: alias const(T) S; // S is same as a T, actually S* foo; // no const here anymore. .. or maybe it was the same... I can't remember what was what now. --bbI think it would be even better to have this: final const(T) - head/tail const const(T) - tail constThat's what we had in D2.0. That's what we've just got rid of. Almost nobody likes the notion that const(T) should mean something different from const T. That idea has already been rejected as being too confusing.
Sep 13 2007
Janice Caron wrote:On 9/13/07, Bruno Medeiros <brunodomedeiros+spam com.gmail> wrote:No, it's not what he have now in D2.0. I said that const(T) should mean "tail const". Since I didn't mention anything else, it should be inferred that I mean that const(T) should mean "tail const" *everywhere*. In D2.0 const(T) means "tail const" if it's at the top level of a declaration, and if it is not it means "head/tail const". That behavior is of course, different from my suggestion. -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#DI think it would be even better to have this: final const(T) - head/tail const const(T) - tail constThat's what we had in D2.0. That's what we've just got rid of.
Sep 13 2007
Bill Baxter Wrote:Yigal Chripun wrote:You sick puppy. If I hadn't seen your many other wonderful posts I'd assume you were trolling with that one. Keyword profilerifation is a classic language design anti-pattern. If you must go down that route then your "const" should be parameterisable. I'm not terribly keen on that idea either.Janice Caron wrote:I think tailconst is too long a word for something that will probably be used pretty frequently. If you think of C++ the most commonly used const with pointer types is "const T* foo;" which means tail const. The equivalent with a D class would be come "tailconst T foo" and you'd have cases where "tailconst" appears 5 times in a function signature. tailconst Z some_func(tailconst A a, tailconst B b, tailconst C c, tailconst D d) { ... } Ick. How about shortening it to just "tconst"? And there could be ttconst, and tttconst as needed. Similarly "hconst". And still the const(T)* syntax can be a synonym for tconst(T*). Kinda reminiscent of cons, cdr, cddr, cdddr, from lisp, which really are basically serving the same purpose. --bbOn 9/11/07, Yigal Chripun <yigal100 gmail.com> wrote:agreed, no need to make tail/head reserved words. i thought 1 level of "tailness" is enough to cover 99% of cases... can you give a use case for "tailtailconst" that can't be resolved with a combination of the const parens and tailconst?my proposal is to simply use the terms tail/head, so the syntax will be [head|tail] const (T) | const T for example: head const (C) c; // c is const but c.x isn't tail const (C) c; // c is mutable but c.x is const const (C) c; // as before, both c and c.x are const head const C c; // Error tail const C c; // Errorhead and tail are good variable names, so I'd rather they didn't become reserved words. But I've no problem with headconst and tailconst. Only ... would that mean we'd then also have to have a tailtailconst?
Sep 12 2007
Bruce Adams wrote:Bill Baxter Wrote:Heh. Well I'd prefer the const*(T), const**(T) thing I posted previously. But if people don't go for that I'd rather at least have short keywords rather than a beasts like "tailconst" and "tailtailconst". :-) --bbYigal Chripun wrote:You sick puppy. If I hadn't seen your many other wonderful posts I'd assume you were trolling with that one. Keyword profilerifation is a classic language design anti-pattern. If you must go down that route then your "const" should be parameterisable. I'm not terribly keen on that idea either.Janice Caron wrote:I think tailconst is too long a word for something that will probably be used pretty frequently. If you think of C++ the most commonly used const with pointer types is "const T* foo;" which means tail const. The equivalent with a D class would be come "tailconst T foo" and you'd have cases where "tailconst" appears 5 times in a function signature. tailconst Z some_func(tailconst A a, tailconst B b, tailconst C c, tailconst D d) { ... } Ick. How about shortening it to just "tconst"? And there could be ttconst, and tttconst as needed. Similarly "hconst". And still the const(T)* syntax can be a synonym for tconst(T*). Kinda reminiscent of cons, cdr, cddr, cdddr, from lisp, which really are basically serving the same purpose. --bbOn 9/11/07, Yigal Chripun <yigal100 gmail.com> wrote:agreed, no need to make tail/head reserved words. i thought 1 level of "tailness" is enough to cover 99% of cases... can you give a use case for "tailtailconst" that can't be resolved with a combination of the const parens and tailconst?my proposal is to simply use the terms tail/head, so the syntax will be [head|tail] const (T) | const T for example: head const (C) c; // c is const but c.x isn't tail const (C) c; // c is mutable but c.x is const const (C) c; // as before, both c and c.x are const head const C c; // Error tail const C c; // Errorhead and tail are good variable names, so I'd rather they didn't become reserved words. But I've no problem with headconst and tailconst. Only ... would that mean we'd then also have to have a tailtailconst?
Sep 12 2007