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
.