memoize (is this a fix for overloading?)
Max Samukha
spambox at d-coding.com
Wed Jan 5 02:07:50 PST 2011
On 01/05/2011 11:21 AM, Lars T. Kyllingstad wrote:
> On Tue, 04 Jan 2011 17:06:45 -0600, Andrei Alexandrescu wrote:
>
>> On 1/4/11 4:49 PM, %u wrote:
>>>> There's still the risk of keeping multiple hashes. Consider:
>>>
>>>> ulong fun(ulong n) { ... }
>>>> alias memoize!fun mfun;
>>>
>>>> mfun(5); // creates hash ulong[int]
>>>> mfun(5u); // creates hash ulong[uint] mfun('5'); // creates hash
>>>> ulong[char]
>>>
>>>
>>> Ohhh I see... so you're basically looking for a compile-time version of
>>> overload resolution, right? Because things seem to be getting
>>> complicated very quickly.
>>
>> It's not that complicated; we'll be able to achieve it somehow.
>> Overloads are compile-time entities so they should be easily
>> inspectable.
>
> Since this is likely to be useful in other cases as well, maybe it would
> be better to make a general template that selects an overload? So you'd
> use it like this:
>
> alias memoize!(selectOverload!(sqrt, double)) msqrt;
>
> A first step towards this would be to make __traits(getOverloads) work
> with module-level functions. Currently it only works for member
> functions. Also it would probably be better if it accepted a function
> alias instead of a string containing the function name.
__traits(getOverloads) does work with module level functions if you pass
a module alias to it. I predict you guys will soon need (and I am happy
you are approaching this way-point) a means to get from a symbol to its
parent, that is __traits(parent, symbol).
So there are two ways to solve the problem:
1. Add a version of __traits(getOverloads) that would not require a
parent as you suggested.
2. Add __traits(parent), so one could do:
void foo();
void foo(int);
alias __traits(getOverloads, __traits(parent, foo), "foo") fooOverloads;
I prefer the second or both, because the parent trait is needed in other
scenarios.
>
> Anyway, I've been able to make the following work for selecting overloads
> of member functions:
>
>
> import std.traits, std.stdio;
>
> struct S
> {
> void foo(int i, double d) { writeln("Overload 1"); }
> void foo(double d, int i) { writeln("Overload 2"); }
>
> void test()
> {
> alias selectOverload!(S, "foo", int, double) bar;
> bar(1, 3.0); // Prints "Overload 1"
>
> alias selectOverload!(S, "foo", double, int) baz;
> baz(4.0, 2); // Prints "Overload 2"
> }
> }
>
> void main()
> {
> S s;
> s.test();
> }
>
>
>
> template selectOverload(T, string fun, Params...)
> {
> alias selectOverloadImpl!(Params.length, Params,
> __traits(getOverloads, T, fun)) selectOverload;
> }
>
>
> template selectOverloadImpl(size_t lenP, A...)
> {
> static assert (A.length> lenP, "No overload matches");
> static if (equalTuples!(lenP,
> A[0 .. lenP],
> ParameterTypeTuple!(A[lenP])))
> {
> alias A[lenP] selectOverloadImpl;
> }
> else
> {
> alias selectOverloadImpl!(lenP, A[0 .. lenP], A[lenP+1 .. $])
> selectOverloadImpl;
> }
> }
>
>
> template equalTuples(size_t len, T...)
> {
> static if (len == 0&& T.length == 0)
> enum equalTuples = true;
> else static if (T.length != len*2)
> enum equalTuples = false;
> else static if (!is (T[0] == T[len]))
> enum equalTuples = false;
> else
> enum equalTuples =
> equalTuples!(len-1, T[1 .. len], T[len+1 .. $]);
> }
More information about the Digitalmars-d
mailing list