Jump to page: 1 2
Thread overview
Figuring out the returntype opDipatch
Nov 02, 2013
TheFlyingFiddle
Nov 03, 2013
Ali Çehreli
Nov 03, 2013
TheFlyingFiddle
Nov 03, 2013
Jacob Carlborg
Nov 14, 2013
TheFlyingFiddle
Nov 14, 2013
TheFlyingFiddle
Nov 14, 2013
TheFlyingFiddle
Nov 15, 2013
Jacob Carlborg
Nov 15, 2013
Jacob Carlborg
Nov 03, 2013
Ali Çehreli
Nov 03, 2013
TheFlyingFiddle
November 02, 2013
I'm currently working on a IReflectionable interface

Currently the usage is as follows

class Foo : IReflectionable
{
  mixin ReflectionImpl;

  void bar(int a) { /* do something */ }
  int baz(string a) { return a.length; }

}

unittest
{
   IReflectionable foo = new Foo();

   alias void delegate(int) bar_t;

   auto bar = foo.funcPtr!(bar_t, "bar"); //Gets a delegate to foo.bar
   bar(1); //Calls foo.bar(1);

   alias int delegate(string) baz_t;
   auto baz = foo.funcPtr!(baz_t, "baz");
   int a = baz("Hello");
}

Now this works and is all well and good. However i would like to improve on the
syntax a bit.

This is how i would like to call the code.

unittest
{
  IReflectionable foo = new FooService();

  foo.bar(1); //Now this becomes foo.opDispatch!("bar", int)(1);

  int a = foo.baz("Hello"); //This does NOT work. Cannot figure out returntype
}

The problem i am faced with is that i need a way to figure out the return value of opDispatch by the invokation call.

all the information i need is here

int a = foo.baz("hello");

This gives returntype int.

So is there a way to gain this information in opDspatch? Is it possible to do something like this?

auto a = foo.baz!(int)("hello");







November 03, 2013
On 11/02/2013 03:41 PM, TheFlyingFiddle wrote:
> I'm currently working on a IReflectionable interface
>
> Currently the usage is as follows
>
> class Foo : IReflectionable
> {
>    mixin ReflectionImpl;
>
>    void bar(int a) { /* do something */ }
>    int baz(string a) { return a.length; }
>
> }
>
> unittest
> {
>     IReflectionable foo = new Foo();
>
>     alias void delegate(int) bar_t;
>
>     auto bar = foo.funcPtr!(bar_t, "bar"); //Gets a delegate to foo.bar
>     bar(1); //Calls foo.bar(1);
>
>     alias int delegate(string) baz_t;
>     auto baz = foo.funcPtr!(baz_t, "baz");
>     int a = baz("Hello");
> }
>
> Now this works and is all well and good. However i would like to improve
> on the
> syntax a bit.
>
> This is how i would like to call the code.
>
> unittest
> {
>    IReflectionable foo = new FooService();
>
>    foo.bar(1); //Now this becomes foo.opDispatch!("bar", int)(1);
>
>    int a = foo.baz("Hello"); //This does NOT work. Cannot figure out
> returntype
> }
>
> The problem i am faced with is that i need a way to figure out the
> return value of opDispatch by the invokation call.
>
> all the information i need is here
>
> int a = foo.baz("hello");
>
> This gives returntype int.
>
> So is there a way to gain this information in opDspatch? Is it possible
> to do something like this?
>
> auto a = foo.baz!(int)("hello");
>
>
>

Can you provide a little more complete code please. Otherwise, the return type is available to typeof:

import std.stdio;

struct S
{
    auto opDispatch(string name, T...)(T parameters)
    {
        writef("S.%s:", name);
        foreach (parameter; parameters) {
            writef(" %s", parameter);
        }
        writeln();

        return parameters[$/2];
    }
}

void main()
{
    auto s = S();

    auto r0 = s.foo(42, 1.5, "hi");
    auto r1 = s.bar("hello", 'a', 100);

    static assert (is (typeof(r0) == double));
    static assert (is (typeof(r1) == char));
}

