Why some collection methods do a shallow copy and some not? mutable vs immutable

Hi all,

After testing and reading the doc about the collection methods. I realize that some modify the original collection (mutable) and some not (immutable).

Why this technical choice?

I have issues understanding this decision.

Let’s take an example.

collection.sort()

if we have $col1 and do a sort like that :

<code 4D>
$col2:=$col1.sort()
</code 4D>

$col2 and $col1 will share the same reference. What is the purpose to return a collection if the original collection is also modified? We end up with 2 collections that are actually the same.

It could be nicer, to not modify the original collection so that we will still have the original collection before the sort, and the modified one.

Collection methods, in my opinion, should always be immutable and return the result as a new reference. (https://medium.com/dailyjs/the-state-of-immutability-169d2cd11310)

If we want to have only one collection, we can easily do

<code 4D>
$col1:=$col1.sort()
</code 4D>

But in the current situation, if we want to keep the original collection not sorted we must do

<code 4D>
$col_not_sorted:=$col1.copy()
$col2:=$col1.sort()
</code 4D>

So we end up with 3 collections : 1 not sorted and 2 sorted that share the same reference.

So why this choice to do some methods mutable and some immutable? Is mutable methods dangerous and can have side effect if we are not careful?

It is also hard to remember which method are mutable and which are not and we have to be careful because the 2 behaviour doesn’t need the same treatment in the code.

That’s why there are two methods. Sort and OrderBy.

Sort is modifying the collection, OrderBy keeps the original collection unchanged and returns another, sorted.

Ok, I think, after more thinking and analyze of each method, that there is a meaning.

I have taken the sort method but I think we should stop on each method which is mutable and try to understand the reason.

sort: mutable but we can use orderBy not to modify the original collection clear: The action clear is directly on the collection. But then why returning another empty collection?
combine: The action is to combine col1 and col2 col1.combine(col2). But then why returning another collection?
fill: Same as combine, the action is directly on the collection. But then why returning another collection?
insert: Same again. We want to insert in the collection that call the command. But then why returning another collection?
push / unshift : Those 2 methods insert something in the existing collection. But then why returning another collection?
pop / shift: OK those remove something in the collection which calls the method and return the removed element -> Good behaviour
resize: Resize the collection. But then why returning another collection?
remove: Remove some elements from the original collection. But then why returning another collection? Here it could return a collection with the removed elements?

It seems the main question is “why returning something, if it is already changing the original one”, yes?

Because returning something allows to daisy chain.

And because you need it for the “new stuff” I cannot talk about here today.
Wait for the master class at 4D Summit 2018 and you will understand. Or at least you get the idea, even better if you visit the advanced training, then I’m sure you will understand.

Ok let’s wait for the advanced training to see what’s coming next :slight_smile:

Thanks for the answer.