# Function inside Macro

**URL:** <https://discourse.julialang.org/t/function-inside-macro/66476>\
**Category:** General Usage\
**Tags:** macros, struct\
**Created:** [August 16, 2021, 10:49am UTC](https://discourse.julialang.org/t/function-inside-macro/66476 "2021-08-16T10:49:35Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![mrVeng](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mrveng/32/8836_2.png) [@mrVeng](https://discourse.julialang.org/u/mrVeng)\
**Post date:** [August 16, 2021, 10:49am UTC](https://discourse.julialang.org/t/function-inside-macro/66476/1 "2021-08-16T10:49:36Z")

</div>

Hi there,

I am struggling to find a way to combine a macro und a function. Lets start with an MWE of what I want to do:

```julia
using QuickTypes
abstract type AbstractModel end
param = (a = 1., b = 2.)

# Create a new Parametric struct that is a subtype of some AbstractModel
macro build(modelname, parameter)
    esc(:( @qmutable_fp $modelname( $parameter::NamedTuple ) <: AbstractModel ) )
end
#Working fine
@build(MyModel, param)
MyModel(param)

```

#1 Now, is there a way to combine @build(MyModel, param) and MyModel(param) such that @build outputs the the actual struct and I don’t need to use both function separately? As soon as I define a new MyModel that is not yet in scope, my solution will not work anymore:

```julia
macro build2(modelname, parameter)
    esc( :( @qmutable_fp $modelname( $parameter::NamedTuple) ) )
    #return esc( :( $modelname($param) ) )
    return :( $modelname($param) )
end
@build2(MyModel, param) #works because already assigned before
@build2(MyModel2, param) #UndefVarError: MyModel2 not defined

@macroexpand( @build2(MyModel2, param) ) # Seems to return exactly what I want, which is a bit puzzling to me

```

#2 Similarly, lets assume I want to have a specific constructor for modelname(parameter). Unfortunately, I cannot just create a (modelname::AbstractModel)(parameter\<:NamedTuple), because the more narrow choice (model::MyModel)(param::NamedTuple) will be chosen and (model::M)(param::NamedTuple) where {M\<:AbstractModel} does not seem to work. So I thought I just make a wrapper function:

```julia
function init(modelname, parameter)
    #do some stuff
    return modelname(parameter)
end
init(MyModel, param)

```

However, just like @build2, the function within the macro does not seem to work here:

```julia
macro build3(modelname, parameter)
    esc( :( @qmutable_fp $modelname( $parameter::NamedTuple) ) )
    return :( init($modelname, $param) )
end
@build3(MyModel3, param) #UndefVarError: MyModel3 not defined

```

There are quite a few similar questions on discourse, but I did not manage to make my examples work even with the guidance from there unfortunately.
