Macro to create structs with custom fields and parametric types

Hi there,

I am starting to learn about Macros in Julia and have a few difficulties with it. My goal is to create a new struct with some custom fields. After searching and reading here on discourse, I
found this useful post: Macro to create a struct with variable number of fields?.
A MWE for my goal is here:

macro make_model(modelname, fields_tuple)
    fields = fields_tuple.args
    quote
        mutable struct $modelname
            $(fields...)
            function $modelname($(fields...))
                new($(fields...))
            end
        end
    end
end

@make_model(mod1, (μ, σ, p) )
mod1(1., [2., 3.], [ 4. 5 ; 6 7])

(1) So far so good. A problem here is that this is not typed at all, so I was wondering if we can use the macro to assign a fully typed strcut? I am not sure if this is even possible given one does not use Macros with values, but I was wondering if someone could help me here because the structs created above are probably not very performant. My (failed) attempt, is here:

macro make_model2(modelname, fields_tuple, value_tuple)
    fields = fields_tuple.args
    values = value_tuple.args
    quote
        mutable struct $modelname ### (i) here should be the parametric type like $modelname{...}
            $(fields...) :: typeof( $(values...) ) ### (ii) Mistake is here
            function $modelname($(fields...))
                new($(fields...))
            end
        end
    end
end

@make_model2(mod21, (μ, σ, p), (1., [2., 3.], [ 4. 5 ; 6 7]) )
mod2(1., [2., 3.], [ 4. 5 ; 6 7]) #ArgumentError: typeof: too many arguments (expected 1)
@macroexpand @make_model2 mod2 (μ, σ, p) (1., [2., 3.], [ 4. 5 ; 6 7])

(2) My second question is: if I can already assign parametric types to the struct, can I make the macro such that it outputs the struct with the values that I used to assign the types?
A (non working) MWE is here:

macro make_model3(modelname, fields_tuple, value_tuple)
    fields = fields_tuple.args
    quote
        mutable struct $modelname
            $(fields...)
            function $modelname($(fields...))
                new($(fields...))
            end
        end
    end
    @eval $modelname($(value_tuple...))
end
val = ( 1., [2., 3.], [ 4. 5 ; 6 7] )
mod3 = @make_model3(mod3, (μ, σ, p), val) #LoadError: MethodError: no method matching iterate(::Symbol)

I did read the manual on Macros, but I struggle quite a bit to get used to this. I would be grateful if someone has advice on my questions!

Best regards,

1 Like