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


Reply via email to