Ok, I see that my function `h`

(revised to take an arguement as `h1`

)

does indeed not allocated if it is working on bitstypes.

```
function h1(tup)
return (getfield(tup, 1), getfield(tup, 3))
end;
julia> @btime h1((10,20,30))
0.029 ns (0 allocations: 0 bytes)
(10, 30)
julia> @btime h1((:a, :b, :c))
6.717 ns (1 allocation: 32 bytes)
(:a, :c)
```

If we are willing to be convoluted, this can be made nonallocating by putting everything into type params.

Putting things into typeparams just to make them *isbits* feels odd,

and I think is only doable with `Symbols`

?

```
function h_t(tup)
return Val{(getfield(tup, 1), getfield(tup, 3))}
end;
h_i(::Type{Val{L}}) where L = L
h2(tup) = h_i(h_t(tup))
julia> @btime h2((10,20,30))
0.029 ns (0 allocations: 0 bytes)
(10, 30)
julia> @btime h2((:a, :b, :c))
1.246 ns (0 allocations: 0 bytes)
(:a, :c)
```

In the microbench mark it works out to be faster.

But I am dubious as to if it will in practice.

The `@code_typed`

for `h2`

is just a worse version of that for `h1`

)

```
julia> @code_typed h1((:a, :b, :c))
CodeInfo(
1 ─ %1 = (Main.getfield)(tup, 1)::Symbol
│ %2 = (Main.getfield)(tup, 3)::Symbol
│ %3 = (Core.tuple)(%1, %2)::Tuple{Symbol,Symbol}
└── return %3
) => Tuple{Symbol,Symbol}
julia> @code_typed h2((:a, :b, :c))
CodeInfo(
1 ─ %1 = (Main.getfield)(tup, 1)::Symbol
│ %2 = (Main.getfield)(tup, 3)::Symbol
│ %3 = (Core.tuple)(%1, %2)::Tuple{Symbol,Symbol}
│ %4 = (Core.apply_type)(Main.Val, %3)::Type{Val{_1}} where _1
│ %5 = (Main.h_i)(%4)::Any
└── return %5
) => Any
```

but it seems inpractice that `h2`

is actually better.

```
julia> @btime (()->hash(h1((:a, :b, :c))))()
13.260 ns (1 allocation: 32 bytes)
0x3098f6b4cf50f6cc
julia> @btime (()->hash(h2((:a, :b, :c))))()
8.031 ns (0 allocations: 0 bytes)
0x3098f6b4cf50f6cc
```