I've been playing around with creating a @map macro:
indexify(s::Symbol, i, syms) = s in syms ? Expr(:ref, s, i) : s
indexify(e::Expr, i, syms) = Expr(e.head, e.args[1], [indexify(a, i, syms)
for a in e.args[2:end]]...)
indexify(a::Any, i, syms) = a
macro map(expr, args...)
quote
@assert all([map(length, ($(args...),))...] .== length($(args[1])))
out = Array(typeof($(indexify(expr, 1, args))), size($(args[1])))
for i in 1:length(out)
@inbounds out[i] = $(indexify(expr, :i, args))
end
out
end
end
When used inside a function it is nice and fast (around 40x faster than map),
but when used in global scope is is twice as slow as map. I assume this is
because of global variables prevent optimization. Now I wonder if there is
some way to introduce a scope to make the variables in expr local?