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