More Than One Return Statement in Vex User Defined Function

   4911   10   3
User Avatar
Member
2035 posts
Joined: Sept. 2015
Offline
Hello,

In the docs it's stated that
You can have more than one return statement in a function.

I have made use of that in my own functions I have written( more than one return), but the final return that gets used is typically based on a conditional set up in the logic of my code.

But it has made me wonder, and too twist the meaning of docs..is there a way to return more than one value from the same return in the function? Like you can similarly with Python?

I know vex syntax structure is very similar to C/C++, and as far as I can remember, something like this is not possible in C ('directly' expressed at least), for C++ I don't have the experience to know.

I've played around with some attempts and at least the following syntax doesn't generate syntax errors, but I don't get any results either. ( confirmed by the default value that gets returned in the printf statement ).

Thanks for anyfeedback/comments.

function int TestReturns()
{
int A, B, C;

A = 5;
B = 7;
C = 8;

return A, B;

}

//*********************

int result_A, result_B;

// default check value;
result_A = 9;

(result_A, result_B) = TestReturns();

printf("return result = %g\n", result_A);
User Avatar
Member
2035 posts
Joined: Sept. 2015
Offline
Ok…forgot you can change the input arguments for the function.

So to get the same effect which the intent was to run the function only once and make use of two results.

Something like this works.
function int TestReturns(int outside_A, outside_B)
{
int A;

A = 5;

outside_A = 33;
outside_B = 44;

return A;

}

//*********************

int converted_A, converted_B, possible_error_code;

converted_A = 5;
converted_B = 6;

possible_error_code = TestReturns(converted_A, converted_B);

printf("Second argument set to %g\n", converted_B);
User Avatar
Member
22 posts
Joined: April 2018
Offline
BabaJ
Ok…forgot you can change the input arguments for the function.

So to get the same effect which the intent was to run the function only once and make use of two results.

Something like this works.
function int TestReturns(int outside_A, outside_B)
{
int A;

A = 5;

outside_A = 33;
outside_B = 44;

return A;

}

//*********************

int converted_A, converted_B, possible_error_code;

converted_A = 5;
converted_B = 6;

possible_error_code = TestReturns(converted_A, converted_B);

printf("Second argument set to %g\n", converted_B);
I don't think it's a good way to return multiple values. Changing input parameter is danger and hard to debug.
I don't know how to return more than one value from a function too.
User Avatar
Member
284 posts
Joined:
Offline
The way to explicitly do this in VEX is to add an “export” keyword ahead of the parameter:

float do_something(float input; export float output)
{
    output = input * 2;
    return input * 3;
}

then when calling the function:
float output1;
float output2 = do_something(6., output1);
float morestuff = output1 * output2;
Edited by jparker - July 28, 2018 11:40:12
User Avatar
Member
2035 posts
Joined: Sept. 2015
Offline
I don't think it's a good way to return multiple values. Changing input parameter is danger and hard to debug.

Perhaps in certain situations, but in my case this was for a single vex wrangle and as such the arguments being given were local and created for the purpose of the the one function; So if there was to be any debugging it would have been easy and not ‘dangerous’.

The way to explicitly do this in VEX is to add an “export” keyword ahead of the parameter:

Not sure of the purpose of the export keyword for the example given as removing that keyword still gives the same results.
User Avatar
Member
284 posts
Joined:
Offline
Hmm, then maybe you could define a struct with the data you need and have the function return that?
User Avatar
Member
284 posts
Joined:
Offline
BTW, the help on functions has this handy info on parameter modification:

As in RenderMan Shading Language, parameters to user functions are always passed by reference, so modifications in a user function affect the variable the function was called with. You can force a shader parameter to be read-only by prefixing it with the const keyword. To ensure that the user function writes to an output parameter, prefix it with the export keyword.

[www.sidefx.com]
User Avatar
Member
2035 posts
Joined: Sept. 2015
Offline
Hmm, then maybe you could define a struct with the data you need and have the function return that?

My original post was about a year and half ago, and my final solution was the equivalent I posted for the project I was working on.

Since then I have taken different approaches where I don't really need to have this functionality ( at least not yet ).

And yes I have used structs which are very usefull with not only multiple variables but also ‘encapsulating’ functions that depend on each other within the same defined struc.

I was responding here now because I haven't seen the use of the export keyword and your headsup on that help is appreciated - thanks.

Will have to play around with it for a bit to make it stick my memory.
Edited by BabaJ - July 28, 2018 16:52:51
User Avatar
Member
284 posts
Joined:
Offline
Good to know! I should have checked the date more carefully…
User Avatar
Member
80 posts
Joined: June 2013
Offline
wavebit
I don't think it's a good way to return multiple values. Changing input parameter is danger and hard to debug.

Yes, it is considered poor form in general programming terms. A function that changes input objects introduces what are called (coincidentally?) side effects where the code is making unexpected changes to variables that may not be obvious to the user.

Sure it seems fine if only you are using the code but it remains risky because you may lose track as the thing gets bigger. If you are depending on those values elsewhere and some function is making unannounced changes it will be very hard to track down what is going wrong. That is why the ‘export’ keyword would be used: it does not change how the function behaves it just warns the user that it may change that variable.
Edited by Rebus B - Sept. 17, 2018 12:28:02
User Avatar
Member
192 posts
Joined: April 2015
Offline
Curious fact:
You can't just supply a value if you don't need the value, like you can for example with with &prim argument of the xyzdist() function if you don't need the primitive number stored in a variable.

It gives the error: "Read-only expression for write-only parameter".
Edited by OdFotan - April 16, 2022 04:47:44

Attachments:
Screenshot 2022-04-16 at 10.39.45.png (45.0 KB)

  • Quick Links