One way to define a struct is to use a simple map with the __struct__ key
Let’s say we have a module StructWithoutFields
we could call
iex> %{__struct__: StructWithoutFields} |> is_struct()
true
This will be a struct but we won’t be able to call %StructWithoutFields{}
The next step I’d suggest is looking into the macro implementation like @sheharyarn suggested.
I left a lot of parts out in the following example but this might give you an idea
defmodule StructWithoutFields do
@struct %{__struct__: __MODULE__}
def __struct__(kv) do
Enum.reduce(kv, @struct, fn {key, val}, map ->
Map.replace!(map, key, val)
end)
end
def __struct__() do
@struct
end
end
With that module you will already be able to call
iex> %StructWithoutFields{} |> is_struct()
true
If you haven’t read it yet I can really recommend reading Metaprogramming Elixir: Write Less Code, Get More Done (and Have Fun!) by Chris McCord
It goes into a lot of detail on how macros work and how basically a lot of elixir is build upon macros


















