Meta-programming, structure constructor definition

Hello everyone,

I was playing around with Meta-programming and I was wondering if it is possible to facilitate writing long constructor call for a structure with many fields .

Suppose I have

struct s_example
     arg_1
     arg_2
      ...
     arg_N
end

With a constructor

function define_s(parameters)
     arg_1 = f(parameters)
      ...
     arg_N = g(parameters)
     object = s_example(arg_1,...,arg_N)
     return object
end

Is it possible to make the call to s_example easier with metaprogramming ?
I tried this

function define_s_easen(parameters)
    arg_1 = f(parameters)
     ...
    arg_N = g(parameters)
    object = eval(Expr(:call,s_example,fieldnames(s_example)...))
    return object
end

But since eval look for arg_i in the global scope, we get arg_1 not defined. During compilation, how can I write the function to be defined as the trivial one define_s ?

( Or maybe It is an equivalent problem, is there a way in Julia to return all the variable defined inside a function ? )

Thank you in advance,
GD

You need to construct the entire function define_s_easen as expression and eval that.

1 Like

I dont really see how to do that, I dont know how to broadcast the interpolation for symbols inside fieldnames.

Actually, you should do:

function define_s(parameters)
     args = (f(parameters), ..., g(parameters))
     object = s_example(args...)
     return object
end

I agree with this, but what about the first solution you proposed ?

Because we lose some readability for the proper definition of each arg_i, what we dont really care about is the call s_example(arg_1,arg_2, etc...)

( And actually we dont necessarily have functions f(parameters), it was just a way to simplify the example )

Something like

fld = fieldnames(s_example)
fns = [:f, :g]
calls = quote end
for (f,fn) in zip(fld,fns)
  push!(calls.args, :($f = $fn(parameters)))
end
eval(quote
function define_s_easen(parameters)
  $calls
  return s_example($(fld...))
end
end)

PS: you sound like you should look at Base.@kwdef or Parameters.jl

1 Like

Nice ! Thank you very much, I didn’t know about Base.@kwdef and Parameters.jl, I just checked it out and it is indeed exactly what I need !

1 Like