# How to make a macro for optional struct fields and function parameters?

**URL:** https://discourse.julialang.org/t/how-to-make-a-macro-for-optional-struct-fields-and-function-parameters/134935
**Category:** General Usage
**Created:** [January 7, 2026, 2:35pm UTC](https://discourse.julialang.org/t/how-to-make-a-macro-for-optional-struct-fields-and-function-parameters/134935 "2026-01-07T14:35:02Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![hadrien.theveneau](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hadrien.theveneau/32/218699_2.png) [@hadrien.theveneau](https://discourse.julialang.org/u/hadrien.theveneau)
#### Post date: [January 7, 2026, 2:35pm UTC](https://discourse.julialang.org/t/how-to-make-a-macro-for-optional-struct-fields-and-function-parameters/134935/1 "2026-01-07T14:35:02Z")

</div>

Dear all,

Would it be a simple way to code this:

```julia-auto
struct MyStruct
   a::Int
   IF OPTION THEN
       b::Int
   END IF
   new MyStruct(
       a_val::Int,
       IF OPTION THEN
           b::Int
       END IF
    )
end

```

I’m struggling with the syntax of macros, any hint ?

Thanks a lot,  
Regards,

---

<div class="post-metadata">

### Author: ![karei](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/karei/32/214809_2.png) [@karei](https://discourse.julialang.org/u/karei)
#### Post date: [January 7, 2026, 2:57pm UTC](https://discourse.julialang.org/t/how-to-make-a-macro-for-optional-struct-fields-and-function-parameters/134935/2 "2026-01-07T14:57:12Z")

</div>

You can’t do this in the sense of “one `struct` whose field list changes depending on a runtime `OPTION`.” In Julia, the set of fields is part of the type definition: a concrete type is _final_ (you can’t subtype it), and a concrete `DataType` has a fixed size, storage layout, and (optionally) field names. That’s exactly why the compiler can lay it out efficiently and why instances of the same concrete type can’t have different fields.

So if the `OPTION` is only known at runtime, a macro can’t magically make a single struct definition grow/shrink fields per instance.

Two practical alternatives:

### 1) Define two concrete structs + a common abstract supertype, then dispatch

```julia
abstract type AbstractCfg end

struct CfgWithB <: AbstractCfg
    a::Int
    b::Int
end

struct CfgNoB <: AbstractCfg
    a::Int
end

# Behavior via dispatch:
value(x::CfgWithB) = x.a + x.b
value(x::CfgNoB) = x.a

```

This keeps each concrete type’s layout fixed, but still lets you represent “with/without field” cleanly.

### 2) If you really want runtime-extensible fields, use a dict-like container

For “`OPTION`fields” that are truly dynamic at runtime, model them as key-value data. If you want dot-access ergonomics, take a look at PropertyDicts.jl, which wraps an `AbstractDict` and provides `getproperty`/`setproperty!` for `Symbol`/`String` keys.

---

<div class="post-metadata">

### Author: ![hadrien.theveneau](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hadrien.theveneau/32/218699_2.png) [@hadrien.theveneau](https://discourse.julialang.org/u/hadrien.theveneau)
#### Post date: [January 7, 2026, 3:06pm UTC](https://discourse.julialang.org/t/how-to-make-a-macro-for-optional-struct-fields-and-function-parameters/134935/3 "2026-01-07T15:06:46Z")

</div>

Thanks for your answer. I indeed want a compile-time option. Would you know how to make it ?

---

<div class="post-metadata">

### Author: ![karei](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/karei/32/214809_2.png) [@karei](https://discourse.julialang.org/u/karei)
#### Post date: [January 7, 2026, 3:17pm UTC](https://discourse.julialang.org/t/how-to-make-a-macro-for-optional-struct-fields-and-function-parameters/134935/4 "2026-01-07T15:17:51Z")

</div>

If `OPTION` is a constant (i.e., it will never change), then you can simply do something like

```julia
const OPTION = true # must be a constant (or at least a constant expression that `@static` can decide)

@static if OPTION
    struct MyStruct
        a::Int
        b::Int
    end
else
    struct MyStruct
        a::Int
    end
end

```

In this setup, the definition of `MyStruct` is fixed at compile time.

However, even if the value is “known at compile time” in some broader sense, if `OPTION` could be either `true` or `false` depending on the build/environment (i.e., you want to support both variants), then you still can’t have a _single_ concrete type whose field list changes dynamically. In that case, one practical approach is to keep the `b` field and make it optional by declaring its type as `Union{T,Nothing}`. You can store `nothing` to represent “b is absent.”

---

<div class="post-metadata">

### Author: ![hadrien.theveneau](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hadrien.theveneau/32/218699_2.png) [@hadrien.theveneau](https://discourse.julialang.org/u/hadrien.theveneau)
#### Post date: [January 8, 2026, 10:18am UTC](https://discourse.julialang.org/t/how-to-make-a-macro-for-optional-struct-fields-and-function-parameters/134935/5 "2026-01-08T10:18:17Z")

</div>

Many thanks for your help.  
Regarding the option macro, if there a way to avoid repeating the common parts ?

I know that this approach has its drawbacks, but to learn how this works I would need to be able to do what I wanted to do at the beginning, that is to be able to generate through a macro the code of the structure.

Many thanks,  
Have a nice day,

---

<div class="post-metadata">

### Author: ![karei](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/karei/32/214809_2.png) [@karei](https://discourse.julialang.org/u/karei)
#### Post date: [January 8, 2026, 11:35am UTC](https://discourse.julialang.org/t/how-to-make-a-macro-for-optional-struct-fields-and-function-parameters/134935/6 "2026-01-08T11:35:53Z")

</div>

Yes, you can fold the `@static if OPTION` branching into the macro. The macro can emit both struct definitions inside a `@static if ... else ... end`, and the compiler will keep only the selected branch at compile time. Here is an example:

```julia
macro def_optional_struct(name, option, common_block, opt_block)
    return esc(quote
        @static if $option
            struct $name
                $common_block
                $opt_block
            end
        else
            struct $name
                $common_block
            end
        end
    end)
end

# usage
const OPTION = true

@def_optional_struct 🍕 OPTION begin
    🧀::Int
    🥓::Float64
end begin
    🍤::String
end

```

```julia
julia> dump(🍕)
struct 🍕 <: Any
  🧀::Int64
  🥓::Float64
  🍤::String

```

---

<div class="post-metadata">

### Author: ![hadrien.theveneau](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hadrien.theveneau/32/218699_2.png) [@hadrien.theveneau](https://discourse.julialang.org/u/hadrien.theveneau)
#### Post date: [January 8, 2026, 11:59am UTC](https://discourse.julialang.org/t/how-to-make-a-macro-for-optional-struct-fields-and-function-parameters/134935/7 "2026-01-08T11:59:04Z")

</div>

Thanks a lot. Nice example to help me with macros.
