It shouldn’t be hard:
struct NoCaptureClosure{F,Args} <: Function
f::F
args::Args
end
function NoCaptureClosure(f::F,args::Args) where{F,Args}
NoCaptureClosure{F,Args}(f,args)
end
@inline function (f::NoCaptureClosure)(args...)
f.f(args...,f.args)
end
macro nocapture(nf...)
if isempty(nf)
return :(error())
else
nametypes = nf[1:end-1]
names = [i.args[1] for i in nametypes]
types = [i.args[2] for i in nametypes]
f = nf[end]
if f.head == :(->)
args = gensym("args")
if isa(f.args[1],Symbol)
paralist = :($(esc(f.args[1])),$args)
else
paralist = :($(esc.(f.args[1].args)...),$args)
end
assigns = [:($(esc(i)) = $(args).$(i)) for i in names]
funcname = gensym("f_nocapture")
func = quote
local function $(funcname)($(paralist.args...))
return let $(assigns...)
$(esc(f.args[end]))
end
end
end
Args = :($(NamedTuple){$(tuple(names...)),$(Tuple){$(esc(types...))}}(tuple($(esc(tuple(names...)...,)))))
FuncWrap = :($(NoCaptureClosure)($funcname,$Args))
return quote
$func
$FuncWrap
end
end
end
end
It’s still a little inconvenient and buggy, but should work for simple cases. You can try to improve it.