Ali


November 03, 2013
> Can you provide a little more complete code please. Otherwise, the return type is available to typeof:
>
> import std.stdio;
>
> struct S
> {
>     auto opDispatch(string name, T...)(T parameters)
>     {
>         writef("S.%s:", name);
>         foreach (parameter; parameters) {
>             writef(" %s", parameter);
>         }
>         writeln();
>
>         return parameters[$/2];
>     }
> }
>
> void main()
> {
>     auto s = S();
>
>     auto r0 = s.foo(42, 1.5, "hi");
>     auto r1 = s.bar("hello", 'a', 100);
>
>     static assert (is (typeof(r0) == double));
>     static assert (is (typeof(r1) == char));
> }
>
> Ali

In the IReflectionable interface:

interface IReflectionable
{
    final P funcPtr(P)(string fun) if (is(P == delegate))
    {
        //Using mangeling for overloads and type safety
	auto ptr = delPtr_impl(mangle!P(fun));

	P del;
	del.ptr = cast(typeof(del.ptr))ptr[0];
	del.funcptr = cast(typeof(del.funcptr))ptr[1];
	return del;
    }

    final P funcPtr(P)(string fun) if (is(P == function))
    {
        //Using mangeling for overloads and type safety
	auto ptr = funcPtr_impl(mangle!(P)(fun));
	return cast(P)ptr;
    }

    final ?? opDispatch(string name, Params...)(Params params)
    {
       alias ?? delegate(Params) del_type;
       auto del = funcPtr!(del_type)(name);

       static if(?? == void)
          del(params);
       else
          return del(params);
    }

    protected Tuple!(void*, void*) delPtr_impl(string s);
    protected void* funcPtr_impl(string s);
}

What i'm interested in is determining what type ?? should be. Variant works but if possible i would like to avoid it. This would require me to know about the code at the invokation site. (So i'm guessing it might not be possible)
November 03, 2013
On 11/02/2013 03:41 PM, TheFlyingFiddle wrote:

> The problem i am faced with is that i need a way to figure out the
> return value of opDispatch by the invokation call.

If I now understand you correctly, what initially confused my was "invocation call." Because "invocation" makes me think about the actual arguments of the functino call.

> all the information i need is here
>
> int a = foo.baz("hello");
>
> This gives returntype int.

So, what you are trying to do is to get the return type from the left-hand side of the assignment operator.

> So is there a way to gain this information in opDspatch?

I don't think so. You can always return a special (similar to Variant that you mentioned) and play with automatic type conversions no that type.

> Is it possible to do something like this?
>
> auto a = foo.baz!(int)("hello");

Hmmm. I don't think so. "baz" itself becomes the first argument of opDispatch. So I tried the following ugly thing but it does not work either:

import std.stdio;

struct S
{
    R opDispatch(string name, R, T...)(T parameters)
    {
        return R.init;
    }
}

void main()
{
    auto s = S();

    auto r0 = s.foo!("foo", int)("hello");    // does not compile
    auto r1 = s.bar!("bar", double)(100);

    static assert (is (typeof(r0) == int));
    static assert (is (typeof(r1) == double));
}

Ali

November 03, 2013
> struct S
> {
>     R opDispatch(string name, R, T...)(T parameters)
>     {
>         return R.init;
>     }
> }
>
> void main()
> {
>     auto s = S();
>
>     auto r0 = s.foo!("foo", int)("hello");    // does not compile
>     auto r1 = s.bar!("bar", double)(100);
>
>     static assert (is (typeof(r0) == int));
>     static assert (is (typeof(r1) == double));
> }
>
> Ali

I decided to go with the following:
interface IReflectionable
{
    final void call(string name, Params...)(Params params)
    {
        //code for getting pointer.
    }

    final void call(Params...)(string name, Params params)
    {
        //code for getting pointer.
    }

    final R call(R, Params...)(string name, Params params)
    {
        //code for getting pointer.
        return R.init;
    }

