Very strange behavior with multiple arguments passed in and out of functions?

Ernest's icon

I'm finding a number of thing slike this, but first let me check if my brain is correct with the simplest case:

test(input1, input2){
    return input1 +2, input2 +2;
}
out1 = 0;
out2 = 0;
out1, out2 = test(in1, 0); // FAILS, returns 0 on 2nd argument 
out1, y    = test(in1, 0); // WORKS, returns 2 for 2nd argument
out3 = y;

Am I right in thinking this is strange, or do I misunderstand something? Here's the patch.

Max Patch
Copy patch and select New From Clipboard in Max.

stkr's icon

your brain is correct. just gen is a bit crap :-)

i get burnt by this often.

i don't know if it is a 'bug' per se or just an unfortunate way that it must work in order to comply with the various jit-compiled rules that must be in place.

in general, if in doubt, declare everything explicitly and do not use in/out directly. this can also happen if you do not process param()s before using in audio rate functions, as well. and can happen when writing many functions in one line as arguments to other functions.

the best rule is: always keep the code compile sidebar open when writing code - it quickly lets you know what gen likes / does not like.

it would be cool if this sort of thing could be more robust - i agree with you. i have no scientific answers here, just sympathy.

Ernest's icon

Thank you for verifying my brain ,lol.

While I agree with what you say, this is not very effiicient, and moreover, it is very confusing that the first argument passed in and returned works, but the others don't. I'm sure this has frustrated alot of users.

My next case is related, about the calcualtion of constants, particularly ones using samplerate. In earlier versions of gen~, these were compiled out as constants. The downside was that one needed to recompile gen~ after changing samplerate. This was documented. The current version of Max does not do this.

In the past, if you said x +=1/3 in codebox, and looked in the code sidebar, it said x = x + .3333333333333. Now it says x = x + 1/3. It seems constants are no longer compiled out at all, and the change was never explained. This is very inconvenient.

Here is a demo patch of samplerate:

no_srate_calc(in){
    y = in;
    return y;
}
srate_calc(y){
    y = pow(samplerate, 2);
    return y;
}
Param mode;
y = 0;
for(x =0; x 

The CPU usage goes up when calculating constants in main. the constants are recalcualted every sample clock cycle. Also, calculating exactly the same thing with samplerate, instead of a constant, is now significantly higher cpu. This means one has to pass all constants in from inputs into codebox, or precompute them. And not only is this inconvenient, passing constants around all over the place, but one rapidly runs out of inputs. Here is a demo patch.

Max Patch
Copy patch and select New From Clipboard in Max.

Ernest's icon

My third problem is that one cannot include functions in return values if one is returning more than value. I wanted a function to make 8 sine waves. Returning a value from one function in a return call works fine:

sinewave(rate, spread){
        return cycle(rate + spread * 0.1);
}

In fact one can nest functions, and it's quite effieint that way. Likewise, the following works as documented:

sillyfunction(rate, spread){
        return rate, rate, rate, rate, rate, rate, rate;
}

So one naturally assumes the following will work:

sinebank(rate, spread){
    return cycle(rate),
        cycle(rate + spread * 0.1),
        cycle(rate + spread * 0.2),
        cycle(rate + spread * 0.3),
        cycle(rate + spread * 0.05),
        cycle(rate + spread * 0.15),
        cycle(rate + spread * 0.25),
        cycle(rate + spread * 0.35);
}

But for some inexplicable reason Max won't compile it, with a totally incomprehensible error message and no indsication where the error was in the code. One actually has to write:

sinebank(rate, spread){
        s1 = cycle(rate);
        s2 = cycle(rate + spread * 0.1);
        s3 = cycle(rate + spread * 0.2);
        s4 = cycle(rate + spread * 0.3);
        s5 = cycle(rate + spread * 0.05);
        s6 = cycle(rate + spread * 0.15);
        s7 = cycle(rate + spread * 0.25);
        s8 = cycle(rate + spread * 0.35);
        return s1, s2, s3, s4, s5, s6, s7, s8;
}

This is also not only inconvenient, and counterintuitive (requiring quite a bit of debugging to figure out), but also inefficient.

I have a fourth problem with Max refusing to compile some functions with returns of multiple values inside conditional loops, but it will take me several days to figure out exactly what the problem is without ambiguity. So before figuring it out, I am wondering if Cycling74 is following this forum thread and has any comment on whether the above are bugs which will be fixed, or not.