digitalmars.D - Is This a Solution For the Const/Rebindable Issue?
- Mehrdad (26/26) Jun 12 2011 An idea came to my mind for fixing the const/rebindable issue, and I'm
- David Nadlinger (4/11) Jun 12 2011 You might be interested in Michel's const(Object)ref proposal:
- Steven Schveighoffer (13/17) Jun 12 2011 It has been brought up, a long time ago, by me on the phobos mailing lis...
- Mehrdad (2/19) Jun 12 2011 No problem, I won't. :) But if you remember the reason, please post it s...
- Steven Schveighoffer (28/52) Jun 12 2011 I'll see if it's in my sent mail...
- Mehrdad (9/37) Jun 12 2011 Hm... that's a reason, but it seems like we can get around it relatively...
- Steven Schveighoffer (13/52) Jun 12 2011 No. final is not a type constructor, so it does not get carried around ...
- Steven Schveighoffer (5/11) Jun 12 2011 Note, you might be able to forbid this line, but I don't think this work...
- Mehrdad (8/22) Jun 12 2011 class is
- Steven Schveighoffer (9/31) Jun 12 2011 What is the type of s.o? Hint, it can't be final, because final isn't
An idea came to my mind for fixing the const/rebindable issue, and I'm not sure if it's a good idea or not but I thought I'd mention it. I'm not sure if it's been mentioned before, but a quick search didn't make it seem like it has been. Right now, the trouble seems to be from the fact that a piece of code like: const(Object) obj; prevents obj from being assigned a new object. For the solution: Why not just relax this restriction for reference types? After all, references are just pretty much pointers, and it's not we disallow pointers to const value types from being rebindable, right? Value types (e.g. structs) would still not be rebindable (that makes sense, since it would really be changing the value) but reference types like Object would be rebindable by default. We could then allow the "final" keyword to be used for members that are reference types (but this would NOT be allowed for value types), to simply prevent their rebinding (although they need not be const). Examples: int i; //variable const int j = 5; //constant final int k; //compiler ERROR (should say const instead, since int is a value type) const Object obj1; //rebindable reference, but contents are all const final Object obj2; //non-rebindable reference to a regular object final const Object obj3; //non-rebindable reference to a const object Does this sound like a good idea?
Jun 12 2011
On 6/13/11 5:36 AM, Mehrdad wrote:An idea came to my mind for fixing the const/rebindable issue, and I'm not sure if it's a good idea or not but I thought I'd mention it. I'm not sure if it's been mentioned before, but a quick search didn't make it seem like it has been. Right now, the trouble seems to be from the fact that a piece of code like: const(Object) obj; prevents obj from being assigned a new object.You might be interested in Michel's const(Object)ref proposal: https://github.com/D-Programming-Language/dmd/pull/3 David
Jun 12 2011
On Sun, 12 Jun 2011 23:36:21 -0400, Mehrdad <wfunction hotmail.com> wrote:An idea came to my mind for fixing the const/rebindable issue, and I'm not sure if it's a good idea or not but I thought I'd mention it. I'm not sure if it's been mentioned before, but a quick search didn't make it seem like it has been.It has been brought up, a long time ago, by me on the phobos mailing list (the idea to just assume const(Object) is rebindable, not the final thing). I think it was on the ML that Andrei maintained, so it's archive is gone. I had the exact same thoughts as you, and Walter found a perfectly iron-clad reason why it doesn't work. I can't say I remember the exact reason (maybe he does off the top of his head), but it definitely killed the idea quite well. So it doesn't work unfortunately :( I know the lack of reference/reason is unsatisfying, but I hope you can trust me that to pursue this is not going to go anywhere, and I don't want to re-argue it again... -Steve
Jun 12 2011
== Quote from Steven Schveighoffer (schveiguy yahoo.com)'s articleOn Sun, 12 Jun 2011 23:36:21 -0400, Mehrdad <wfunction hotmail.com> wrote:No problem, I won't. :) But if you remember the reason, please post it since I'm curious!An idea came to my mind for fixing the const/rebindable issue, and I'm not sure if it's a good idea or not but I thought I'd mention it. I'm not sure if it's been mentioned before, but a quick search didn't make it seem like it has been.It has been brought up, a long time ago, by me on the phobos mailing list (the idea to just assume const(Object) is rebindable, not the final thing). I think it was on the ML that Andrei maintained, so it's archive is gone. I had the exact same thoughts as you, and Walter found a perfectly iron-clad reason why it doesn't work. I can't say I remember the exact reason (maybe he does off the top of his head), but it definitely killed the idea quite well. So it doesn't work unfortunately :( I know the lack of reference/reason is unsatisfying, but I hope you can trust me that to pursue this is not going to go anywhere, and I don't want to re-argue it again... -Steve
Jun 12 2011
On Sun, 12 Jun 2011 23:58:01 -0400, Mehrdad <wfunction hotmail.com> wrote:== Quote from Steven Schveighoffer (schveiguy yahoo.com)'s articleI'll see if it's in my sent mail... OK, I found it, it was actually the same logic but applied to shared objects. But Walter convinced me that the issues are the same (at least for this problem). Consider this type: struct S { Object o; } now, we have these two variables: const(S) s; const(Object) o; finally, the issue: void kryptonite(ref const(Object) o) { o = new Object(); } kryptonite(o); // fine kryptonite(s.o);// oops! The problem is, there isn't a way to distinguish a tail-const object reference from a fully const object reference, yet both types can exist. If you want to pass a reference to such a reference, then you run into sticky issues like this one. I understand that you want final to mean "head const", but final is a storage class, not a type modifier -- it cannot be used as part of the type info. -SteveOn Sun, 12 Jun 2011 23:36:21 -0400, Mehrdad <wfunction hotmail.com> wrote:No problem, I won't. :) But if you remember the reason, please post it since I'm curious!An idea came to my mind for fixing the const/rebindable issue, and I'm not sure if it's a good idea or not but I thought I'd mention it. I'm not sure if it's been mentioned before, but a quick search didn't make it seem like it has been.It has been brought up, a long time ago, by me on the phobos mailing list (the idea to just assume const(Object) is rebindable, not the final thing). I think it was on the ML that Andrei maintained, so it's archive is gone. I had the exact same thoughts as you, and Walter found a perfectly iron-clad reason why it doesn't work. I can't say I remember the exact reason (maybe he does off the top of his head), but it definitely killed the idea quite well. So it doesn't work unfortunately :( I know the lack of reference/reason is unsatisfying, but I hope you can trust me that to pursue this is not going to go anywhere, and I don't want to re-argue it again... -Steve
Jun 12 2011
== Quote from Steven Schveighoffer (schveiguy yahoo.com)'s articleOn Sun, 12 Jun 2011 23:58:01 -0400, Mehrdad <wfunction hotmail.com> wrote: I'll see if it's in my sent mail... OK, I found it, it was actually the same logic but applied to shared objects. But Walter convinced me that the issues are the same (at least for this problem). Consider this type: struct S { Object o; } now, we have these two variables: const(S) s; const(Object) o; finally, the issue: void kryptonite(ref const(Object) o) { o = new Object(); } kryptonite(o); // fine kryptonite(s.o);// oops! The problem is, there isn't a way to distinguish a tail-const object reference from a fully const object reference, yet both types can exist. If you want to pass a reference to such a reference, then you run into sticky issues like this one. I understand that you want final to mean "head const", but final is a storage class, not a type modifier -- it cannot be used as part of the type info. -SteveHm... that's a reason, but it seems like we can get around it relatively easily. It seems like it could be solved by making it so that const(S) also makes the fields of S final. That way, you could no longer do `kryptonite(s.o)` because it's final. You could then say "final ref const Object o" to allow for passing that field, because that would mean the callee cannot modify o. Wouldn't that work? (Note that this does **NOT** require that "final" be a type constructor. That would be ugly. It can remain a storage class, a property of the variable rather than the object.)
Jun 12 2011
On Mon, 13 Jun 2011 01:06:43 -0400, Mehrdad <wfunction hotmail.com> wrote:== Quote from Steven Schveighoffer (schveiguy yahoo.com)'s articleNo. final is not a type constructor, so it does not get carried around with the type. final int i; assert(typeof(i) == int); // after the declaration, the storage class is gone from the type! int * ip = &i; *ip = 4; // can't be forbidden. final can only apply to the storage of the variable, and I'm not actually sure the above is valid in today's D2. I think it's only a storage class in D1. In D2, I think it's only use is to declare a function as not-virtual. -SteveOn Sun, 12 Jun 2011 23:58:01 -0400, Mehrdad <wfunction hotmail.com> wrote: I'll see if it's in my sent mail... OK, I found it, it was actually the same logic but applied to shared objects. But Walter convinced me that the issues are the same (at least for this problem). Consider this type: struct S { Object o; } now, we have these two variables: const(S) s; const(Object) o; finally, the issue: void kryptonite(ref const(Object) o) { o = new Object(); } kryptonite(o); // fine kryptonite(s.o);// oops! The problem is, there isn't a way to distinguish a tail-const object reference from a fully const object reference, yet both types can exist. If you want to pass a reference to such a reference, then you run into sticky issues like this one. I understand that you want final to mean "head const", but final is a storage class, not a type modifier -- it cannot be used as part of the type info. -SteveHm... that's a reason, but it seems like we can get around it relatively easily. It seems like it could be solved by making it so that const(S) also makes the fields of S final. That way, you could no longer do `kryptonite(s.o)` because it's final. You could then say "final ref const Object o" to allow for passing that field, because that would mean the callee cannot modify o. Wouldn't that work?
Jun 12 2011
On Mon, 13 Jun 2011 01:09:57 -0400, Steven Schveighoffer <schveiguy yahoo.com> wrote:No. final is not a type constructor, so it does not get carried around with the type. final int i; assert(typeof(i) == int); // after the declaration, the storage class is gone from the type! int * ip = &i;Note, you might be able to forbid this line, but I don't think this works well. -Steve
Jun 12 2011
== Quote from Steven Schveighoffer (schveiguy yahoo.com)'s articleOn Mon, 13 Jun 2011 01:09:57 -0400, Steven Schveighoffer <schveiguy yahoo.com> wrote:aroundNo. final is not a type constructor, so it does not get carriedclass iswith the type. final int i; assert(typeof(i) == int); // after the declaration, the storagethis worksgone from the type! int * ip = &i;Note, you might be able to forbid this line, but I don't thinkwell. -SteveI completely realize that final is not a type constructor (I don't want it to be one either), but I'm failing to what that has to do with anything. How does that fact affect my previous answer?
Jun 12 2011
On Mon, 13 Jun 2011 01:38:17 -0400, Mehrdad <wfunction hotmail.com> wrote:== Quote from Steven Schveighoffer (schveiguy yahoo.com)'s articleWhat is the type of s.o? Hint, it can't be final, because final isn't part of the type. What is the type of &s.o? If the type of s.o is T (let's say) and the type of &s.o is not T*, then I think we have a problem. I just think it doesn't work. Maybe you can figure out a way it can, but I don't think it can be done without severe confusing semantics. -SteveOn Mon, 13 Jun 2011 01:09:57 -0400, Steven Schveighoffer <schveiguy yahoo.com> wrote:aroundNo. final is not a type constructor, so it does not get carriedclass iswith the type. final int i; assert(typeof(i) == int); // after the declaration, the storagethis worksgone from the type! int * ip = &i;Note, you might be able to forbid this line, but I don't thinkwell. -SteveI completely realize that final is not a type constructor (I don't want it to be one either), but I'm failing to what that has to do with anything. How does that fact affect my previous answer?
Jun 12 2011
== Quote from Steven Schveighoffer (schveiguy yahoo.com)'s articleWhat is the type of s.o? Hint, it can't be final, because final isn't part of the type. What is the type of &s.o? If the type of s.o is T (let's say) and the type of &s.o is not T*, then I think we have a problem. I just think it doesn't work. Maybe you can figure out a way it can, but I don't think it can be donewithout severe confusing semantics.-SteveType of s.o: const(Object), like before. Can be reassigned. Type of &s.o: Pointer to a const(Object)... yeah I think I finally see. x_____x Gosh, that sucks... thanks for the explanation, I appreciate it. :) I'll see if I can figure out a way (though I doubt I can, lol)...
Jun 12 2011
On 6/12/2011 11:00 PM, Mehrdad wrote:== Quote from Steven Schveighoffer (schveiguy yahoo.com)'s articleHm... how about if you just don't allow the address of a final variable to be taken? I'm probably missing something (it's past midnight...) but is that a potential solution?What is the type of s.o? Hint, it can't be final, because final isn't part of the type. What is the type of&s.o? If the type of s.o is T (let's say) and the type of&s.o is not T*, then I think we have a problem. I just think it doesn't work. Maybe you can figure out a way it can, but I don't think it can be donewithout severe confusing semantics.-SteveType of s.o: const(Object), like before. Can be reassigned. Type of&s.o: Pointer to a const(Object)... yeah I think I finally see. x_____x Gosh, that sucks... thanks for the explanation, I appreciate it. :) I'll see if I can figure out a way (though I doubt I can, lol)...
Jul 03 2011