So I want to create models that have a similar calculation graph but differ in small aspects.

Each model is represented as a struct with matching dispatches for function calc.

To demonstrate what I have so far, I created the following script:

```
#file: demonstration.jl
abstract type AbstractT end
""" concreteT1 and concreteT2 have different parameter sets """
struct concreteT1 <: AbstractT
a
b
c
end
struct concreteT2 <: AbstractT
a
b
c
p
end
""" the function body into which expressions have to be inserted via
expression ex_de """
macro calc_body(ex_de)
return esc(quote
a = ob.a
b = ob.b
c = ob.c
d,e = $ex_de
d += 1
e += 2
return a + b / (d*e)
end)
end
""" calc shall be able to be called with both concreteT1 and concreteT2"""
function calc(ob::AbstractT)
@calc_body(inserted_expression(ob))
end
""" expressions which can be inserted into calc_body """
macro de1()
return esc(:((0, 0)))
end
macro de2()
return esc(:((a/b, a*b*p)))
end
""" these functions decide, with type information about ob, which expression
will be inserted into calc_body during a call to calc(AbstractT)"""
@generated function inserted_expression(ob::concreteT1)
return @de1
end
@generated function inserted_expression(ob::concreteT2)
return @de2
end
function main()
""" works as expected """
ob = concreteT1(1, 2, 3)
""" UndefVarError will be thrown when trying to access a
(that should be known inside calc_body)"""
#ob = concreteT2(1, 2, 3, 4)
result = calc(ob)
println(result)
end
main()
```

So far, only calc(concreteT1) works, but not calc(concreteT2). An UndefVarError is thrown when trying to access variable “a” that, from my point of view, should be known within calc_body, where the returned expression from macro de2 is inserted.

I tried to esc() the returned expression from inserted_expression(concreteT2) but I it wouldn’t help either…

**Why am I not just using functions instead of trying to generate functions?**

I would like to be able to access every temporary variable known in calc_body and not think about what exactly goes into the code which calculates “d” and “e”.

**Why am I not just moving the content from de2 to inserted_expression(concreteT2)?**

In reality, calc_body can be modified at multiple points, not just with “ex_de”. If I then add concreteT3 that shares “ex_de” with concreteT1, but has another “ex_xy” (just an example), i want to reuse the expression that the existing macro de1 already returns.

I hope that I could make clear what my question is: **Why do I get the UndefVarError?** Can i change my code so that “a” will be known in the expression that de2 returns?

I am also open to criticism regarding my architecture itself.