I read about macros the last few days and I am starting to love the concept. Due to their powerfulness, I still seem to not be able to get my ideas into an implemented Macro (actually in two cases and this is the first).
Let’s assume I have a decorator pattern like parametrised type like
abstract type P end
immutable struct Q{T <: Float64} <: P
field::T
end
immutable struct DecoQ{S <: Q{T} where T} <: Q
base::Q{T}
info::Int
DecoQ(t::T) = new(Q(t),0)
end
get(t::Q{T} where T) = t.field
get(t::DecoQ{S <: Q{T} where T}) = get(t.base)
myF(q::T where T<:Q, i::Int)::Q = Q(i*Q.flield)
function myF(q::T where T <: DecoQ, i::Int)
info = info+1
return DecoQ(myF(q.base,i),info)
end
So if I initialise a value to be DecoQ
it is a Q
decorated with another field and with the getters I have a proper access to the field (I could also write that to access Q
instead of it’s field, it’s to “unpeel” the decorator(s)).
With this pattern (adapted from object oriented, I’d be open for a more Julia-type decorator), I would like to have a @macro
that easily starts the procedure decorated, i.e. if I have
q::Q{Float64} = Q(0.1337)
qnew = myF(q,23)
I would like to be able to change that last line to
qnew = @decorateQ myF(q,23)
That changes the call to myF( DecoQ(q,23), 23)
for example (or even calculate on i
for example changing it to myF( DecoQ(q,46),23)
).
So I can describe what I would like to have, but for the last days I still haven’t understood macros enough to know how to do that. Especially hooking into arguments and local variables is something I haven’t understood yet – so maybe if somebody could solve this, I’d learn more about macros (or give me a hint where to find such ideas).
edit: the first <: P
was mistyped to be <: E
, Float
was corrected to Float64
.