I'm glad to report that the general and beautifully functional solution sum(
imap(sinc_plus_x, x)) is in fact as efficient as the "devectorized"
hand-written one!
It turns out I made the mistake to forget to forward an expression like
"{Type{F}}" to the imap iterator constructor (cf. code below), making it
specialized on DataType instead of sinc_plus_x. (While I can see why this
prevented inlining, I still don't understand this caused allocations).
For the record, here is a possible implementation of imap for "functors"
with 1 argument:
immutable imap{TF, X}
F::TF
x::X
end
imap{F, X}(::Type{F}, x::X) = imap{Type{F}, X}(F, x)
Base.start(i::imap) = start(i.x)
Base.next(i::imap, s) = ((v, s) = next(i.x, s); (i.F(v), s))
Base.done(i::imap, s) = done(i.x, s)