Thread overview
Get return type statically
Jun 28, 2016
"Smoke" Adams
Jun 28, 2016
"Smoke" Adams
Jun 28, 2016
"Smoke" Adams
Jun 28, 2016
Ali Çehreli
Jun 28, 2016
H. S. Teoh
Jun 29, 2016
H. S. Teoh
June 28, 2016
I have a type

public class SuperFunction(T)
{
  T t;
  return(T) Do() { return t(); }
}

where T is a delegate or function. First, I would like to be able to specify that this must be the case for SuperFunction so we can't pass non-function/delegates for T. Second, How to specify the return type of Do to match that of T.

e.g., SuperFunction!(bool function())

then return(T) should be bool.

Similarly, I would like to extra the T's parameters and make Do have them also.

This way, SuperFunction!T.Do emulates T in every way.


June 28, 2016
On Tuesday, 28 June 2016 at 01:41:03 UTC, "Smoke" Adams wrote:
> I have a type
>
> public class SuperFunction(T)
> {
>   T t;
>   return(T) Do() { return t(); }
> }
>
> where T is a delegate or function. First, I would like to be able to specify that this must be the case for SuperFunction so we can't pass non-function/delegates for T. Second, How to specify the return type of Do to match that of T.
>
> e.g., SuperFunction!(bool function())
>
> then return(T) should be bool.
>
> Similarly, I would like to extra the T's parameters and make Do have them also.
>
> This way, SuperFunction!T.Do emulates T in every way.

I should mention that I am looking to make this as type safe as possible as if Do was declared exactly like T manually.




June 28, 2016
I should point out also that this should be inheritable.

Eventually I would like to create an algebra of SuperFunctions.

e.g., SF3 = SF1 + SF2

is a new super function that combines the parameter list of SF1 and SF2 and unionizes their return type. Both functions are called by Do(which will ultimately be handled by opCall).

Other operations on the parameters can be created(intersection or subtraction, multiplication, etc...).

I believe, to do this, I will have to create a string mixin that formulates Do(...) properly using a CTFE.







June 27, 2016
On 06/27/2016 06:41 PM, Smoke Adams wrote:
> I have a type
>
> public class SuperFunction(T)
> {
>    T t;
>    return(T) Do() { return t(); }
> }
>
> where T is a delegate or function. First, I would like to be able to
> specify that this must be the case for SuperFunction so we can't pass
> non-function/delegates for T. Second, How to specify the return type of
> Do to match that of T.
>
> e.g., SuperFunction!(bool function())
>
> then return(T) should be bool.

The simplest thing is to define the return type as 'auto'.

>
> Similarly, I would like to extra the T's parameters and make Do have
> them also.
>
> This way, SuperFunction!T.Do emulates T in every way.
>
>

std.traits is your friend. :)

import std.traits;

public class SuperFunction(alias func)
        if (isCallable!func) {
    auto Do(Parameters!func args) { return func(args); }
}

void main() {
    auto sf = new SuperFunction!((int i) => i * 2);
    assert(sf.Do(42) == 84);
}

Ali

June 27, 2016
On Tue, Jun 28, 2016 at 01:41:03AM +0000, Smoke Adams via Digitalmars-d-learn wrote:
> I have a type
> 
> public class SuperFunction(T)
> {
>   T t;
>   return(T) Do() { return t(); }
> }
> 
> where T is a delegate or function. First, I would like to be able to specify that this must be the case for SuperFunction so we can't pass non-function/delegates for T.

Try:

	class SuperFunction(T)
		if (is(T == function) || is(T == delegate))
	{
		...
	}


> Second, How to specify the return type of Do to match that of T.

Maybe this?

	import std.traits : ReturnType, Parameters;

	ReturnType!T Do(Parameters!T args) { return t(args); }


T

-- 
INTEL = Only half of "intelligence".
June 29, 2016
On Mon, Jun 27, 2016 at 08:13:21PM -0700, H. S. Teoh via Digitalmars-d-learn wrote:
> On Tue, Jun 28, 2016 at 01:41:03AM +0000, Smoke Adams via Digitalmars-d-learn wrote:
> > I have a type
> > 
> > public class SuperFunction(T)
> > {
> >   T t;
> >   return(T) Do() { return t(); }
> > }
> > 
> > where T is a delegate or function. First, I would like to be able to specify that this must be the case for SuperFunction so we can't pass non-function/delegates for T.
[...]
> Maybe this?
> 
> 	import std.traits : ReturnType, Parameters;
> 
> 	ReturnType!T Do(Parameters!T args) { return t(args); }
[...]

Actually, we can do even better by using opCall:

 	ReturnType!T opCall(Parameters!T args) { return t(args); }

Then you can call the object directly:

	auto sf = new SuperFunction!someFunc;
	auto ret = sf(x, y, z);


T

-- 
Кто везде - тот нигде.