I struggle to wrap my skull around metaprogramming!
So, following great advice (thanks guys) [Extract intermediate data from inside a function] I have written the following code
#module spying
#export spy
#export store
# a simple spying closure
function spy(targets)
vals=[]
tags=[]
function store(val,tag)
if tag ∈ targets
push!(vals,copy(val))
push!(tags,tag)
end
end
store(val)=store(val,:unspecified)
function get()
return (vals,tags)
end
return store,get
end
macro store(ex)
@assert ex.head== :(=)
local var = ex.args[1]
return quote
$ex
store($var,var)
end
end
#end #module spying
#using spying
# a function to spy on
f(x) = f((val,tag)->nothing,x)
function f(store,x)
y = x
for i = 1:3
@store y = 3*y
#y = 3*y
#store(y,:y)
end
z = y+2
store(z,:z)
return 2z
end
(store,results)=spy([:y,:z])
f(store,3)
(vals,tags)=results()
display(vals)
display(tags)
The idea is to be able to extract intermediate results from function f, by spending in a function to retrieve the data. Any way, if, int he definition of f I comment the line with a macro, and uncomment the two following lines, everything works like a breeze. But my “macro store” is not doing what I want.
a) Executing the code generated by the call @store y = 3*y
generates a “y not defined” error. But the code @store y = 3
does not generate this error.
b) I want the macro to generate the code store(y,:y)
and I do not know how to generate :y
: )
Philippe