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;
}