digitalmars.D.learn - How to declare function with the same call signature as another?
- Tofu Ninja (16/16) Nov 20 2016 I feel like this should be simple but I can't seem to figure it
- Nicholas Wilson (6/22) Nov 20 2016 import std.traits;
- Tofu Ninja (11/39) Nov 20 2016 This does not seem to account for return type attributes or
- Tofu Ninja (2/3) Nov 20 2016 Also does not include function linkage :/
- Tofu Ninja (17/20) Nov 23 2016 Because of the lack of response, I am going to guess there is no
- ketmar (2/4) Nov 23 2016 it is "type with modifier", like "const int" or "immutable int".
- Tofu Ninja (3/8) Nov 23 2016 Since when has ref been a type qualifier? It has always been a
- ketmar (3/13) Nov 23 2016 which is technically type qualifier. it just forbidden (in
- Tofu Ninja (9/24) Nov 23 2016 Maybe the compiler sees it as a type qualifier, but it is not
- ketmar (6/7) Nov 23 2016 you are unable to alias it, `ref` will be erased on aliasing. the
- Tofu Ninja (4/12) Nov 23 2016 Unless I can write "alias refint = ref int;", this should not be
- ketmar (5/20) Nov 23 2016 either this, or you won't be able to replicate function with it's
- Tofu Ninja (5/28) Nov 23 2016 You still can't replicate a function with this. No way to
- ketmar (2/3) Nov 23 2016 you can, by using std.traits and string mixins.
- Tofu Ninja (7/10) Nov 23 2016 Even with std.traits, you can't know which arguments are
- ketmar (5/7) Nov 23 2016 sure, you can. see
- Tofu Ninja (8/15) Nov 23 2016 Oh well that is my bad, for some reason I was under the
- ketmar (4/22) Nov 23 2016 here i agree. ;-) still, i can't think out a better way to do
- Nicholas Wilson (4/20) Nov 20 2016 Or if you want additional parameters.
I feel like this should be simple but I can't seem to figure it out. How do I declare a function to have the same call signature as another function/callable type? Like if I have: alias Sig = int function(int x, int y); How do I define a function such that it will have the same call signature as Sig? How do I take into account all the extra stuff that can go into a function signature like the argument attributes and the return type attributes etc.? Another way to phrase this question would be, how do I pass a function signature into a template and actually define functions with it? Related question, if I have Sig, how would I define DeltaSig to be exactly the same as Sig but with an extra parameter at the start or end of the parameter list? Thanks :)
Nov 20 2016
On Sunday, 20 November 2016 at 11:19:24 UTC, Tofu Ninja wrote:I feel like this should be simple but I can't seem to figure it out. How do I declare a function to have the same call signature as another function/callable type? Like if I have: alias Sig = int function(int x, int y); How do I define a function such that it will have the same call signature as Sig? How do I take into account all the extra stuff that can go into a function signature like the argument attributes and the return type attributes etc.? Another way to phrase this question would be, how do I pass a function signature into a template and actually define functions with it? Related question, if I have Sig, how would I define DeltaSig to be exactly the same as Sig but with an extra parameter at the start or end of the parameter list? Thanks :)import std.traits; ReturnType!Sig func(Parameters!Sig args) { //... }
Nov 20 2016
On Sunday, 20 November 2016 at 11:23:37 UTC, Nicholas Wilson wrote:On Sunday, 20 November 2016 at 11:19:24 UTC, Tofu Ninja wrote:This does not seem to account for return type attributes or function attributes. Eg: alias Sig = ref int function() nogc; ReturnType!Sig func(Parameters!Sig args) { // func is missing ref on return type and is not nogc static int g; return g; } How should I account for these things?I feel like this should be simple but I can't seem to figure it out. How do I declare a function to have the same call signature as another function/callable type? Like if I have: alias Sig = int function(int x, int y); How do I define a function such that it will have the same call signature as Sig? How do I take into account all the extra stuff that can go into a function signature like the argument attributes and the return type attributes etc.? Another way to phrase this question would be, how do I pass a function signature into a template and actually define functions with it? Related question, if I have Sig, how would I define DeltaSig to be exactly the same as Sig but with an extra parameter at the start or end of the parameter list? Thanks :)import std.traits; ReturnType!Sig func(Parameters!Sig args) { //... }
Nov 20 2016
On Sunday, 20 November 2016 at 11:52:01 UTC, Tofu Ninja wrote:...Also does not include function linkage :/
Nov 20 2016
On Sunday, 20 November 2016 at 12:06:15 UTC, Tofu Ninja wrote:On Sunday, 20 November 2016 at 11:52:01 UTC, Tofu Ninja wrote:Because of the lack of response, I am going to guess there is no way to do this cleanly. Guess I am going to have to break out the trusty old mixin to get this working. Also wtf is this... how does this even make sense? template make_ref(T){ static if(is(void delegate(ref T) ftype == delegate) && is(ftype P == function)) alias make_ref = P; else static assert(false); } void main(){ import std.stdio; writeln(make_ref!int.stringof); // (ref int) } What is a (ref int)? A tuple with "ref int" as its only member? Since when is ref int a type?...Also does not include function linkage :/
Nov 23 2016
On Wednesday, 23 November 2016 at 22:14:25 UTC, Tofu Ninja wrote:What is a (ref int)? A tuple with "ref int" as its only member? Since when is ref int a type?it is "type with modifier", like "const int" or "immutable int".
Nov 23 2016
On Wednesday, 23 November 2016 at 22:19:28 UTC, ketmar wrote:On Wednesday, 23 November 2016 at 22:14:25 UTC, Tofu Ninja wrote:Since when has ref been a type qualifier? It has always been a parameter/function attribute.What is a (ref int)? A tuple with "ref int" as its only member? Since when is ref int a type?it is "type with modifier", like "const int" or "immutable int".
Nov 23 2016
On Wednesday, 23 November 2016 at 22:28:57 UTC, Tofu Ninja wrote:On Wednesday, 23 November 2016 at 22:19:28 UTC, ketmar wrote:which is technically type qualifier. it just forbidden (in grammar) to use it anywhere except arg declaration.On Wednesday, 23 November 2016 at 22:14:25 UTC, Tofu Ninja wrote:Since when has ref been a type qualifier? It has always been a parameter/function attribute.What is a (ref int)? A tuple with "ref int" as its only member? Since when is ref int a type?it is "type with modifier", like "const int" or "immutable int".
Nov 23 2016
On Wednesday, 23 November 2016 at 22:48:17 UTC, ketmar wrote:On Wednesday, 23 November 2016 at 22:28:57 UTC, Tofu Ninja wrote:Maybe the compiler sees it as a type qualifier, but it is not listed as a type qualifier and does not behave like a type qualifier in any sense. For example typeof will never return "ref int" but will return "const int", auto will never infer ref but can infer const, you can pass const(int) into a template but can never pass ref(int) into a template(even with that hack I posted before, the ref gets striped). Being able to get an alias to (ref int) seems like a bug.On Wednesday, 23 November 2016 at 22:19:28 UTC, ketmar wrote:which is technically type qualifier. it just forbidden (in grammar) to use it anywhere except arg declaration.On Wednesday, 23 November 2016 at 22:14:25 UTC, Tofu Ninja wrote:Since when has ref been a type qualifier? It has always been a parameter/function attribute.What is a (ref int)? A tuple with "ref int" as its only member? Since when is ref int a type?it is "type with modifier", like "const int" or "immutable int".
Nov 23 2016
On Wednesday, 23 November 2016 at 23:02:30 UTC, Tofu Ninja wrote:Being able to get an alias to (ref int) seems like a bug.you are unable to alias it, `ref` will be erased on aliasing. the only way to retain it is to have a tuple with it. that trick aliases *function* *argument* *tuple*, not a single type. yeah, `ref` is very special beast. but it is still type modifier. ;-)
Nov 23 2016
On Wednesday, 23 November 2016 at 23:21:53 UTC, ketmar wrote:On Wednesday, 23 November 2016 at 23:02:30 UTC, Tofu Ninja wrote:Unless I can write "alias refint = ref int;", this should not be a feature at all... how did anyone think this is a good idea. Seriously I used to love D but now it's just a mess of hacks...Being able to get an alias to (ref int) seems like a bug.you are unable to alias it, `ref` will be erased on aliasing. the only way to retain it is to have a tuple with it. that trick aliases *function* *argument* *tuple*, not a single type. yeah, `ref` is very special beast. but it is still type modifier. ;-)
Nov 23 2016
On Thursday, 24 November 2016 at 00:04:51 UTC, Tofu Ninja wrote:On Wednesday, 23 November 2016 at 23:21:53 UTC, ketmar wrote:either this, or you won't be able to replicate function with it's exact args; you won't be able to even check if some arg is ref. but not having `ref int` as a valid type declaration has it's reasons.On Wednesday, 23 November 2016 at 23:02:30 UTC, Tofu Ninja wrote:Unless I can write "alias refint = ref int;", this should not be a feature at all... how did anyone think this is a good idea. Seriously I used to love D but now it's just a mess of hacks...Being able to get an alias to (ref int) seems like a bug.you are unable to alias it, `ref` will be erased on aliasing. the only way to retain it is to have a tuple with it. that trick aliases *function* *argument* *tuple*, not a single type. yeah, `ref` is very special beast. but it is still type modifier. ;-)
Nov 23 2016
On Thursday, 24 November 2016 at 00:15:07 UTC, ketmar wrote:On Thursday, 24 November 2016 at 00:04:51 UTC, Tofu Ninja wrote:You still can't replicate a function with this. No way to replicate or even know if a parameter is variadic. No way to replicate the ref on the return. No way to replicate the linkage or attributes of the function. This is a hack that solves nothing.On Wednesday, 23 November 2016 at 23:21:53 UTC, ketmar wrote:either this, or you won't be able to replicate function with it's exact args; you won't be able to even check if some arg is ref. but not having `ref int` as a valid type declaration has it's reasons.On Wednesday, 23 November 2016 at 23:02:30 UTC, Tofu Ninja wrote:Unless I can write "alias refint = ref int;", this should not be a feature at all... how did anyone think this is a good idea. Seriously I used to love D but now it's just a mess of hacks...Being able to get an alias to (ref int) seems like a bug.you are unable to alias it, `ref` will be erased on aliasing. the only way to retain it is to have a tuple with it. that trick aliases *function* *argument* *tuple*, not a single type. yeah, `ref` is very special beast. but it is still type modifier. ;-)
Nov 23 2016
On Thursday, 24 November 2016 at 00:19:04 UTC, Tofu Ninja wrote:You still can't replicate a function with this.you can, by using std.traits and string mixins.
Nov 23 2016
On Thursday, 24 November 2016 at 00:36:54 UTC, ketmar wrote:On Thursday, 24 November 2016 at 00:19:04 UTC, Tofu Ninja wrote:Even with std.traits, you can't know which arguments are variadic. The only way to actually replicate a function is with string mixins and parsing the stringof of the function you want to replicate. This (ref int) thing does not help one bit and will only trick people into thinking they are properly replicating the call signature when they are not.You still can't replicate a function with this.you can, by using std.traits and string mixins.
Nov 23 2016
On Thursday, 24 November 2016 at 00:51:01 UTC, Tofu Ninja wrote:Even with std.traits, you can't know which arguments are variadic.sure, you can. see http://dpldocs.info/experimental-docs/std.traits.variadicFunctionStyle.html that will return variadic style. and the only argument that can be variadic is last. it is enough to reconstruct the signature.
Nov 23 2016
On Thursday, 24 November 2016 at 02:11:21 UTC, ketmar wrote:On Thursday, 24 November 2016 at 00:51:01 UTC, Tofu Ninja wrote:Oh well that is my bad, for some reason I was under the impression that there could be more than one typesafe variadic. Still I think the way all of this currently works is very misleading, certainly there is lots of code out there trying to replicate call signatures but are doing it wrong. Having Parameters!(fun) capture things like ref is only going to mislead people(like me!) into thinking it is enough.Even with std.traits, you can't know which arguments are variadic.sure, you can. see http://dpldocs.info/experimental-docs/std.traits.variadicFunctionStyle.html that will return variadic style. and the only argument that can be variadic is last. it is enough to reconstruct the signature.
Nov 23 2016
On Thursday, 24 November 2016 at 02:52:05 UTC, Tofu Ninja wrote:On Thursday, 24 November 2016 at 02:11:21 UTC, ketmar wrote:here i agree. ;-) still, i can't think out a better way to do that. if you have any solid (or at least semi-solid ;-) ideas, feel free to start a new thread, we love bikeshedding! ;-)On Thursday, 24 November 2016 at 00:51:01 UTC, Tofu Ninja wrote:Oh well that is my bad, for some reason I was under the impression that there could be more than one typesafe variadic. Still I think the way all of this currently works is very misleading, certainly there is lots of code out there trying to replicate call signatures but are doing it wrong. Having Parameters!(fun) capture things like ref is only going to mislead people(like me!) into thinking it is enough.Even with std.traits, you can't know which arguments are variadic.sure, you can. see http://dpldocs.info/experimental-docs/std.traits.variadicFunctionStyle.html that will return variadic style. and the only argument that can be variadic is last. it is enough to reconstruct the signature.
Nov 23 2016
On Sunday, 20 November 2016 at 11:19:24 UTC, Tofu Ninja wrote:I feel like this should be simple but I can't seem to figure it out. How do I declare a function to have the same call signature as another function/callable type? Like if I have: alias Sig = int function(int x, int y); How do I define a function such that it will have the same call signature as Sig? How do I take into account all the extra stuff that can go into a function signature like the argument attributes and the return type attributes etc.? Another way to phrase this question would be, how do I pass a function signature into a template and actually define functions with it? Related question, if I have Sig, how would I define DeltaSig to be exactly the same as Sig but with an extra parameter at the start or end of the parameter list? Thanks :)Or if you want additional parameters. ReturnType!Sig func(int paramBefore, Parameters!Sig args, int paramAfter) { ... }
Nov 20 2016