Getting the const-correctness of Object sorted once and for all
era scarecrow
rtcvb32 at yahoo.com
Wed May 23 13:43:51 PDT 2012
On Tuesday, 15 May 2012 at 21:18:11 UTC, Chad J wrote:
> On 05/15/2012 03:32 PM, Chris Cain wrote:
>> On Tuesday, 15 May 2012 at 18:07:12 UTC, Chad J wrote:
>>> An idea I thought of is to introduce a method local
>>> declaration that
>>> allows a method to access instance-specific-state that isn't
>>> accessible to the rest of the class:
>>
>> This is an interesting idea (as it seems to really try to keep
>> the state changes internal to the function, which can be seen
>> as
>> how D handles purity)... however, it breaks the point of
>> purity due to
>> this:
>>
>> pure nothrow hash_t toHash() const {
>> @instance hash_t bad = 0;
>> ++bad;
>> return hashfn(field) + bad;
>> }
>>
>> Now it violates everyone's definition of purity and we can no
>> longer make our sweet optimizations and reasoning about the
>> code.
>> Sure, we could "trust the programmers to not do this" ... but
>> that's another debate entirely.
>
>
> Yes. I intend to "trust the programmers to not do this".
>
> Otherwise we need to find some way to ensure that a function
> that alters external state will always return the same value as
> long as the rest of the program doesn't change the state it
> looks at.
>
>>
>> ... and setting toStringCacheValid to true in toString violates
>> const, so this is absolutely not allowed. Sorry.
>>
>
> Yep, ya got me.
>
>>
>> Maybe there's a solution, but I doubt the solution is something
>> the programmer can/should do completely transparently.
I think I have an answer. It came to me last night when I was
going to sleep. Anyways, it may be a little verbose but I Hope I
got it all right. Oddly enough it stays within D's own rules :)
--
import std.stdio;
import std.conv;
struct CachedHash(T) {
T element;
uint hash;
alias element this;
this(T inVal) {
element = inVal;
}
@property uint toHash(){
if(!hash) {
writeln("Hashing!");
hash = element.toHash();
} else
writeln("From Cache!");
return hash;
}
}
uint toHash(string x){
return 123456; //for example
}
class AString {
string str;
this(string s) {
str = s;
}
const uint toHash(){
return 123456;
}
}
uint calledHash(T)(T as){
return as.toHash();
}
int main() {
immutable char[] s = "this is a test!";
auto ch_s = CachedHash!string(s); //since s is inherently
immutable..
writeln(s);
writeln(s.toHash, "\n");
writeln(ch_s);
writeln(ch_s.toHash);
writeln(ch_s.toHash, "\n");
AString as = new AString(s);
immutable AString ias = cast(immutable AString) new AString(s);
auto as_s = CachedHash!AString(as);
auto ias_s = CachedHash!(immutable AString)(ias);
writeln(as.toHash, "\n");
writeln(as_s.toHash);
writeln(as_s.toHash);
writeln(ias_s.toHash);
writeln(ias_s.toHash, "\n");
writeln(calledHash!AString(as_s)); //non-CachedHash aware
simulate
writeln(calledHash!(typeof(as_s))(as_s));
return 0;
}
More information about the Digitalmars-d
mailing list