~var=[] , ~var.fill( 2,4)

I’m sorry if I have asked this before
But why is the second method of filling the array not giving the desired resultt ?

~one=Array.fill(4,3)
~one



~two=[]
~two.fill(4,3)

Struggling further , I defined the size and while executing the add method I can put elements in the first array …size 10
Using ~var=Array(10)
But when using ~var= and using the add method (I repeated the add method a couple of times each time with a new value) , it only puts two elements in max , despite the being set to 8

~tim=Array(10)
~tim.add(18)




~tom=[].(8)
~tom.add(4)

1

I think this is because Array’s size is defined when it’s created and is then immutable, meaning you can’t add or remove slots. Using List instead allow you to redefine it’s size on the fly. It necessitates more CPU calculation, but I don’t think our computers care that much nowadays, unless you are using a lot of List at the same time.

Array is a reference to the class Array.

[] is not a reference to the class. It’s an instance of the class Array.

There is a class method fill (which creates an instance and fills it) and an instance method fill (which can only operate on an existing instance – which, as correctly noted, can’t change its maximum size).

hjh

So is there a method to fill [ ] instance of class array ?
Iow , an example of filling instance array as shown in example would be nice

yes

you can check to see if there is a method like this:

[1,2,3].respondsTo(\fill) //true

from the help for ArrayedCollection:

.fill(value)
Inserts the item into the contents of the receiver.

NOTE: the difference between this and Collection's *fill.
(
var z;
z = [1, 2, 3, 4];
z.fill(4).postln;
z.fill([1,2,3,4]).postln;
)

remember that methods may be inherited - so be sure to check out the methods of the superclasses

When I assign Array.(4) to variable ~tulp and keep on adding elements , by replacing the number in add
see second line
The arrays gets filled
When I reassign an array of size 2 to the same variable ( line ) ,I can go beyond size 2 , I can put in 5 elements .
Declaring the variable , shows four elements , what happened to the declaration of size 2 ?
Is the first declaration of size 4 still in memory?

~tulp=Array(4)
~tulp.add(6)
~tulp






~tulp=Array(2)
~tulp.add(7)
~tulp










Yes , but z is already a filled array
I meant an empty one like
z=[ nothing inside ].fill me !!

answered above:
.fill cant change the size of an Array.

When I assign Array.(4) to variable ~tulp and keep on adding elements , by replacing the number in add
see second line
The arrays gets filled

always reassign when you use .add with Array instances! results otherwise as you are seeing are not dependable.

My guess is that Arrays can grow up to the next power of 2 size then stop…

here is the help for .add

Adds an item to an ArrayedCollection if there is space. This method may
return a new ArrayedCollection. For this reason, you should always
assign the result of add to a variable - never depend on add changing
the receiver.

    >
    (
    // z and y are the same object
    var y, z;
    z = [1, 2, 3];
    y = z.add(4);
    z.postln;
    y.postln;
    )

    (
    // in this case a new object is returned
    var y, z;
    z = [1, 2, 3, 4];
    y = z.add(5);
    z.postln;
    y.postln;
    )

This is weird
Declare the variable c =[1,2,3,4]
Keep adding the value 7 , execute this a couple of times
Our array now has reached a maimum number of 5 elements , see first screenshot .
Re-evaluate our variable but now =[1,2,3,4,5] , all of a sudden the value 44 can be added 4 times ?
See second screesnhot
It seems that the new declaration holds something in memory when it comes to the previous size of the array

~top=[1,2,3,4,4]
~top.add(44)
~top


screenshot

Or this , execute each line from top to bottom and notice that value 44 can be added 4 times , what defined that ?

~light=[1,2,3,4]
~light.add(5)
~light
~light=[1,2,3,4,5]
~light.add(6)
~light

explained above!

Arrays seem to be able to grow only up to the next power of 2 in size (that is up to 4, 8, 16 elements).

a=[1,1,1];
a.add(1)
a //[1,1,1,1]
a.add(1)
a //[1,1,1,1]

now this is not a very useful behavior most of the time!

so always reassign when using .add with an Array.

a=[];
a = a.add(1) // do this as many times as you like;

If you want to be able to use .add without reassigning, use a List instead of an Array

a=List[];
a.add(1) // do as many times as you like

I just encounter these when I force myself to learn the language .
If anyone knows if there are supercollider education classes in Flanders-Belgium give me a sign .
Purely focused on the language , dsp side is not needed

But… why?

There’s a method (Array.fill) that gives you an array, of a size that you choose, filled with the contents you choose.

There’s another method (operating on an existing instance) which doesn’t let you control the size.

You want the first behavior. The common sense way to proceed is to use the first method!

Trying to force the second method to do the first is extremely unlikely to achieve a useful result… like saying “I really want 3+4 to be 12.”

c is always 4 elements in that example – c never becomes 5 elements.

When you later start with c = [1, 2, 3, 4, 5] then you’ve changed the game.

hjh

Yes I might have changed the game when declared c=[1,2,3,4,5]
But why does c in the end gives me then [1,2,3,4,5,6] , iow the added value is kept when declaring var c on its own
p.s. using f in this example
Executed each line only once from top to bottom

f=[1,2,3,4]
f.add(5)
f;
f=[1,2,3,4,5]
f.add(6)
f;

I dunno of any classes, but Andrea Valle’s Introduction to SuperCollider is very very extensive on the programming language side of things.


Semiquaver has already answered this question: “Arrays seem to be able to grow only up to the next power of 2 in size (that is up to 4, 8, 16 elements).”

When you start with 5, internally 8 slots are reserved. So add will mutate the same instance up to 6, 7 and finally 8 elements. After that, add will give you a new Array with 16 slots, using 9 of them.

@semiquaver actually I’d disagree. It’s a useful optimization when you’re adding a large number of elements.

It’s very slow to create new array instances and discard old ones.

If you’re adding just a few elements, then you want the array to grow just a little per expansion. If you’re adding a lot, then you want to add a bunch of elements before it grows.

This log2(n) approach neatly does both.

hjh

One source of confusion for OP might be that if you interpret a = [1,2,3,4]; a.add(5), [1,2,3,4,5] prints to the post window. But a == [1,2,3,4] not [1,2,3,4,5] and there’s no indication that the side effect requested by add didn’t happen.

That is a=[1,2,3,4].add(5) returns [1,2,3,4,5], but a still points to [1,2,3,4] unless you reassign: a = a.add(5). Its a common gotcha, not sure if there’s anything that could be done to help make this detail less painful…

Hmm…

a = a.add(x);  // ok

a.add(x);  // not ok (but if a is a List, then, ok)

I don’t think there’s a way for either the compiler or the interpreter to distinguish these cases.

hjh

1 Like

A good argument for functional programming!

I guess the other thing about this thread is that there are different levels of understanding.

You can get by perfectly well with:

  • Array.fill and not the other way
  • Reassign when adding

… just do it the recommended way and get your stuff done happily.

It only becomes upsetting when you start saying “Well I think [].fill should be the same, why isn’t it” or “I’m breaking the recommendation in the Array help file and I think there shouldn’t be any weird consequences from that” but actually all of that is unnecessary in the end. It’s ok for curiosity but in the meantime, it’s not making music.

(Edit) Another way to put it is that every computer language has quirks and funny things. SC’s array-add behavior is quirky! But at the end of the day, it’s not going to change, so the outcome of the discussion is that you either have to accept it and use it as is, or switch to another language. It’s fair to ask why but it still isn’t going to change the end result :man_shrugging:

hjh