    final R call(R, string method,  Params...)(Params params)
    {
        //code for getting pointer.
        return R.init;
    }
}

unittest
{
    auto foo = new Foo();

    string hello = "Hello";
    int a = 10;

    foo.call!("bar")(a); //Infers void return type and int parameter.
    auto r1 = foo.call!(int, "baz")(hello); //Return type is int and infers string parameter.

    foo.call("bar", a); //Infers void return type and int parameter.
    foo.call!(int)("baz", hello); //Return type is int and infers sting parameter.
}

Sadly i could not get opDispatch to work either :( Idealy i would like to have foo.baz!(int)(hello) working but i guess since it's a template the compiler is
unable to convert it into foo.opDispatch!("baz", int)(hello);

Thanks for all the help Ali.
November 03, 2013
On 2013-11-03 03:15, TheFlyingFiddle wrote:

> In the IReflectionable interface:
>
> interface IReflectionable
> {
>      final P funcPtr(P)(string fun) if (is(P == delegate))
>      {
>          //Using mangeling for overloads and type safety
>      auto ptr = delPtr_impl(mangle!P(fun));
>
>      P del;
>      del.ptr = cast(typeof(del.ptr))ptr[0];
>      del.funcptr = cast(typeof(del.funcptr))ptr[1];
>      return del;
>      }
>
>      final P funcPtr(P)(string fun) if (is(P == function))
>      {
>          //Using mangeling for overloads and type safety
>      auto ptr = funcPtr_impl(mangle!(P)(fun));
>      return cast(P)ptr;
>      }
>
>      final ?? opDispatch(string name, Params...)(Params params)
>      {
>         alias ?? delegate(Params) del_type;
>         auto del = funcPtr!(del_type)(name);
>
>         static if(?? == void)
>            del(params);
>         else
>            return del(params);
>      }
>
>      protected Tuple!(void*, void*) delPtr_impl(string s);
>      protected void* funcPtr_impl(string s);
> }
>
> What i'm interested in is determining what type ?? should be. Variant
> works but if possible i would like to avoid it. This would require me to
> know about the code at the invokation site. (So i'm guessing it might
> not be possible)

I have the same problem as well. I haven't figured out the best way to solve this yet.

-- 
/Jacob Carlborg
November 14, 2013
On Sunday, 3 November 2013 at 10:48:45 UTC, Jacob Carlborg wrote:
> On 2013-11-03 03:15, TheFlyingFiddle wrote:
>
>> In the IReflectionable interface:
>>
>> interface IReflectionable
>> {
>>     final P funcPtr(P)(string fun) if (is(P == delegate))
>>     {
>>         //Using mangeling for overloads and type safety
>>     auto ptr = delPtr_impl(mangle!P(fun));
>>
>>     P del;
>>     del.ptr = cast(typeof(del.ptr))ptr[0];
>>     del.funcptr = cast(typeof(del.funcptr))ptr[1];
>>     return del;
>>     }
>>
>>     final P funcPtr(P)(string fun) if (is(P == function))
>>     {
>>         //Using mangeling for overloads and type safety
>>     auto ptr = funcPtr_impl(mangle!(P)(fun));
>>     return cast(P)ptr;
>>     }
>>
>>     final ?? opDispatch(string name, Params...)(Params params)
>>     {
>>        alias ?? delegate(Params) del_type;
>>        auto del = funcPtr!(del_type)(name);
>>
>>        static if(?? == void)
>>           del(params);
>>        else
>>           return del(params);
>>     }
>>
>>     protected Tuple!(void*, void*) delPtr_impl(string s);
>>     protected void* funcPtr_impl(string s);
>> }
>>
>> What i'm interested in is determining what type ?? should be. Variant
>> works but if possible i would like to avoid it. This would require me to
>> know about the code at the invokation site. (So i'm guessing it might
>> not be possible)
>
> I have the same problem as well. I haven't figured out the best way to solve this yet.

Might this be something you could solve using the DIP50 AST macros?

Something like


interface IRefectionable
{
   //I'm assuming you can use a macro as opDispatch
   macro opDispatch(string s, Params...)(Context context, Ast!(Params) ast)
   {
       //The name is sort of bad
       enum returnType = context.?? //Look at the stuff in the context to figure out what the returnType would be.

       return <|
   alias ?? delegate(Params) del_type;
       auto del = funcPtr!(del_type)(name);

       static if(?? == void)
          del(params);
       else
          return del(params);
   }
}

unittest
{
   IReflectionable refl = new Foo();

   refl.bar(1); //void is infered since not setting any value.
   int baz = refl.baz("Hello");
   auto baz2 = refl.baz("hello"); //Can't work.

}


November 14, 2013
On Thursday, 14 November 2013 at 20:39:35 UTC, TheFlyingFiddle wrote:
> On Sunday, 3 November 2013 at 10:48:45 UTC, Jacob Carlborg wrote:
>> On 2013-11-03 03:15, TheFlyingFiddle wrote:
>>
>>> In the IReflectionable interface:
>>>
>>> interface IReflectionable
>>> {
>>>    final P funcPtr(P)(string fun) if (is(P == delegate))
>>>    {
>>>        //Using mangeling for overloads and type safety
>>>    auto ptr = delPtr_impl(mangle!P(fun));
>>>
>>>    P del;
>>>    del.ptr = cast(typeof(del.ptr))ptr[0];
>>>    del.funcptr = cast(typeof(del.funcptr))ptr[1];
>>>    return del;
>>>    }
>>>
>>>    final P funcPtr(P)(string fun) if (is(P == function))
>>>    {
>>>        //Using mangeling for overloads and type safety
>>>    auto ptr = funcPtr_impl(mangle!(P)(fun));
>>>    return cast(P)ptr;
>>>    }
>>>
>>>    final ?? opDispatch(string name, Params...)(Params params)
>>>    {
>>>       alias ?? delegate(Params) del_type;
>>>       auto del = funcPtr!(del_type)(name);
>>>
>>>       static if(?? == void)
>>>          del(params);
>>>       else
>>>          return del(params);
>>>    }
>>>
>>>    protected Tuple!(void*, void*) delPtr_impl(string s);
>>>    protected void* funcPtr_impl(string s);
>>> }
>>>
>>> What i'm interested in is determining what type ?? should be. Variant
>>> works but if possible i would like to avoid it. This would require me to
>>> know about the code at the invokation site. (So i'm guessing it might
>>> not be possible)
>>
>> I have the same problem as well. I haven't figured out the best way to solve this yet.
>
> Might this be something you could solve using the DIP50 AST macros?
>
> Something like
>
>
> interface IRefectionable
> {
>    //I'm assuming you can use a macro as opDispatch
>    macro opDispatch(string s, Params...)(Context context, Ast!(Params) ast)
>    {
>        //The name is sort of bad
>        enum returnType = context.?? //Look at the stuff in the context to figure out what the returnType would be.
>
>        return <|
>    alias ?? delegate(Params) del_type;
>        auto del = funcPtr!(del_type)(name);
>
>        static if(?? == void)
>           del(params);
>        else
>           return del(params);
>    }
> }
>
> unittest
> {
>    IReflectionable refl = new Foo();
>
>    refl.bar(1); //void is infered since not setting any value.
>    int baz = refl.baz("Hello");
>    auto baz2 = refl.baz("hello"); //Can't work.
>
> }

Edit: ?? should be replaced with $returnType

November 14, 2013
After looking at the DIP some more i can see that my suggestion implementation does not make any sense (and i missed some of the syntax). If it can be done with AST's i don't have a sugestion for it.
November 15, 2013
On 2013-11-14 21:39, TheFlyingFiddle wrote:

> Might this be something you could solve using the DIP50 AST macros?

Possibly, if the context parameter provides enough information about where the macro is used.

-- 
/Jacob Carlborg
« First   ‹ Prev
1 2