# Interpolate expression into macro

**URL:** https://discourse.julialang.org/t/interpolate-expression-into-macro/24204
**Category:** General Usage
**Tags:** metaprogramming
**Created:** [May 14, 2019, 11:26am UTC](https://discourse.julialang.org/t/interpolate-expression-into-macro/24204 "2019-05-14T11:26:29Z")
**Posts on this page:** 1
**Showing post:** 10

<div class="post-metadata">

### Author: ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)
#### Post date: [May 15, 2019, 7:00am UTC](https://discourse.julialang.org/t/interpolate-expression-into-macro/24204/10 "2019-05-15T07:00:04Z")

</div>

The full background is the following: I have implemented a type `Particles <: Real` which wraps a vector for `Float64`. I can define lots of functions for this type, but some functions are hard to define in a meaningful way. In those situations, I want to fall back to propagate each float of the wrapped vector through the function one by one and collect the result in a new `Particles` at the output. If the `particles` appear as an argument to the top-level function, this is really straightforward. The problem appears when my type `Particles` appears as a field nested somewhere in a struct I have no control over. As an example, consider this structure

```julia
julia> P
TransferFunction{ControlSystems.SisoRational{StaticParticles{Float64,100}}}
   0.998 ± 0.1
-----------------
1.0*s + 1.0 ± 0.1

Continuous-time transfer function model

julia> dump(P)
TransferFunction{ControlSystems.SisoRational{StaticParticles{Float64,100}}}
  matrix: Array{ControlSystems.SisoRational{StaticParticles{Float64,100}}}((1, 1))
    1: ControlSystems.SisoRational{StaticParticles{Float64,100}}
      num: Polynomials.Poly{StaticParticles{Float64,100}}
        a: Array{StaticParticles{Float64,100}}((1,)) StaticParticles{Float64,100}[0.998 ± 0.1]
        var: Symbol x
      den: Polynomials.Poly{StaticParticles{Float64,100}}
        a: Array{StaticParticles{Float64,100}}((2,)) StaticParticles{Float64,100}[1.0 ± 0.1, 1.0]
        var: Symbol x
  Ts: Float64 0.0
  nu: Int64 1
  ny: Int64 1

```

The particles appear deeply nested in the object `P` which is the input to my function, and can be accessed by `P.matrix[1].num.a[:]` and `P.matrix[1].den.a[:]`. which are the expressions I am generating.

I want to create an object identical to `P`, let’s call it `P2`, but in all places where `Particles` appear, I want to have `Float64` instead. I then want to populate `P2` with particle index `i` for `eachindex(particles)`. I then call my function with `P2` which is completely free of weird particle types and put the result of the computation into an output object with the desired `Particles` fields.

The real code to generate the expressions is [here](https://github.com/baggepinnen/MonteCarloMeasurements.jl/blob/281a59fb03bfc02fd7894889d2073b14e2a6b878/src/deconstruct.jl#L94)  
I turn these expressions into functions that get and set fields in the generated intermediate buffers `P2` and `Pres` to store the result. The buffer is autogenerated [here](https://github.com/baggepinnen/MonteCarloMeasurements.jl/blob/deconstruct/src/deconstruct.jl#L35) and it mostly works okay at the moment. The only problem is with the world age, causing me to not be able to use the getter and setter functions until the world age is updated. My current strategy is to make the user create a `Workspace` object which creates the internal buffer `P2` and the `eval`ed functions, and then call this workspace object with the desired function in a later stage:

```julia
P = tf(1 ∓ 0.1, [1, 1∓0.1]) # The P shown above
w = Workspace(P) # Creates work buffer `P2` and some getter/setter functions
f = x->c2d(x,0.1) # This is the computation I want to perform on P but which fails if P contains Particles
Pd = w(f) # This works

```

However, if created and called in the same function:

```julia
    tt = function (P)
        w = Workspace(P)
        f = x->c2d(x,0.1)
        @time Pd = w(f)
    end
    @test_throws MethodError tt(P) # This causes a world-age problem. If this tests suddenly break, it would be nice and we can get rid of the intermediate workspace object.

```

---

_[View the full topic](https://discourse.julialang.org/t/interpolate-expression-into-macro/24204)._
