# How to construct a type using Meta programming?

**URL:** https://discourse.julialang.org/t/how-to-construct-a-type-using-meta-programming/136644
**Category:** General Usage
**Created:** [April 9, 2026, 2:05pm UTC](https://discourse.julialang.org/t/how-to-construct-a-type-using-meta-programming/136644 "2026-04-09T14:05:43Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![Thomas008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thomas008/32/204169_2.png) [@Thomas008](https://discourse.julialang.org/u/Thomas008)
#### Post date: [April 9, 2026, 2:05pm UTC](https://discourse.julialang.org/t/how-to-construct-a-type-using-meta-programming/136644/1 "2026-04-09T14:05:44Z")

</div>

I would like to contruct a type using meta programming. More specific,I need a tuple type like

```julia-auto
Tuple{Vector{String}, Vector{String}}

```

.  
Constructing a _value_ is quite easily possible,  
e.g.

```julia-auto
ex = Expr(:tuple)
push!(ex.args, 1)
push!(ex.args, 2)

```

with

```julia-auto
eval(ex)

```

resulting in the tuple value

```julia-auto
(1,2)

```

But how to construct a tuple _type_?  
I used dump to get a syntax tree of the tuple type mentioned above.

```julia-auto
dump(:(Tuple{Vector{String}, Vector{String}}))

```

It results in the following syntax tree:

```julia-auto
Expr
  head: Symbol curly
  args: Array{Any}((4,))
    1: Symbol Tuple
    2: Expr
      head: Symbol curly
      args: Array{Any}((2,))
        1: Symbol Vector
        2: Symbol String
    3: Expr
      head: Symbol curly
      args: Array{Any}((2,))
        1: Symbol Vector
        2: Symbol String
    4: Expr
      head: Symbol curly
      args: Array{Any}((2,))
        1: Symbol Vector
        2: Symbol String

```

However, using the symbol curly, using

```julia-auto
ex = Expr(:curly)

```

did not work to get a well-formed expression so far.  
I would be very happy if you had a suggesion.

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [April 9, 2026, 2:15pm UTC](https://discourse.julialang.org/t/how-to-construct-a-type-using-meta-programming/136644/2 "2026-04-09T14:15:43Z")

</div>

> [@Thomas008](#):
>
> However, using the symbol curly, using
> 
> ```julia-auto
> ex = Expr(:curly)
> 
> ```
> 
> did not work to get a well-formed expression so far.  
> I would be very happy if you had a suggesion.

`Expr(:curly, :Tuple, :Int, :Char)` works just fine to construct `:(Tuple{Int, Char})`, for example.

PS. Obligatory warning that [metaprogramming is the wrong tool 99% of the time](https://discourse.julialang.org/t/how-to-warn-new-users-away-from-metaprogramming/35022) … but is very useful in remaining 1%.

---

<div class="post-metadata">

### Author: ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)
#### Post date: [April 9, 2026, 2:42pm UTC](https://discourse.julialang.org/t/how-to-construct-a-type-using-meta-programming/136644/3 "2026-04-09T14:42:02Z")

</div>

First, I’ll echo the above that there might be a better way to do this without metaprogramming. Metaprogramming is difficult to write and read and it can be brittle.

To answer your specific query based on the `dump` you gave (less `args[4]`, which should not actually be present):

```julia-repl
julia> Expr(:curly, :Tuple, Expr(:curly, :Vector, :String), Expr(:curly, :Vector, :String))
:(Tuple{Vector{String}, Vector{String}})

```

or, for an incremental build:

```julia-repl
julia> ex = Expr(:curly, :Tuple); for _ in 1:2; push!(ex.args, Expr(:curly, :Vector, :String)); end; ex
:(Tuple{Vector{String}, Vector{String}})

julia> ex = :(Tuple{}); for _ in 1:2; push!(ex.args, :(Vector{String})); end; ex # quotes are usually nicer
:(Tuple{Vector{String}, Vector{String}})

```

Deconstructing the above a bit, notice that `:curly` needs an `args[1]` to tell it _what_ is curly to make a “well-formed expression”:

```julia-repl
julia> ex = Expr(:curly); push!(ex.args, :Tuple); ex
:(Tuple{})

```

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [April 10, 2026, 5:53am UTC](https://discourse.julialang.org/t/how-to-construct-a-type-using-meta-programming/136644/4 "2026-04-10T05:53:22Z")

</div>

In earlier steps, typing source code into quoted expressions and interpolation could be easier than constructing and mutating `Expr` directly:

```julia-auto
julia> x = :(Vector{String})
:(Vector{String})

julia> :(Tuple{$x, $x})
:(Tuple{Vector{String}, Vector{String}})

julia> :(Tuple{$( (x, x)... )})
:(Tuple{Vector{String}, Vector{String}})

```

It’s good to know the `Expr` structure and how to mutate it regardless; beyond a point, it gets simpler and more efficient than only writing quoted expressions.

> [@stevengj](#):
>
> Obligatory warning that [metaprogramming is the wrong tool 99% of the time](https://discourse.julialang.org/t/how-to-warn-new-users-away-from-metaprogramming/35022)

I never liked how this is worded. IIRC the basis is that macros and generated functions made up \<1% of method definitions in base Julia at some point, but that has some caveats:

- `eval` loops are also metaprogramming.
- A lot of `Expr` and raw string processing is done in plain functions called by macros.
- Macro or generated function _calls_ do transform or generate code, so it’s comes across as a bit strange to say metaprogramming is a rare tool then suggest macro calls for routine timing and reflection. Maybe “implementing metaprogramming” would be closer, but that still sounds odd to me.
- Some languages don’t specify expression objects like Julia does (though they may expose internals in implementation-specific libraries), changing the concept of metaprogramming. This advice for beginners may backfire, say make a Python user avoid higher-order functions because that’s what most decorators do. I think most people would study enough to avoid that pitfall, but some won’t, might even throw off an AI prompt.

---

<div class="post-metadata">

### Author: ![Thomas008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thomas008/32/204169_2.png) [@Thomas008](https://discourse.julialang.org/u/Thomas008)
#### Post date: [April 10, 2026, 1:47pm UTC](https://discourse.julialang.org/t/how-to-construct-a-type-using-meta-programming/136644/5 "2026-04-10T13:47:36Z")

</div>

Thank you! That helps a lot.
