Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
November 02, 2013 Figuring out the returntype opDipatch | ||||
---|---|---|---|---|
| ||||
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 Re: Figuring out the returntype opDipatch | ||||
---|---|---|---|---|
| ||||
Posted in reply to TheFlyingFiddle | 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 Re: Figuring out the returntype opDipatch | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | > 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 Re: Figuring out the returntype opDipatch | ||||
---|---|---|---|---|
| ||||
Posted in reply to TheFlyingFiddle | 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 Re: Figuring out the returntype opDipatch | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | > 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 Re: Figuring out the returntype opDipatch | ||||
---|---|---|---|---|
| ||||
Posted in reply to TheFlyingFiddle | 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 Re: Figuring out the returntype opDipatch | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | 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 Re: Figuring out the returntype opDipatch | ||||
---|---|---|---|---|
| ||||
Posted in reply to TheFlyingFiddle | 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 Re: Figuring out the returntype opDipatch | ||||
---|---|---|---|---|
| ||||
Posted in reply to TheFlyingFiddle | 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 Re: Figuring out the returntype opDipatch | ||||
---|---|---|---|---|
| ||||
Posted in reply to TheFlyingFiddle | 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 |
Copyright © 1999-2021 by the D Language Foundation