digitalmars.D.learn - Reuse of variables referencing const objects
- Sergey Kovrov (10/10) Mar 06 2009 I wonder if it is possible to reuse a variable for a const/invariant ref...
- Sergey Kovrov (3/3) Mar 06 2009 Other reference types (e.g. arrays) have solution to this: ``immutable(T...
- bearophile (4/5) Mar 06 2009 Arrays aren't really references, they are a small 2-word long struct, th...
- Sergey Kovrov (5/7) Mar 06 2009 I guess there is a data member for allocated buffer size as well...
- bearophile (5/8) Mar 06 2009 Objects are managed by a reference (even in a transparent way, when you ...
- Steven Schveighoffer (4/12) Mar 06 2009 std.typecons.Rebindable
- Sergey Kovrov (5/7) Mar 07 2009 Thanks Steve,
- Chris Nicholson-Sauls (10/22) Mar 09 2009 While not strictly intuitive, you could do this:
- Sergey Kovrov (13/21) Mar 09 2009 Thanks Chris, this approach indeed works, its a shame I haven't figured
- Chris Nicholson-Sauls (19/45) Mar 09 2009 Technically, no, not really. Then again, it isn't absolutely horrible
- Steven Schveighoffer (15/55) Mar 10 2009 The "is null" construct is pretty special to the compiler, it avoids
I wonder if it is possible to reuse a variable for a const/invariant reference type? By "reuse" I mean to reference different data. Considering code: auto f = new const(Foo)(); // Foo is a class, e.g. reference type f = new Foo(); // error: cannot modify const But here I really meant to assign new data to variable `f`, not to modify old instance. Of course, I could use mutable pointer to const/invariant data. But this make sense only for value types. In case of reference types this will complicate things (introducing more human errors) and just feels wrong. Consider code: const (Foo)* foo = a_condition ? &some_foo : null; if (foo !is null && *foo !is null) ...; Reference types was invented to simplify things. And they do, but not in case of const data. Do I miss something, or const support in reference types is not there yet? -- serg.
Mar 06 2009
Other reference types (e.g. arrays) have solution to this: ``immutable(TYPE)[]`` and ``immutable(TYPE[])`. I think class instances should have something similar in language as well. -- serg.
Mar 06 2009
Sergey Kovrov:Other reference types (e.g. arrays)<Arrays aren't really references, they are a small 2-word long struct, that contains a pointer to the data and a length. Bye, bearophile
Mar 06 2009
On 3/6/2009 4:42 PM, bearophile wrote:Arrays aren't really references, they are a small 2-word long struct, that contains a pointer to the data and a length.I guess there is a data member for allocated buffer size as well... Objects may be viewed as a structure too. There are context pointer virtual function table and maybe something else implementation-specific. -- serg.
Mar 06 2009
Sergey Kovrov:I guess there is a data member for allocated buffer size as well...Nope, this isn't vector of C++. It's a long story (caused to allow the slicing). The result is that the append is very slow.Objects may be viewed as a structure too. There are context pointer virtual function table and maybe something else implementation-specific.Objects are managed by a reference (even in a transparent way, when you use scope and the compiler accepts it). Bye, bearophile
Mar 06 2009
On Fri, 06 Mar 2009 09:39:43 -0500, Sergey Kovrov wrote:Other reference types (e.g. arrays) have solution to this: ``immutable(TYPE)[]`` and ``immutable(TYPE[])`. I think class instances should have something similar in language as well. -- serg.std.typecons.Rebindable http://www.digitalmars.com/d/2.0/phobos/std_typecons.html#Rebindable -Steve
Mar 06 2009
On 3/6/2009 11:29 PM, Steven Schveighoffer wrote:std.typecons.Rebindable http://www.digitalmars.com/d/2.0/phobos/std_typecons.html#RebindableThanks Steve, this is what I've been looking for, the only thing missing is comparing against null (is null). -- serg.
Mar 07 2009
Sergey Kovrov wrote:On 3/6/2009 11:29 PM, Steven Schveighoffer wrote:While not strictly intuitive, you could do this: auto var = Rebindable!(const Foo)(new Foo); assert(var.opDot !is null); As 'opDot' returns the wrapped object (with const intact). The downside to that, however, is that it won't work in those cases where Rebindable's template parameter was mutable, as then it simply aliases it. This shouldn't be a problem in general use, though. Only in generic code, which could try to check for Rebindable. -- Christopher Nicholson-Saulsstd.typecons.Rebindable http://www.digitalmars.com/d/2.0/phobos/std_typecons.html#RebindableThanks Steve, this is what I've been looking for, the only thing missing is comparing against null (is null). -- serg.
Mar 09 2009
On 3/9/2009 8:50 PM, Chris Nicholson-Sauls wrote:While not strictly intuitive, you could do this: auto var = Rebindable!(const Foo)(new Foo); assert(var.opDot !is null); As 'opDot' returns the wrapped object (with const intact). The downside to that, however, is that it won't work in those cases where Rebindable's template parameter was mutable, as then it simply aliases it. This shouldn't be a problem in general use, though. Only in generic code, which could try to check for Rebindable.Thanks Chris, this approach indeed works, its a shame I haven't figured this on my own. I wonder if it's proper usage of opDot.. In general, is it safe for client code to rely on implementation of opDot and call it directly? And in this particular case we rely on the fact that Rebindable uses opDot to forward calls. Slightly off-topic... In Python world (and I guess any other dynamic language) it is not valid to make assumptions based on implementation. Only safe way to use "foreign code" (a library, framework) is to follow documentation. That way authors of libraries are free to change their code as long as it comply with documented behavior. -- serg.
Mar 09 2009
Sergey Kovrov wrote:On 3/9/2009 8:50 PM, Chris Nicholson-Sauls wrote:Technically, no, not really. Then again, it isn't absolutely horrible either. It would be better if there were some other means of testing for null, which could be overwritten. The only alternative that comes immediately to mind would be an opCast to T, but then it would supersede any opCast defined on T. (Then again, in code dealing with Rebindable one could always chain the casts: 'cast(Bar)cast(Foo)var'. Ugly, but possibly effective.While not strictly intuitive, you could do this: auto var = Rebindable!(const Foo)(new Foo); assert(var.opDot !is null); As 'opDot' returns the wrapped object (with const intact). The downside to that, however, is that it won't work in those cases where Rebindable's template parameter was mutable, as then it simply aliases it. This shouldn't be a problem in general use, though. Only in generic code, which could try to check for Rebindable.Thanks Chris, this approach indeed works, its a shame I haven't figured this on my own. I wonder if it's proper usage of opDot.. In general, is it safe for client code to rely on implementation of opDot and call it directly?And in this particular case we rely on the fact that Rebindable uses opDot to forward calls.Considering its the only way of doing so in a completely generic manner anyhow, I don't think its a big deal. It could become annoying, however, for generic code.Slightly off-topic... In Python world (and I guess any other dynamic language) it is not valid to make assumptions based on implementation. Only safe way to use "foreign code" (a library, framework) is to follow documentation. That way authors of libraries are free to change their code as long as it comply with documented behavior. -- serg.The sentiment applies in almost any language, but a static typed language does allow for a few more assumptions. I have a habit of crawling through the sources of libraries I use anyhow, so I'm sure I occasionally do things in "*evil*" undocumented ways. ;) Maybe there should be an 'IsNull' template that understands Rebindable's. That said, I'm not sure what kind of is() invocation would match a struct template... (pssst, template ninjas...) -- Chris Nicholson-Sauls
Mar 09 2009
On Mon, 09 Mar 2009 23:00:50 -0400, Chris Nicholson-Sauls wrote:Sergey Kovrov wrote:The "is null" construct is pretty special to the compiler, it avoids calling any methods of any kind, and simply does a bit compare. I'm not sure if implicit casting is used. What would also work is this: auto var = Rebindable!(const Foo)(new Foo); assert(var !is var.init); // or assert(var !is typeof(var)(null)); Personally, I think the compiler should recognize the "struct with opDot" form, and translate var is null to var.opDot is null automatically. Or at least translate to something like the latter form, where it tries to construct a type using null. Why not file an enhancment request? -SteveOn 3/9/2009 8:50 PM, Chris Nicholson-Sauls wrote:Technically, no, not really. Then again, it isn't absolutely horrible either. It would be better if there were some other means of testing for null, which could be overwritten. The only alternative that comes immediately to mind would be an opCast to T, but then it would supersede any opCast defined on T. (Then again, in code dealing with Rebindable one could always chain the casts: 'cast(Bar)cast(Foo)var'. Ugly, but possibly effective.While not strictly intuitive, you could do this: auto var = Rebindable!(const Foo)(new Foo); assert(var.opDot !is null); As 'opDot' returns the wrapped object (with const intact). The downside to that, however, is that it won't work in those cases where Rebindable's template parameter was mutable, as then it simply aliases it. This shouldn't be a problem in general use, though. Only in generic code, which could try to check for Rebindable.Thanks Chris, this approach indeed works, its a shame I haven't figured this on my own. I wonder if it's proper usage of opDot.. In general, is it safe for client code to rely on implementation of opDot and call it directly?And in this particular case we rely on the fact that Rebindable uses opDot to forward calls.Considering its the only way of doing so in a completely generic manner anyhow, I don't think its a big deal. It could become annoying, however, for generic code.Slightly off-topic... In Python world (and I guess any other dynamic language) it is not valid to make assumptions based on implementation. Only safe way to use "foreign code" (a library, framework) is to follow documentation. That way authors of libraries are free to change their code as long as it comply with documented behavior. -- serg.The sentiment applies in almost any language, but a static typed language does allow for a few more assumptions. I have a habit of crawling through the sources of libraries I use anyhow, so I'm sure I occasionally do things in "*evil*" undocumented ways. ;) Maybe there should be an 'IsNull' template that understands Rebindable's. That said, I'm not sure what kind of is() invocation would match a struct template... (pssst, template ninjas...)
Mar 10 2009