Discrepency in Signal concatenation when using variables

Hi,
Newbie here… I’m experiencing a bizarre behavior:

I create an Array using Signal: (0, 1, 2, 3, 4) and attach it to variable “signalarray”.
If i post or plot variable “signalarray” I get:
[0, 1, 2, 3, 4].

(var signalarray, why;
signalarray = Signal.series(5, 0, 1);
signalarray.postln;
) // outputs: Signal[ 0.0, 1.0, 2.0, 3.0, 4.0 ]

Reverse this array and attaching it to variable “why” and then plotting the unmodified variable “signalarray” i get:
[4, 3, 2, 1, 0]. (Bizarre… i haven’t changed “signalarray” only “why”).

(var signalarray, why;
signalarray = Signal.series(5, 0, 1);
why = (signalarray).reverse;
signalarray.postln;
) // outputs: Signal[ 4.0, 3.0, 2.0, 1.0, 0.0 ]

If I exchange (signalarray).reverse with (signalarray+0.0).reverse then i get what i expect:
[0, 1, 2, 3, 4].

(var signalarray, why;
signalarray = Signal.series(5, 0, 1);
why = (signalarray+0.0).reverse;
signalarray.postln;
) // outputs: Signal[ 0.0, 1.0, 2.0, 3.0, 4.0 ]
var first = Signal.series(5, 0, 1.0/50);
var second = first.copy.reverse;
(first ++ second).plot(discrete: true);

You need a copy.
reverse for some reason does this in place, it mutates the original. I don’t know why because Array doesn’t and it isn’t in keeping with how most supercollider things work. It looks like internally this is done with a primitive, so this was probably done for speed, though it is very confusing.

Thanks a lot Jordan.

I’ve actually modified my post to make it even clearer. What you suggest makes some sense to me though i don’t understand then why adding +0.0 to the Signal array before reversing it prevents this behavior. I’ve set out the three examples above.

The code at the end, evaluates to this.

(
var signalarray = Signal.series(5, 0, 1);
var temp = signalarray + 0.0; // here a new signal is made
var why = temp.reverse;
signalarray
) 
// outputs: Signal[ 0.0, 1.0, 2.0, 3.0, 4.0 ]

whereas, when you don’t add 0…

Signal.series(5, 0, 1).reverse;

there is no copy and a single signal object is mutated.

I think this is pretty dumb, and what you expect to happen is the correct thing to expect. Somewhere along the line, someone decided the performance benefit was worth the confusion, a mistake, in my opinion. Supercollider isn’t very friendly in this regard, although difficulties with figuring out where copies occur is not an uncommon issue with dynamic languages.

1 Like

Thanks @jordan! That’s really helpful. Agree with your sentiments and good to know my frustration was not misplaced.