digitalmars.D.learn - Using a macro for a function signature
- pineapple (17/17) Apr 05 2016 If I have a common function signature I'm using throughout my
- pineapple (3/3) Apr 05 2016 Ah, aside from the mismatched "examplefunc" numbers - please
- Anonymouse (34/45) Apr 05 2016 somelongsignature testfunc0 = &examplefunc0;
- pineapple (4/13) Apr 05 2016 You are both wonderful, this is exactly what I was trying to work
- ag0aep6g (19/25) Apr 05 2016 alias somelongsignature = int function(in int);
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
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
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
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.ParametersYou are both wonderful, this is exactly what I was trying to work out. Thank you so much!
Apr 05 2016
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