www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Using a macro for a function signature

reply pineapple <meapineapple gmail.com> writes:
If I have a common function signature I'm using throughout my 
code, and I feel like there should be a way to condense it using 
a macro. The intuitive method isn't working, but this seems like 
something D would be able to do. What've I got wrong in this 
example?



alias somelongsignature = int(in int x);

int examplefunc0(in int x){
     return x * 2;
}

somelongsignature testfunc0 = examplefunc1;
somelongsignature testfunc1 = somelongsignature {return x + 3};

public void main(){
     import std.stdio;
     writeln(testfunc0(5)); // Should output 10
     writeln(testfunc1(5)); // Should output 8
}



Thanks!
Apr 05 2016
next sibling parent pineapple <meapineapple gmail.com> writes:
Ah, aside from the mismatched "examplefunc" numbers - please 
disregard

Can't post example code without stupid typos for the life of me
Apr 05 2016
prev sibling next sibling parent reply Anonymouse <asdf asdf.com> writes:
On Tuesday, 5 April 2016 at 11:35:24 UTC, pineapple wrote:
 If I have a common function signature I'm using throughout my 
 code, and I feel like there should be a way to condense it 
 using a macro. The intuitive method isn't working, but this 
 seems like something D would be able to do. What've I got wrong 
 in this example?



 alias somelongsignature = int(in int x);
alias somelongsignature = int function(in int);
 int examplefunc0(in int x){
     return x * 2;
 }

 somelongsignature testfunc0 = examplefunc1;
 somelongsignature testfunc1 = somelongsignature {return x + 3};
somelongsignature testfunc0 = &examplefunc0; somelongsignature testfunc1 = function(in int x){return x + 3;}; somelongsignature testfunc2 = function(x){return x + 15;}; somelongsignature testfunc3 = (in int x){return x + 20;}; somelongsignature testfunc4 = (x){return x + 25;}; somelongsignature testfunc5 = (x => x+30); // probably more You can't get rid of the signature completely as the functions still need a parameter list with x declared. You will get "Error: undefined identifier 'x'" otherwise. You can largely omit the *type* of x if it can be inferred from the signature, but you can't have its name be solely in the signature alias. Parantheses are optional when calling functions without arguments. This is valid D: void main() { import std.stdio; writeln; // valid, no parantheses makes it writeln(), compare 'testfunc0 = examplefunc1/*()*/;' writeln = "Hello world!"; // valid, looks funky but helps with properties // auto doesntwork = writeln; // invalid, writeln() returns void // auto doesntworkeither = &writeln; // invalid, writeln is a template alias println = writeln; // valid, aliases to templates work println("Hello world again!"); println; println(3.14); } So the original code was trying to assign testfunc0 the return value of a call to examplefunc1(), which doesn't exist. You want the function pointer instead.
Apr 05 2016
parent pineapple <meapineapple gmail.com> writes:
On Tuesday, 5 April 2016 at 13:17:38 UTC, Anonymouse wrote:
 You can't get rid of the signature completely as the functions 
 still need a parameter list with x declared. You will get 
 "Error: undefined identifier 'x'" otherwise. You can largely 
 omit the *type* of x if it can be inferred from the signature, 
 but you can't have its name be solely in the signature alias.
On Tuesday, 5 April 2016 at 13:19:43 UTC, ag0aep6g wrote:
 On 05.04.2016 13:35, pineapple wrote:
 Saves you some typing, especially with complicated parameter 
 types.

 Another thing is std.traits.Parameters
You are both wonderful, this is exactly what I was trying to work out. Thank you so much!
Apr 05 2016
prev sibling parent ag0aep6g <anonymous example.com> writes:
On 05.04.2016 13:35, pineapple wrote:
 alias somelongsignature = int(in int x);
alias somelongsignature = int function(in int); Or if you want to accept methods and such: alias somelongsignature = int delegate(in int); You can name the parameter, but it won't be part of the type.
 int examplefunc0(in int x){
      return x * 2;
 }

 somelongsignature testfunc0 = examplefunc1;
somelongsignature testfunc0 = &examplefunc0; Note the ampersand.
 somelongsignature testfunc1 = somelongsignature {return x + 3};
I don't think there's a way to do this as nicely as you want. One thing you can do is declare the parameters without types: somelongsignature testfunc1 = (x) {return x + 3;}; Saves you some typing, especially with complicated parameter types. Another thing is std.traits.Parameters: alias F = int function(int, float, string, void*); import std.traits: Parameters; F testfunc2 = (Parameters!F args) {return args[0] + 3;}; This way you don't have to type out a long list of parameters, but `args[0]` isn't as nice as `x`, of course. There may be a way to transfer the parameter names as well, but I suspect that's going to be a little more fiddly.
Apr 05 2016