On 03.06.2016 18:36, Vladimir Panteleev wrote:
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 :)
...
There's also this commit:
https://github.com/tgehr/d-compiler/commit/dc34b0b2529300a05fc00c0fc54d006bc96aa790
I noticed during your nice talk at DConf that I lacked support for lazy
void parameters. This was fixed before the end of the talk. :)
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. ...
You are right, the behavior in question is not actually newly
introduced. It's probably fine.
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.
...
Well, one argument seems to be that it is clearly possible to create
somewhat weird situations if both inference and introspection happen at
the same time. I handle all forward reference issues in an unified
manner and therefore shouldn't run into major problems there.
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?
It should still be a delegate. One context pointer suffices to address
an arbitrary amount of data. We can just put a void*[n] with all
remaining contexts inside the stack frame context.