Passing `Symbol` variable allocates when literal does not?

For these macros I think to avoid these extra allocations you need to use typed globals (or constants but then the benchmark might be affected by constant propagation?)

using BenchmarkTools

function preparearrays!(arrays, N, L; mode = :all)
    for n in 0:(length(arrays)-1)
        if mode === :all
            for m in 0:(L-1) # run till length L to zero all bits
                arrays[n+1][m+1] = (n & (1 << m)) >> m
            end
        elseif mode === :basis
            arrays[n+1] .= 0;
            arrays[n+1][n+1] = 1;
        end
    end
    return arrays
end

preparearrays(N, L; mode = :all) = preparearrays!(collect(zeros(Int64, L) for i in 1:ifelse(mode==:basis, N, 2^N)), N, L; mode = mode)

arr::Vector{Vector{Int64}} = preparearrays(8, 16; mode = :basis);
var::Symbol = :basis

With this I get

julia> @allocated preparearrays!(arr, 8, 16; mode=var)
0

You can also make a wrapper function:

using BenchmarkTools

function preparearrays!(arrays, N, L; mode = :all)
    for n in 0:(length(arrays)-1)
        if mode === :all
            for m in 0:(L-1) # run till length L to zero all bits
                arrays[n+1][m+1] = (n & (1 << m)) >> m
            end
        elseif mode === :basis
            arrays[n+1] .= 0;
            arrays[n+1][n+1] = 1;
        end
    end
    return arrays
end

preparearrays(N, L; mode = :all) = preparearrays!(collect(zeros(Int64, L) for i in 1:ifelse(mode==:basis, N, 2^N)), N, L; mode = mode)

function get_allocated(arr, var)
    @allocated preparearrays!(arr, 8, 16; mode=var)
end

arr = preparearrays(8, 16; mode = :basis);
var = :basis;

get_allocated(arr, var)  # returns 0