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