# Custom keyword arguments with metaprogramming

**URL:** <https://discourse.julialang.org/t/custom-keyword-arguments-with-metaprogramming/74009>\
**Category:** General Usage\
**Tags:** metaprogramming\
**Created:** [January 3, 2022, 11:09pm UTC](https://discourse.julialang.org/t/custom-keyword-arguments-with-metaprogramming/74009 "2022-01-03T23:09:48Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![MarcBerliner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marcberliner/32/14883_2.png) [@MarcBerliner](https://discourse.julialang.org/u/MarcBerliner)\
**Post date:** [January 3, 2022, 11:09pm UTC](https://discourse.julialang.org/t/custom-keyword-arguments-with-metaprogramming/74009/1 "2022-01-03T23:09:49Z")

</div>

I am trying to recreate the function `fun1` using metaprogramming, and `fun2` is my attempt but I’m running into errors. How can I do this (or is there a better way to get this done)?

```julia
# Arbitrary struct
struct ABC
    A
    B
    C
end

# The function I'm trying to create with meta programming
function fun1(ABC;
    A = ABC.A,
    B = ABC.B,
    C = ABC.C,
)
    return A + B + C
end

# The non-working version
keywords = join(["$field = ABC.$field" for field in fieldnames(ABC)], ",\n")

eval(quote
function fun2(ABC;
    $(keywords),
)
    return A + B + C
end
end)

```

The errors are

```julia
ERROR: syntax: invalid keyword argument syntax ""A = ABC.A,
B = ABC.B,
C = ABC.C"" around REPL[83]:2
Stacktrace:
 [1] top-level scope
   @ none:1
 [2] eval
   @ ./boot.jl:373 [inlined]
 [3] eval(x::Expr)
   @ Base.MainInclude ./client.jl:453
 [4] top-level scope
   @ REPL[83]:1

```

---

<div class="post-metadata">

**Author:** ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)\
**Post date:** [January 4, 2022, 4:29am UTC](https://discourse.julialang.org/t/custom-keyword-arguments-with-metaprogramming/74009/2 "2022-01-04T04:29:37Z")

</div>

You don’t want to use strings for this. `dump` is your friend for figuring out what to build; I’m not sure if there is a more tidy way to build this one, but explicitly calling `Expr` should let you build anything:

```julia
julia> :(f(x; y=1, z=2)) |> dump
Expr
  head: Symbol call
  args: Array{Any}((3,))
    1: Symbol f
    2: Expr
      head: Symbol parameters
      args: Array{Any}((2,))
        1: Expr
          head: Symbol kw
          args: Array{Any}((2,))
            1: Symbol y
            2: Int64 1
        2: Expr
          head: Symbol kw
          args: Array{Any}((2,))
            1: Symbol z
            2: Int64 2
    3: Symbol x

julia> nt = (y=1, z=2);

julia> :(f(x; $(nt...))) # doesn't work
:(f(x; 1, 2))

julia> :(f(x, $(; nt...)))
:(f(x, (y = 1, z = 2)))

julia> :(f(x; $nt...))
:(f(x; (y = 1, z = 2)...))

julia> kw = Expr(:parameters, Expr(:kw, :y, 1), Expr(:kw, :z, 2));

julia> :(f($kw, x))
:(f(x; y = 1, z = 2))

julia> dump(ans)

```
