How to partially apply member functions?

Balagopal Komarath via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Jul 1 02:37:26 PDT 2017


On Friday, 30 June 2017 at 08:43:32 UTC, ct wrote:
> It compiled when I wrote:
>
> auto on_next_previous = &this.OnNextPreviousMatch;
> entry_.addOnNextMatch(&partial!(on_next_previous, true));
> entry_.addOnPreviousMatch(&partial!(on_next_previous, false));
>
> But not when I wrote:
>
> entry_.addOnNextMatch(partial!(&this.OnNextPreviousMatch, 
> true));
>
> Or
>
> entry_.addOnNextMatch(partial!(&Editor.OnNextPreviousMatch, 
> true));
>
> Error: value of 'this' is not known at compile time

In the first snippet, you are passing the local variable 
on_next_previous by alias to the template and not the function 
&this.OnNextPreviousMatch. AFAIK, when the partial function is 
invoked at a later point of time, it will use the value of the 
variable at the invocation time and not the value of the variable 
at the time of the invocation of partial! template. The following 
snippet should clarify this.

import std.stdio;
import std.traits;

template partial(alias f, alias arg1, T = Parameters!f[1])
{
     auto g(T arg2)
     {
         return f(arg1, arg2);
     }
     enum partial = &g;
}

int foo(int x, int y)
{
     writeln("foo");
     return x + y;
}

struct bar
{
     int id;
     int baz(int x, int y)
     {
         writeln("bar.baz", id);
         return x + y;
     }
}

void main()
{
     auto foo2 = partial!(foo, 2);
     writeln(foo2(3));

     auto b = bar(0);
     auto bbaz = &b.baz;
     auto bar2 = partial!(bbaz, 2);
     writeln(bar2(3)); // bar.baz0 5
     auto c = bar(1);
     bbaz = &c.baz;
     writeln(bar2(3)); // bar.baz1 5
}

One might think that in the above code, bar2 is set to the 
partial function b.baz(2, *). But, it is clear that that is not 
the case. There is no partially applied function here. When bar2 
is invoked, it invokes the function in the variable bbaz with the 
argument given at the time of the template invocation and the 
argument given during function invocation.

The snippet

> partial!(&this.OnNextPreviousMatch, true)

doesn't work because templates cannot accept runtime values as 
arguments since they work at compile time. The only things that 
are available at compile time are symbols and literal values.

Hope this makes sense.


More information about the Digitalmars-d-learn mailing list