June 04, 2007 Re: lazy evaluation | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Manfred Nowak |
I'm not sure how you'd account for lazy arguments, but it should be possible to abstract memorisation of function results. Warning: untested and likely non-compiling code follows, but it should at least be in the right ballpark :)
--Daniel
--
template memoImpl(alias fn)
{
alias typeof(&fn) fnT;
private ReturnType!(fnT)[Tuple!(ParameterTypeTuple!(fnT))] results;
ReturnType!(fnT) memo(ParameterTypeTuple!(fnT) args)
{
auto targs = tuple(args);
if( !(targs in results) )
results[targs] = fn(args);
return results[targs];
}
}
template memo(alias fn)
{
alias memoImpl!(fn).memo memo;
}
class Foo
{
int _foo(char[] bar)
{
// ... some complex calculation ...
}
alias memo!(_foo) foo;
}
| |||
June 04, 2007 Re: lazy evaluation | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Daniel Keep |
Ok; this time, the example does actually work. Sadly, it doesn't work if you try to memorise a member function; not sure how to work around that as of yet.
-- Daniel
--
module memo;
import std.traits;
struct STuple(T...)
{
alias T Type;
alias STuple!(T) thisT;
T values;
int opEquals(thisT rhs)
{
foreach( i,v ; values )
if( v != rhs.values[i] )
return false;
return true;
}
int opCmp(thisT rhs)
{
foreach( i,v ; values )
{
if( v == rhs.values[i] )
{}
else if( v < rhs.values[i] )
return -1;
else
return 1;
}
return 0;
}
hash_t toHash()
{
hash_t result;
foreach( v ; values )
result ^= typeid(typeof(v)).getHash(&v);
return result;
}
}
STuple!(T) stuple(T...)(T args)
{
STuple!(T) result;
foreach( i,arg ; args )
result.values[i] = arg;
return result;
}
template memoImpl(alias fn)
{
alias typeof(&fn) fnT;
private ReturnType!(fnT)[STuple!(ParameterTypeTuple!(fnT))] results;
ReturnType!(fnT) memo(ParameterTypeTuple!(fnT) args)
{
auto targs = stuple(args);
if( !(targs in results) )
{
results[targs] = fn(args);
}
return results[targs];
}
}
template memo(alias fn)
{
alias memoImpl!(fn).memo memo;
}
import std.stdio;
uint _foo(char[] bar)
{
writefln(`foo("%s") called!`, bar);
return bar.length;
}
alias memo!(_foo) foo;
void main()
{
writefln(`foo("abc") == %s`, foo("abc"));
writefln(`foo("fuzzy") == %s`, foo("fuzzy"));
writefln(`foo("abc") == %s`, foo("abc"));
writefln(`foo("fuzzy") == %s`, foo("fuzzy"));
writefln(`foo("Hello, World!") == %s`, foo("Hello, World!"));
writefln(`foo("Hello, World!") == %s`, foo("Hello, World!"));
}
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply