We call this type of optimisation "stream fusion".
In an ideal world, the compiler would always know to do this for us. In practice, it's very difficult (in most languages) to determine whether this optimisation is correct.
In the README example's case, the optimisation happens to be correct because both mapping functions are pure. If they had side effects, then stream fusion might create different results than the original code. Let's make this concrete with an example.
Say our array is `[1, 2]` and our functions are `function A(n) { print("A: "+n) }` and `function B(n) { print("B: "+n) }`. Then _without_ stream fusion, we would see the following output:
```
A: 1
A: 2
B: 1
B: 2
```
_With_ stream fusion, we would see different output:
```
A: 1
B: 1
A: 2
B: 2
```
Since the mapping functions have side effects, stream fusion is not valid here.
Some languages can do automatic implicit stream fusion. Haskell is a great example of this: it's able to determine when stream fusion is correct because the language has an _effect tracking system_ where functions with side effects are distinct from functions without side effects.
> In practice, it's very difficult (in most languages) to determine whether this optimisation is correct.
>
> [...] the optimisation happens to be correct because both mapping functions are pure. If they had side effects, [...]
TLDR: make all your functions pure. It'll make it so much simpler for you, your coworkers, but also the compiler(!) to reason about your code.
About half of the bugs and issues I come across in my $DAYJOB are because code that I use (through a third-party library) is not pure. If I had a penny every time I fixed a bug caused by impure code, I'd be rich.
>Isn't this an optimisation that could/should be handled by the compiler (JIT evaluation or something like that)?
Interesting question, which i also asked myself every once in a while, but unfortunately couldn't find a clear answer so far. Maybe someone with deeper understanding of swiftc or aot compilers in general here could clarify?
ps.: To give my reply a meaning. JIT optimization in particular can not happen here, because swift is an ahead of time compiled language, which means the compiler produces machine code which runs directly on your CPU. JIT is a thing for languages which run in a virtual machine (e.g. Java or C#) or an interpreter (e.g. Javascript).
That said, pardon my ignorance on the subject -
> This seems nice, but we've introduced an inefficiency: in mapping over the array twice, we unnecessarily create an intermediate array.
Isn't this an optimisation that could/should be handled by the compiler (JIT evaluation or something like that)?