# 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.

I also ran into some… interesting decisions in the Signal API recently. It’s a subclass of ArrayedCollection but certain methods behave completely differently from superclasses. `reverse` is one, `normalize` is another (arguments are different and it normalizes peak absolute value instead of range). Also, `Signal.newFrom([1, 2, 3]).linlin(0, 3, 0, 3)` returns an ordinary Array instead of a Signal.

1 Like