Thread overview
IFTI reflection would be nice
Jul 26
Avrina
Jul 26
Avrina
Jul 28
user1234
Jul 30
Manu
July 26
Another useful thing to have would be "given this argument set to a function, give me the function that would be called".

This would do implicit function template instantiation and overload resolution, but yield the function instead of the return value.

Imagine:

void foo(int a) {}
void foo(string b) {}


I want to get the address of foo(string). How do you do that right now? Well, you have to loop over overloads and check the types. What a pain, but at least doable.

But wouldn't it be cool if you could do

&__functionOf(foo("foo"))

Where the __functionOf is the magic.


So far, this is kinda just a convenience, but now imagine the case of a template. Even if template reflection worked, you'd need to figure out the template arguments and that can be basically impossible given the conversions and specializations.

Then

&__functionOf(writeln("bar"))

for example would give a void function(string). There you can do `&writeln!string`


And in cases more complex than that, the compiler's logic need not be reimplemented in user cde.
July 26
On Sunday, 26 July 2020 at 13:20:40 UTC, Adam D. Ruppe wrote:
> Imagine:
>
> void foo(int a) {}
> void foo(string b) {}
>
>
> I want to get the address of foo(string). How do you do that right now? Well, you have to loop over overloads and check the types. What a pain, but at least doable.
>
> But wouldn't it be cool if you could do
>
> &__functionOf(foo("foo"))
>
> Where the __functionOf is the magic.

You can just use cast() right now to get the overload you want.

https://run.dlang.io/is/n76kt3

import std.stdio;

void foo(string) { writeln("foo(string)"); }
void foo(int)    { writeln("foo(int)"); }

void main() {
    auto a = cast(void function(string))&foo;
    auto b = cast(void function(int))&foo;
    a("");
    b(10);
}
July 26
On Sunday, 26 July 2020 at 14:03:31 UTC, Avrina wrote:
> You can just use cast() right now to get the overload you want.

Wow, I actually did not know that.

But, cast is always bleh - try `auto a = cast(void function(float))&foo;`... then it calls the string one in both cases, yikes...


I can't remember the example that got me thinking about this a couple weeks ago, but it was a template that could *only* be used with IFTI. That's my main concern, but overload selection without the pitfalls of cast would be a very nice bonus too.
July 26
On 7/26/20 12:36 PM, Adam D. Ruppe wrote:
> On Sunday, 26 July 2020 at 14:03:31 UTC, Avrina wrote:
>> You can just use cast() right now to get the overload you want.
> 
> Wow, I actually did not know that.
> 
> But, cast is always bleh - try `auto a = cast(void function(float))&foo;`... then it calls the string one in both cases, yikes...
> 
> 
> I can't remember the example that got me thinking about this a couple weeks ago, but it was a template that could *only* be used with IFTI. That's my main concern, but overload selection without the pitfalls of cast would be a very nice bonus too.

Maybe my query here? This would solve my issue.

https://forum.dlang.org/post/rd0d29$8bj$1@digitalmars.com

-Steve
July 26
On Sunday, 26 July 2020 at 16:36:43 UTC, Adam D. Ruppe wrote:
> On Sunday, 26 July 2020 at 14:03:31 UTC, Avrina wrote:
>> You can just use cast() right now to get the overload you want.
>
> Wow, I actually did not know that.
>
> But, cast is always bleh - try `auto a = cast(void function(float))&foo;`... then it calls the string one in both cases, yikes...
>
>
> I can't remember the example that got me thinking about this a couple weeks ago, but it was a template that could *only* be used with IFTI. That's my main concern, but overload selection without the pitfalls of cast would be a very nice bonus too.

That should probably be an error, there's no reason that should work at all. It can't select one based on the type, it shouldn't select any, and it looks like it just selects the first one.

You can do this which is more type safe, but again, it should an ambiguous error. There's no reason it should be picking string over int.

import std.stdio;

void foo(string) { writeln("foo(string)"); }
void foo(int)    { writeln("foo(int)"); }

void main() {
	void function(float) a = &foo;
}

