Wouldn’t that be the classical case for recursion?
function chain(x::Int, ca::Int, fs::Tuple)
if length(fs) == 1
fs[1](x, ca)
else
chain(fs[1](x,ca), ca, fs[2:end])
end
end
julia> @btime chain(42, 13, (+,*,+,*,+))
1.488 μs (8 allocations: 480 bytes)
9477
not so fast as your preallocated chains, but simpler. If your chains vary, this would be certainly preferable.