On Friday, 3 June 2016 at 15:14:59 UTC, Timon Gehr wrote:
https://github.com/dlang/dmd/pull/3361
...
Interesting. Not sure about this. It seems it should work by
analogy with this:
struct Test{
int x=2;
int foo(){ return x; }
int call(alias a)(){ return a(); }
pragma(msg,Test().call!foo);
}
So I have implemented it. :)
https://github.com/tgehr/d-compiler/commit/ea7cdcc43dce8fd05b64b872e83ac28905b81dff
Hah, very cool :)
However, there are some funny cases:
struct A{
int x;
this(int x){ this.x=x; }
int fun(){ return x;}
int[] caller(T)(T t){
int[] r;
r~=T.fun();
r~=(x++,t).fun();
return r;
}
}
struct B{
alias fun = A.fun;
}
pragma(msg, A(2).caller(B())); // [2,3]
pragma(msg, A(2).caller(A(10))); // [2,10]
I.e. this code exhibits 'special' behaviour when the passed
type is A.
Maybe when I don't follow your argument, but it acts exactly as
before when the passed type is A. It also acts as before when you
pass some other type with a regular old fun() method (i.e. when
fun is static or the T.fun call is removed). It acts differently
only when fun is an alias to a method in A, which otherwise
wouldn't have compiled. Either way, this piggy-backs on that
T.fun() works when fun is not static, which I think would not
have been necessary had we had a nice syntax for __traits(child)
(with the one I proposed it would be `this.(T.fun)();`).
Anyway, I don't feel too strongly about this one.
It must work by default, otherwise libraries can accidentally
not support it. I think it should just be inferred. I.e. if the
template instance needs access to the context, that requirement
is propagated to the caller, otherwise it isn't. The arguments
that Kenji raises against it seem to be DMD-specific, no?
I must admit that I don't fully understand Kenji's explanation
either.
I share it. The main limitation that needs fixing is capture of
multiple contexts. Unfortunately I have not gotten around to
implementing multiple contexts and context inference myself so
far.
Yeah, multiple contexts would be the crown jewel. I've been told,
though, that the idea that things can have at most one context
pointer is very deeply rooted into DMD. I think Walter Bright is
also not a fan of the idea, if I understand correctly his main
counter-argument is that for untemplated function pointers, when
it has 0 contexts it's just a function pointer, when it has 1
context it's a delegate, when it has 2 or more contexts, it's
something else, what is it - how would you describe its type in
language syntax?