Sebb

Sebb

I just tried to create a struct without fields (because: why not?).
It’s not possible with defstruct, which insists on an argument.

Best it can do is

defstruct _: nil # nice

btw, this is not OK:

defstruct [_]

isn’t that inconsistent?

So I tried to figure out what defstruct does. From the docs:

To define a struct, a developer must define both __struct__/0 and __struct__/1 functions. defstruct/1 is a convenience macro which defines such functions with some conveniences.

Where are __struct__/x documented?

Structs are usually defined with the Kernel.defstruct/1 macro

What if I want to be unusual? How can I define a struct by hand, maybe even without fields?

Showing Posts 1 to 7

dimitarvp

dimitarvp

…but what’s your goal?

Sebb

Sebb OP

to create a struct without fields :upside_down_face:
Actually I really think I have a use case, but the main point is: just being curious.

NobbZ

NobbZ

Using an empty list as argument to defstruct/1works for me:

iex(1)> defmodule S do
...(1)>   defstruct []
...(1)> end
iex(2)> %S{}
%S{}
sheharyarn

sheharyarn

Like @Nobbz said, you can just do this:

defmodule X, do: defstruct []

The reason this doesn’t work is that you cannot assign _. The first example works because :_ is not _, so you can do defstruct [:_] which is equivalent to your first example.


This is the macro that’s called underneath when defining a new struct. Going over the definition should help you better understand manually defining a struct in a module.

daskycodes

daskycodes

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

Sebb

Sebb OP

thanks for the great advice, can’t fully understand the defstruct-macro yet, but I’ll take a look at the book. (feeling a little too stupid for that right now, not having thought about defstruct []).

aiwaiwa

aiwaiwa

One legitimate reason would be to implement a protocol without data.

Use case: postgrex/lib/postgrex/parameters.ex at v0.16.5 · elixir-ecto/postgrex · GitHub

— All posts loaded —

Where Next? Top

Trending in Questions Top

katta
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
asweet-confluent
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
apz
I’m new to elixir and just tried to install the elixirLS extension for VScode(ium) and it is throwing some errors that I would like help ...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews