Iβm sorry for missing it.

We can type-stably create a tuple using `map`

and `zip`

by doing the following, but it will be less efficient because it goes through a `Vector`

.

```
using BenchmarkTools
f(a::NTuple{N}, b::NTuple{N}) where N =
NTuple{N}(map(((i, j),) -> j - i, zip(a, b)))
a = (1.0, 2.0)
b = (3.0, 5.0)
@btime f($a, $b)
```

Output:

```
30.885 ns (1 allocation: 96 bytes)
(2.0, 3.0)
```

The following similar code using `zip`

is more efficient (but too complex than `b .- a`

).

```
g(a::NTuple{N}, b::NTuple{N}) where N =
NTuple{N}(j - i for (i, j) in zip(a, b))
@btime g($(Ref(a))[], $(Ref(b))[])
```

Output:

```
1.300 ns (0 allocations: 0 bytes)
(2.0, 3.0)
```

Using `@code_native`

, I have found that the following three functions generate the same native code for `a = (1.0, 2.0)`

and `b = (2.0, 5.0)`

:

```
F(a, b) = b .- a
g(a::NTuple{N}, b::NTuple{N}) where N =
NTuple{N}(j - i for (i, j) in zip(a, b))
h(a::NTuple{N}, b::NTuple{N}) where N =
ntuple(i -> b[i] - a[i], N)
```

**Conclusion:** Using `g(a, b)`

, we can do exactly the same as `b .- a`

using `zip`

.