Error: cannot implicitly convert expression & foo of type void function(string _param_0) to void function(float)
July 26
On Sunday, 26 July 2020 at 17:30:40 UTC, Avrina wrote:
> On Sunday, 26 July 2020 at 16:36:43 UTC, Adam D. Ruppe wrote:
>> [...]
>
> That should probably be an error, there's no reason that should work at all. It can't select one based on the type, it shouldn't select any, and it looks like it just selects the first one.
>
> You can do this which is more type safe, but again, it should an ambiguous error. There's no reason it should be picking string over int.
>
> import std.stdio;
>
> void foo(string) { writeln("foo(string)"); }
> void foo(int)    { writeln("foo(int)"); }
>
> void main() {
> 	void function(float) a = &foo;
> }
>
> Error: cannot implicitly convert expression & foo of type void function(string _param_0) to void function(float)

The reason is the other of definition.
But the int overload first and the error should go away.
July 26
On Sunday, 26 July 2020 at 13:20:40 UTC, Adam D. Ruppe wrote:
> Another useful thing to have would be "given this argument set to a function, give me the function that would be called".
>
> This would do implicit function template instantiation and overload resolution, but yield the function instead of the return value.
>
> Imagine:
>
> void foo(int a) {}
> void foo(string b) {}
>
>
> I want to get the address of foo(string). How do you do that right now? Well, you have to loop over overloads and check the types. What a pain, but at least doable.
>
> But wouldn't it be cool if you could do
>
> &__functionOf(foo("foo"))
>
> Where the __functionOf is the magic.
>
>
> So far, this is kinda just a convenience, but now imagine the case of a template. Even if template reflection worked, you'd need to figure out the template arguments and that can be basically impossible given the conversions and specializations.
>
> Then
>
> &__functionOf(writeln("bar"))
>
> for example would give a void function(string). There you can do `&writeln!string`
>
>
> And in cases more complex than that, the compiler's logic need not be reimplemented in user cde.

Or make an alias, rather than a function pointer. That would be more useful.
July 26
On Sunday, 26 July 2020 at 19:08:01 UTC, Jean-Louis Leroy wrote:
> Or make an alias, rather than a function pointer. That would be more useful.

yeah my __functionOf would be an alias, then you can & it to get the function pointer.
July 28
On Sunday, 26 July 2020 at 14:03:31 UTC, Avrina wrote:
> On Sunday, 26 July 2020 at 13:20:40 UTC, Adam D. Ruppe wrote:
>> Imagine:
>>
>> void foo(int a) {}
>> void foo(string b) {}
>>
>>
>> I want to get the address of foo(string). How do you do that right now? Well, you have to loop over overloads and check the types. What a pain, but at least doable.
>>
>> But wouldn't it be cool if you could do
>>
>> &__functionOf(foo("foo"))
>>
>> Where the __functionOf is the magic.
>
> You can just use cast() right now to get the overload you want.
>
> https://run.dlang.io/is/n76kt3
>
> import std.stdio;
>
> void foo(string) { writeln("foo(string)"); }
> void foo(int)    { writeln("foo(int)"); }
>
> void main() {
>     auto a = cast(void function(string))&foo;
>     auto b = cast(void function(int))&foo;
>     a("");
>     b(10);
> }

OMG  excellent, where have you learnt this ancient secret of the gods ?
July 30
On Sun, Jul 26, 2020 at 11:25 PM Adam D. Ruppe via Digitalmars-d < digitalmars-d@puremagic.com> wrote:

> Another useful thing to have would be "given this argument set to a function, give me the function that would be called".
>
> This would do implicit function template instantiation and overload resolution, but yield the function instead of the return value.
>
> Imagine:
>
> void foo(int a) {}
> void foo(string b) {}
>
>
> I want to get the address of foo(string). How do you do that right now? Well, you have to loop over overloads and check the types. What a pain, but at least doable.
>
> But wouldn't it be cool if you could do
>
> &__functionOf(foo("foo"))
>
> Where the __functionOf is the magic.
>
>
> So far, this is kinda just a convenience, but now imagine the case of a template. Even if template reflection worked, you'd need to figure out the template arguments and that can be basically impossible given the conversions and specializations.
>
> Then
>
> &__functionOf(writeln("bar"))
>
> for example would give a void function(string). There you can do
> `&writeln!string`
>
>
> And in cases more complex than that, the compiler's logic need not be reimplemented in user cde.
>

Write a DIP! This is a very real reflection hole that I've struggled with
before too.
Trying to sample all the possibilities, and then mirror the complex logic
that the compiler uses to select a function to call internally is not a
problem that should exist in user-space, and the compiler rules are subject
to change making maintenance tricky and extremely brittle.

I'd suggest it might just be a __traits though, rather than introducing a new magic thing.