Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
March 06, 2009 Reuse of variables referencing const objects | ||||
---|---|---|---|---|
| ||||
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. |
March 06, 2009 Re: Reuse of variables referencing const objects | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sergey Kovrov | 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. |
March 06, 2009 Re: Reuse of variables referencing const objects | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sergey Kovrov | 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
|
March 06, 2009 Re: Reuse of variables referencing const objects | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | 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.
|
March 06, 2009 Re: Reuse of variables referencing const objects | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sergey Kovrov | 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 |
March 06, 2009 Re: Reuse of variables referencing const objects | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sergey Kovrov | 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 |
March 07, 2009 Re: Reuse of variables referencing const objects | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 3/6/2009 11:29 PM, Steven Schveighoffer wrote:
> std.typecons.Rebindable
>
> http://www.digitalmars.com/d/2.0/phobos/std_typecons.html#Rebindable
Thanks Steve,
this is what I've been looking for, the only thing missing is comparing against null (is null).
-- serg.
|
March 09, 2009 Re: Reuse of variables referencing const objects | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sergey Kovrov | Sergey Kovrov wrote:
> On 3/6/2009 11:29 PM, Steven Schveighoffer wrote:
>> std.typecons.Rebindable
>>
>> http://www.digitalmars.com/d/2.0/phobos/std_typecons.html#Rebindable
>
> Thanks Steve,
>
> this is what I've been looking for, the only thing missing is comparing against null (is null).
>
>
> -- serg.
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-Sauls
|
March 09, 2009 Re: Reuse of variables referencing const objects | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Nicholson-Sauls | 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.
|
March 10, 2009 Re: Reuse of variables referencing const objects | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sergey Kovrov | Sergey Kovrov wrote: > 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? 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. > 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 |
Copyright © 1999-2021 by the D Language Foundation