$(esc(f)) evaluates the expression f, so it is not an expression anymore, but a function. To avoid this, you can build the sf.stored_func = f expression yourself:
macro capture_function(sf, f)
Expr(:(=), :($(esc(sf)).stored_func), Expr(:quote, f))
end