The first reads:

- *change `X` in-place for `X - mean_vector`. The variable `X` still points to the same memory, it's now just updated.*

The second reads

- *calculate `X - mean_vector` producing a fresh numpy array and then assign it to the name `X`. Afterwards the name `X` points to a whole new piece of memory, and the original array that was pointed to by the name `X` is left alone.*

In the original version of this function the array passed in to the function was destructively modified in place:

```python
X_1 = X.copy()
y = principal_component_decomposition(X)
np.all(X_1 == X) #  False! X has been modified by the function call.
```

which @patricksnape interpreted as a dangerous side effect.

Do you think this copy could be problematic for large arrays? If so we might have to consider an `inplace` kwarg on this function. Or we could allow an `out` kwarg as numpy frequently does.

```python
X_1 = X.copy()
y = principal_component_decomposition(X, out=X)
np.all(X_1 == X) #  False, X is changed but we were explicit
```
vs

```python
X_1 = X.copy()
y = principal_component_decomposition(X)
np.all(X_1 == X) #  True, X experiences no quiet changes
```